KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hero > client > grapheditor > GPGraphTools


1 /*
2  * @(#)GPGraphTools.java 1.0 1/1/02
3  *
4  * Copyright (C) 2001 Gaudenz Alder
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */

21
22 package hero.client.grapheditor;
23
24 import java.awt.Point JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Comparator JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Hashtable JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.SortedSet JavaDoc;
31 import java.util.TreeSet JavaDoc;
32
33 import com.jgraph.JGraph;
34 import com.jgraph.graph.CellView;
35 import com.jgraph.graph.DefaultGraphModel;
36 import com.jgraph.graph.EdgeView;
37 import com.jgraph.graph.GraphModel;
38
39 public class GPGraphTools {
40
41     public CostFunction createDefaultCostFunction() {
42       return new DefaultCostFunction();
43     }
44
45     //
46
// Component Counting
47
//
48

49     public int getComponentCount(WFGraph graph) {
50       GraphModel m = graph.getModel();
51       UnionFind uf = new UnionFind();
52       Object JavaDoc[] all = graph.getAll();
53       // Vertices
54
Object JavaDoc[] v = graph.getVertices(all);
55       for (int i = 0; i < v.length; i++)
56     uf.find(v[i]);
57       // Edges
58
Object JavaDoc[] e = graph.getEdges(all);
59       for (int i = 0; i < e.length; i++) {
60         Object JavaDoc source = graph.getSourceVertex(e[i]);
61     Object JavaDoc target = graph.getTargetVertex(e[i]);
62     uf.union(uf.find(source), uf.find(target));
63       }
64       return uf.getSetCount();
65     }
66
67     //
68
// Dijkstra Algorithm
69
//
70

71     public Object JavaDoc[] getShortestPath(WFGraph graph, Object JavaDoc from,
72                       Object JavaDoc to, CostFunction cf)
73     {
74       if (cf == null)
75                 cf = createDefaultCostFunction();
76       GraphModel model = graph.getModel();
77       PriorityQueue q = new PriorityQueue();
78       Hashtable JavaDoc pred = new Hashtable JavaDoc();
79       q.setPrio(from, 0);
80       // Main Loop
81
Object JavaDoc[] all = graph.getAll();
82       int jmax = graph.getVertices(all).length;
83       for (int j = 0; j < jmax; j++) {
84                 double prio = q.getPrio();
85                 Object JavaDoc obj = q.pop();
86                 if (obj == to)
87                     break;
88                 Object JavaDoc[] tmp = new Object JavaDoc[]{obj};
89                 Object JavaDoc[] e = DefaultGraphModel.getEdges(model, tmp).toArray();
90                 if (e != null) {
91                   for (int i = 0; i < e.length; i++) {
92                     Object JavaDoc neighbour = graph.getNeighbour(e[i], obj);
93                     double newPrio = prio + cf.getCost(graph, e[i]);
94                     if (neighbour != null && neighbour != obj &&
95                         newPrio < q.getPrio(neighbour))
96                     {
97                       pred.put(neighbour, e[i]);
98                       q.setPrio(neighbour, newPrio);
99                     }
100                   }
101                 }
102                 if (q.isEmpty())
103                     break;
104       }
105       // Return Path-Array
106
ArrayList JavaDoc list = new ArrayList JavaDoc();
107       Object JavaDoc obj = to;
108       while (obj != null) {
109                 list.add(obj);
110                 Object JavaDoc edge = pred.get(obj);
111                 if (edge != null) {
112                   list.add(edge);
113                   obj = graph.getNeighbour(edge, obj);
114                 } else
115                   obj = null;
116       }
117       return list.toArray();
118     }
119
120     //
121
// Kruskal Algorithm
122
//
123

124     public Object JavaDoc[] getSpanningTree(WFGraph graph, CostFunction cf) {
125       if (cf == null)
126                 cf = createDefaultCostFunction();
127       Object JavaDoc[] all = graph.getAll();
128       SortedSet JavaDoc edges = sort(graph, graph.getEdges(all), cf);
129       UnionFind uf = new UnionFind();
130       HashSet JavaDoc result = new HashSet JavaDoc();
131       while (!edges.isEmpty()) {
132                 Object JavaDoc edge = edges.first();
133                 edges.remove(edge);
134                 Object JavaDoc setA, setB;
135                 setA = uf.find(graph.getSourceVertex(edge));
136                 setB = uf.find(graph.getTargetVertex(edge));
137                 if (setA == null || setB == null || setA != setB) {
138                   uf.union(setA, setB);
139                   result.add(edge);
140                 }
141       }
142       // Create set of vertices
143
HashSet JavaDoc v = new HashSet JavaDoc();
144       Iterator JavaDoc it = result.iterator();
145       while (it.hasNext()) {
146                 Object JavaDoc edge = it.next();
147                 Object JavaDoc source = graph.getSourceVertex(edge);
148                 Object JavaDoc target = graph.getTargetVertex(edge);
149                 if (source != null)
150                   v.add(source);
151                 if (target != null)
152                   v.add(target);
153       }
154       Object JavaDoc[] cells = new Object JavaDoc[result.size()+v.size()];
155       System.arraycopy(result.toArray(), 0, cells, 0, result.size());
156       System.arraycopy(v.toArray(), 0, cells, result.size(), v.size());
157       return cells;
158     }
159
160     //
161
// Sorting With CostFunction
162
//
163

164     public SortedSet JavaDoc sort(final JGraph graph, Object JavaDoc[] cells, final CostFunction cf) {
165       TreeSet JavaDoc set = new TreeSet JavaDoc(new Comparator JavaDoc() {
166                  public int compare(Object JavaDoc o1, Object JavaDoc o2) {
167                   Double JavaDoc d1 = new Double JavaDoc(cf.getCost(graph, o1));
168                   Double JavaDoc d2 = new Double JavaDoc(cf.getCost(graph, o2));
169                   return d1.compareTo(d2);
170                 }
171       });
172       for (int i = 0; i < cells.length; i++)
173                 set.add(cells[i]);
174       return set;
175     }
176
177     //
178
// Cost Function
179
//
180

181     public interface CostFunction {
182
183       public double getCost(JGraph graph, Object JavaDoc cell);
184
185     }
186
187     public class DefaultCostFunction implements CostFunction {
188
189       public double getCost(JGraph graph, Object JavaDoc cell) {
190                 CellView view = graph.getView().getMapping(cell, false);
191                 return getLength(view);
192       }
193     }
194
195     public static double getLength(CellView view) {
196       double cost = 1;
197       if (view instanceof EdgeView) {
198                 EdgeView edge = (EdgeView) view;
199                 Point JavaDoc last = null, current = null;
200                 for (int i = 0; i < edge.getPointCount(); i++) {
201                   current = edge.getPoint(i);
202                   if (last != null)
203                     cost += last.distance(current);
204                   last = current;
205                 }
206       }
207       return cost;
208     }
209
210     //
211
// Union-Find
212
//
213

214     public class UnionFind {
215
216       protected Hashtable JavaDoc sets = new Hashtable JavaDoc(),
217               cells = new Hashtable JavaDoc();
218
219       /* Return the number of distinct sets. */
220       public int getSetCount() {
221     return sets.size();
222       }
223
224       /* Return an object identifying the set that contains the given cell. */
225       public Object JavaDoc find(Object JavaDoc cell) {
226     Object JavaDoc set = null;
227     if (cell != null) {
228       set = cells.get(cell);
229       if (set == null) {
230         set = cell;
231         cells.put(cell, set);
232         HashSet JavaDoc contents = new HashSet JavaDoc();
233         contents.add(cell);
234         sets.put(set, contents);
235       }
236     }
237     return set;
238       }
239
240       /* Union the given sets such that all elements belong to the same set. */
241       public Object JavaDoc union(Object JavaDoc set1, Object JavaDoc set2) {
242                 if (set1 != null && set2 != null && set1 != set2) {
243                   HashSet JavaDoc tmp1 = (HashSet JavaDoc) sets.get(set1);
244                   HashSet JavaDoc tmp2 = (HashSet JavaDoc) sets.get(set2);
245                   if (tmp1 != null && tmp2 != null) {
246                     if (tmp1.size() < tmp2.size()) {
247                       Object JavaDoc tmp = tmp1; tmp1 = tmp2; tmp2 = (HashSet JavaDoc) tmp;
248                       tmp = set1; set1 = set2; set2 = tmp;
249                     }
250                     tmp1.addAll(tmp2);
251                     sets.remove(set2);
252                     Iterator JavaDoc it = tmp2.iterator();
253                     while (it.hasNext())
254                       cells.put(it.next(), set1);
255                   }
256                 }
257                 return set1;
258       }
259
260     }
261
262     //
263
// Priority Queue
264
//
265

266     public class PriorityQueue {
267
268       protected Hashtable JavaDoc prio = new Hashtable JavaDoc();
269
270       protected HashSet JavaDoc data = new HashSet JavaDoc();
271       
272       protected double minPrio = Double.MAX_VALUE;
273       
274       protected Object JavaDoc minElt = null;
275
276             public boolean isEmpty() {
277                 return data.isEmpty();
278             }
279
280       // Removes element but holds prio
281
public Object JavaDoc pop() {
282         Object JavaDoc tmp = minElt;
283         data.remove(tmp);
284         update();
285         return tmp;
286       }
287
288       /* Return the priority of the top element. */
289       public double getPrio() {
290         return minPrio;
291       }
292
293       /* Return the priority of the given element. */
294       public double getPrio(Object JavaDoc obj) {
295                 if (obj != null) {
296                   Double JavaDoc d = (Double JavaDoc) prio.get(obj);
297                   if (d != null)
298                     return d.doubleValue();
299                 }
300                 return Double.MAX_VALUE;
301       }
302       
303       protected void update() {
304         Iterator JavaDoc it = data.iterator();
305         minElt = null;
306         minPrio = Double.MAX_VALUE;
307         while (it.hasNext()) {
308             Object JavaDoc tmp = it.next();
309             double prio = getPrio(tmp);
310             if (prio < minPrio) {
311                 minPrio = prio;
312                 minElt = tmp;
313             }
314                 }
315       }
316
317       /* Set the priority of the given element and add to queue if necessary. */
318       public void setPrio(Object JavaDoc obj, double prio) {
319                 Double JavaDoc d = new Double JavaDoc(prio);
320                 this.prio.put(obj, d);
321                 data.add(obj);
322                 if (prio < minPrio) {
323                     minPrio = prio;
324                     minElt = obj;
325                 }
326       }
327     
328     }
329
330 }
331
Popular Tags