KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > util > collections > DiGraph


1 package com.quadcap.util.collections;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 //-//#ifdef JDK11
42
//-import com.sun.java.util.collections.ArrayList;
43
//-import com.sun.java.util.collections.Comparable;
44
//-import com.sun.java.util.collections.HashMap;
45
//-import com.sun.java.util.collections.HashSet;
46
//-import com.sun.java.util.collections.Iterator;
47
//-import com.sun.java.util.collections.Map;
48
//-import com.sun.java.util.collections.Set;
49
//#else
50
import java.util.ArrayList JavaDoc;
51 import java.util.HashMap JavaDoc;
52 import java.util.HashSet JavaDoc;
53 import java.util.Iterator JavaDoc;
54 import java.util.Map JavaDoc;
55 import java.util.Set JavaDoc;
56 //#endif
57

58 import com.quadcap.util.Debug;
59
60 /**
61  * A simple implementation of a directed graph of Objects. Each node
62  * is represented using HashSets of incoming and outgoing arcs.
63  *
64  * @author Stan Bailes
65  */

66 public class DiGraph {
67     // Could replace by any Map
68
final HashMap JavaDoc nodes = new HashMap JavaDoc();
69     
70     public DiGraph() {}
71
72     public void addNode(Object JavaDoc obj) {
73     mapNode(obj);
74     }
75
76     public final Iterator JavaDoc getNodes() {
77     return new NodeIterator(nodes.values().iterator());
78     }
79
80     public void addArc(Object JavaDoc from, Object JavaDoc to) {
81     Node f = mapNode(from);
82     Node t = mapNode(to);
83     f.addTo(t);
84     t.addFrom(f);
85     }
86
87     public final boolean hasChildren(Object JavaDoc obj) {
88     return mapNode(obj).toSize() > 0;
89     }
90
91     public final boolean hasParents(Object JavaDoc obj) {
92     return mapNode(obj).fromSize() > 0;
93     }
94
95     public boolean hasNode(Object JavaDoc obj) {
96     Node node = (Node)nodes.get(obj);
97     return node != null;
98     }
99
100     public final Iterator JavaDoc getParents(Object JavaDoc to) {
101     return new NodeIterator(mapNode(to).iterateFrom());
102     }
103
104     public final Iterator JavaDoc getChildren(Object JavaDoc from) {
105     return new NodeIterator(mapNode(from).iterateTo());
106     }
107
108     public void removeNode(Object JavaDoc obj, boolean force) {
109     Node node = mapNode(obj);
110     if (!force) {
111         if (node.toSize() != 0 || node.fromSize() != 0) {
112         throw new RuntimeException JavaDoc("node has links");
113         }
114     } else {
115         Iterator JavaDoc iter = node.iterateTo();
116         while (iter.hasNext()) {
117         Node to = (Node)iter.next();
118         node.removeTo(to);
119         to.removeFrom(node);
120         }
121         iter = node.iterateFrom();
122         while (iter.hasNext()) {
123         Node from = (Node)iter.next();
124         node.removeFrom(from);
125         from.removeTo(node);
126         }
127     }
128     nodes.remove(obj);
129     }
130
131     public void removeArc(Object JavaDoc from, Object JavaDoc to) {
132     Node f = mapNode(from);
133     Node t = mapNode(to);
134     f.removeTo(t);
135     t.removeFrom(f);
136     }
137
138     public Iterator JavaDoc levelize() {
139         return levelize(false);
140     }
141     
142     public Iterator JavaDoc levelize(boolean cyclesOK) {
143     ArrayList JavaDoc v = new ArrayList JavaDoc();
144     Iterator JavaDoc iter = nodes.values().iterator();
145     while (iter.hasNext()) {
146         Node node = (Node)iter.next();
147         node.level = -1;
148         node.visitCnt = 0;
149         if (node.fromSize() == 0) {
150         node.level = 0;
151         v.add(node);
152         }
153     }
154     for (int i = 0; i < v.size(); i++) {
155         Node node = (Node)v.get(i);
156         Iterator JavaDoc t = node.iterateTo();
157         while (t.hasNext()) {
158         Node to = (Node)t.next();
159         if (++to.visitCnt == to.fromSize()) {
160             to.level = node.level + 1;
161             v.add(to);
162         }
163         }
164     }
165         if (!cyclesOK && v.size() != nodes.size()) {
166         throw new RuntimeException JavaDoc("can't levelize, contains cycles");
167     }
168     return new NodeIterator(v.iterator());
169     }
170
171     public String JavaDoc toString() {
172     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
173     Iterator JavaDoc iter = getNodes();
174     String JavaDoc ldelim = "";
175     while (iter.hasNext()) {
176         sb.append(ldelim);
177         ldelim = "\n";
178         Object JavaDoc obj = iter.next();
179         Iterator JavaDoc i2 = getParents(obj);
180         String JavaDoc delim = "";
181         sb.append("(");
182         while (i2.hasNext()) {
183         sb.append(delim);
184         delim = " ";
185         sb.append(i2.next().toString());
186         }
187         sb.append(") ");
188         sb.append(obj.toString());
189         sb.append(" (");
190         i2 = getChildren(obj);
191         delim = "";
192         while (i2.hasNext()) {
193         sb.append(delim);
194         delim = " ";
195         sb.append(i2.next().toString());
196         }
197         sb.append(") ");
198     }
199     return sb.toString();
200     }
201
202     final Node mapNode(Object JavaDoc obj) {
203     Node node = (Node)nodes.get(obj);
204     if (node == null) {
205         node = new Node(obj);
206         nodes.put(obj, node);
207     }
208     return node;
209     }
210         
211     class Node implements Comparable JavaDoc {
212     Object JavaDoc obj;
213
214     final HashSet JavaDoc to = new HashSet JavaDoc();
215     final HashSet JavaDoc from = new HashSet JavaDoc();
216     int level = 0;
217     int visitCnt = 0;
218
219     Node(Object JavaDoc obj) { this.obj = obj; }
220     void addTo(Node node) {
221         to.add(node);
222     }
223     void addFrom(Node node) {
224         from.add(node);
225     }
226     void removeTo(Node obj) { to.remove(obj); }
227     void removeFrom(Node obj) { from.remove(obj); }
228
229     int toSize() { return to.size(); }
230     int fromSize() { return from.size(); }
231
232     Iterator JavaDoc iterateTo() { return to.iterator(); }
233     Iterator JavaDoc iterateFrom() { return from.iterator(); }
234
235     public int compareTo(Object JavaDoc other) {
236         Node no = (Node)other;
237         return ((Comparable JavaDoc)obj).compareTo(no.obj);
238     }
239
240     public int hashCode() { return obj.hashCode(); }
241
242     public boolean equals(Object JavaDoc obj) {
243         return 0 == compareTo(obj);
244     }
245     public String JavaDoc toString() {
246         return obj.toString();
247     }
248     }
249
250     class NodeIterator implements Iterator JavaDoc {
251     Iterator JavaDoc iter;
252     NodeIterator(Iterator JavaDoc iter) { this.iter = iter; }
253     public boolean hasNext() { return iter.hasNext(); }
254     public Object JavaDoc next() {
255         Node node = (Node)iter.next();
256         return node.obj;
257     }
258     public void remove() {}
259     }
260 }
261
262
Popular Tags