Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

UnionFindSet.java

00001 package edu.ksu.cis.bandera.abstraction.util;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 2000   Robby (robby@cis.ksu.edu)                    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import java.util.*;
00036 
00037 public class UnionFindSet implements Set {
00038     private Hashtable elements = new Hashtable();
00039     private Hashtable partAttrTable = new Hashtable();
00040     private class Element {
00041         int rank;
00042         Element parent;
00043         Object object;
00044         Element(int rank, Object object) {
00045             this.rank = rank;
00046             this.parent = this;
00047             this.object = object;
00048         }
00049     }
00050 /**
00051  * 
00052  */
00053 public UnionFindSet() {}
00054 /**
00055  * 
00056  */
00057 public UnionFindSet(Collection c) {
00058     for (Iterator i = new HashSet(c).iterator(); i.hasNext();) {
00059         Object o = i.next();
00060         elements.put(o, new Element(0, o));
00061     }
00062 }
00063 /**
00064  * 
00065  * @return boolean
00066  * @param o java.lang.Object
00067  */
00068 public boolean add(Object o) {
00069     if (find(o) == null) {
00070         elements.put(o, new Element(0, o));
00071         return true;
00072     } else {
00073         return false;
00074     }
00075 }
00076 /**
00077  * 
00078  * @return boolean
00079  * @param c java.util.Collection
00080  */
00081 public boolean addAll(Collection c) {
00082     boolean result = false;
00083     for (Iterator i = c.iterator(); i.hasNext();) {
00084         result = result || add(i.next());
00085     }
00086     return result;
00087 }
00088 /**
00089  * 
00090  * @return boolean
00091  * @param c java.util.Collection
00092  * @param o java.lang.Object
00093  */
00094 public boolean addAllTo(Collection c, Object orep) {
00095     boolean result = false;
00096     for (Iterator i = c.iterator(); i.hasNext();) {
00097         result = result || addTo(i.next(), orep);
00098     }
00099     return result;
00100 }
00101 /**
00102  * 
00103  * @return boolean
00104  * @param o java.lang.Object
00105  * @param orep java.lang.Object
00106  */
00107 public boolean addTo(Object o, Object orep) {
00108     if (add(o)) {
00109         union(o, orep);
00110     }
00111     return false;
00112 }
00113 /**
00114  * 
00115  */
00116 public void clear() {
00117     elements = new Hashtable();
00118     partAttrTable = new Hashtable();
00119 }
00120 /**
00121  * 
00122  * @return boolean
00123  * @param o java.lang.Object
00124  */
00125 public boolean contains(Object o) {
00126     return toSet().contains(o);
00127 }
00128 /**
00129  * 
00130  * @return boolean
00131  * @param c java.util.Collection
00132  */
00133 public boolean containsAll(Collection c) {
00134     return toSet().containsAll(c);
00135 }
00136 /**
00137  * 
00138  * @return java.lang.Object
00139  * @param o java.lang.Object
00140  */
00141 public Object find(Object o) {
00142     try {
00143         Element e = (Element) elements.get(o);
00144         if (e == null) return null;
00145         Element above = e.parent;
00146         while (above != above.parent) {
00147             e.parent = above.parent;
00148             above = above.parent.parent;
00149         }
00150         return above.object;
00151     } catch (Exception e) {
00152         return null;
00153     }
00154 }
00155 /**
00156  * 
00157  * @return java.lang.Object
00158  * @param o java.lang.Object
00159  */
00160 public Object getAttribute(Object o) {
00161     o = find(o);
00162     if (o == null) return null;
00163     else return partAttrTable.get(o);
00164 }
00165 /**
00166  * 
00167  * @return boolean
00168  */
00169 public boolean isEmpty() {
00170     return elements.size() == 0;
00171 }
00172 /**
00173  * 
00174  * @return java.util.Iterator
00175  */
00176 public Iterator iterator() {
00177     return toSet().iterator();
00178 }
00179 /**
00180  * 
00181  * @param args java.lang.String[]
00182  */
00183 public static void main(String[] args) {
00184     if (args.length != 2) {
00185         System.out.println("needs two positive-integer arguments");
00186         return;
00187     }
00188     
00189     UnionFindSet ufs = new UnionFindSet();
00190 
00191     int size = Integer.parseInt(args[0]);
00192     int cmod = Integer.parseInt(args[1]);
00193 
00194     Integer[] ints = new Integer[size];
00195 
00196     for (int i = 0; i < size; i++) {
00197         ufs.add(ints[i] = new Integer(i));
00198     }
00199 
00200     System.out.println(ufs.toString());
00201 
00202     for (int i = 0; i < size; i++) {
00203         for (int j = 0; j < cmod; j++) {
00204             if (i % cmod == j) {
00205                 ufs.union(ints[j], ints[i]);
00206             }
00207         }
00208     }
00209 
00210     System.out.println(ufs);
00211 
00212     for (int i = 0; i < size; i++) {
00213         System.out.println(ints[i] + " is represented as " + ufs.find(ints[i]));
00214     }
00215 }
00216 /**
00217  * 
00218  * @return boolean
00219  * @param object java.lang.Object
00220  */
00221 public boolean remove(Object object) {
00222     try {
00223         Element e = (Element) elements.get(object);
00224         if (e.parent == e) {
00225             Element top = null;
00226             for (Enumeration enum = elements.elements(); enum.hasMoreElements();) {
00227                 Element e2 = (Element) enum.nextElement();
00228                 if (e2.parent == e) {
00229                     if (top == null) {
00230                         top = e2;
00231                         top.rank = e.rank;
00232                     }
00233                     e2.parent = top;
00234                 }
00235             }
00236             partAttrTable.put(top.object, partAttrTable.get(e.object));
00237         } else {
00238             for (Enumeration enum = elements.elements(); enum.hasMoreElements();) {
00239                 Element e2 = (Element) enum.nextElement();
00240                 if (e2.parent == e) {
00241                     e2.parent = e.parent;
00242                 }
00243             }
00244         }
00245         elements.remove(object);
00246         return true;
00247     } catch (Exception e) {
00248         return false;
00249     }
00250 }
00251 /**
00252  * 
00253  * @return boolean
00254  * @param c java.util.Collection
00255  */
00256 public boolean removeAll(Collection c) {
00257     boolean result = false;
00258     for (Iterator i = c.iterator(); i.hasNext();) {
00259         result = result || remove(i.next());
00260     }
00261     return result;
00262 }
00263 /**
00264  * 
00265  * @return boolean
00266  * @param c java.util.Collection
00267  */
00268 public boolean retainAll(Collection c) {
00269     boolean result = false;
00270     for (Enumeration e = elements.elements(); e.hasMoreElements();) {
00271         Object o = e.nextElement();
00272         if (!c.contains(o)) {
00273             remove(o);
00274         }
00275     }
00276     return result;
00277 }
00278 /**
00279  * 
00280  * @return boolean
00281  * @param o java.lang.Object
00282  * @param attr java.lang.Object
00283  */
00284 public boolean setAttribute(Object o, Object attr) {
00285     o = find(o);
00286     if (o == null) return false;
00287     partAttrTable.put(o, attr);
00288     return true;
00289 }
00290 /**
00291  * 
00292  * @return int
00293  */
00294 public int size() {
00295     return toSet().size();
00296 }
00297 /**
00298  * 
00299  * @return java.lang.Object[]
00300  */
00301 public Object[] toArray() {
00302     return toSet().toArray();
00303 }
00304 /**
00305  * 
00306  * @return java.lang.Object[]
00307  * @param objects java.lang.Object[]
00308  */
00309 public Object[] toArray(Object[] objects) {
00310     return null;
00311 }
00312 /**
00313  * 
00314  * @return java.util.Set
00315  */
00316 private Set toSet() {
00317     Hashtable table = new Hashtable();
00318     for (Enumeration e = elements.elements(); e.hasMoreElements();) {
00319         Element el = (Element) e.nextElement();
00320         Element rel = (Element) elements.get(find(el.object));
00321         if (table.get(rel) == null) {
00322             table.put(rel, new HashSet());
00323         }
00324         ((HashSet) table.get(rel)).add(el.object);
00325     }
00326     HashSet set = new HashSet();
00327     for (Enumeration e = table.elements(); e.hasMoreElements();) {
00328         set.add(e.nextElement());
00329     }
00330     return set;
00331 }
00332 /**
00333  * 
00334  * @return java.lang.String
00335  */
00336 public String toString() {
00337     Set set = toSet();
00338     StringBuffer temp = new StringBuffer(set.size() + "= {\n");
00339     for (Iterator i = set.iterator(); i.hasNext();) {
00340         Set s = (Set) i.next();
00341         
00342         temp.append("(" + getAttribute(s.iterator().next()) + ", " + s + "),\n");
00343     }
00344     temp.append("}\n");
00345     return temp.toString();
00346 }
00347 /**
00348  *
00349  * @return boolean
00350  * @param o1 java.lang.Object
00351  * @param o2 java.lang.Object
00352  */
00353 public boolean union(Object o1, Object o2) {
00354     o1 = find(o1);
00355     o2 = find(o2);
00356     if ((o1 == null) || (o2 == null))
00357         return false;
00358     if (getAttribute(o1) != null && getAttribute(o2) != null)
00359         if (getAttribute(o1) != getAttribute(o2))
00360             System.out.println("Warning: trying to merge two partitions that have different attributes");
00361     Object attr = getAttribute(o1);
00362     if (attr == null)
00363         attr = getAttribute(o2);
00364     partAttrTable.remove(o1);
00365     partAttrTable.remove(o2);
00366     try {
00367         Element e1 = (Element) elements.get(o1);
00368         Element e2 = (Element) elements.get(o2);
00369         if (e1.rank >= e2.rank) {
00370             e2.parent = e1;
00371             if (e1.rank == e2.rank) {
00372                 e1.rank++;
00373             }
00374         } else {
00375             e1.parent = e2;
00376         }
00377     } catch (Exception e) {
00378         return false;
00379     }
00380     o1 = find(o1);
00381     if (attr != null)
00382         partAttrTable.put(o1, attr);
00383     return true;
00384 }
00385 }

Generated at Thu Feb 7 06:58:56 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001