1 22 package org.jboss.util.graph; 23 24 import java.util.LinkedList ; 25 import java.util.ArrayList ; 26 27 35 public class Graph<T> 36 { 37 38 public static final int VISIT_COLOR_WHITE = 1; 39 40 public static final int VISIT_COLOR_GREY = 2; 41 42 public static final int VISIT_COLOR_BLACK = 3; 43 44 private ArrayList <Vertex<T>> verticies; 45 46 private ArrayList <Edge<T>> edges; 47 48 public Graph() 50 { 51 verticies = new ArrayList <Vertex<T>>(); 52 edges = new ArrayList <Edge<T>>(); 53 } 54 55 59 public boolean isEmpty() 60 { 61 return verticies.size() == 0; 62 } 63 64 69 public boolean addVertex(Vertex<T> v) 70 { 71 return verticies.add(v); 72 } 73 74 78 public int size() 79 { 80 return verticies.size(); 81 } 82 83 88 public Vertex<T> getVertex(int n) 89 { 90 Vertex<T> v = verticies.get(n); 91 return v; 92 } 93 94 101 public boolean addEdge(Vertex<T> from, Vertex<T> to, int cost) 102 { 103 Edge<T> e = new Edge<T>(from, to, cost); 104 if (from.findEdge(to) != null) 105 return false; 106 else 107 { 108 from.addEdge(e); 109 to.addEdge(e); 110 edges.add(e); 111 return true; 112 } 113 } 114 115 122 public boolean insertBiEdge(Vertex<T> from, Vertex<T> to, int cost) 123 { 124 return addEdge(from, to, cost) && addEdge(to, from, cost); 125 } 126 127 132 public boolean removeVertex(Vertex<T> from) 133 { 134 if (!verticies.contains(from)) 135 return false; 136 137 verticies.remove(from); 138 for(int n = 0; n < from.getOutgoingEdgeCount(); n ++) 139 { 140 Edge<T> e = from.getOutgoingEdge(n); 141 from.remove(e); 142 Vertex<T> to = e.getTo(); 143 to.remove(e); 144 edges.remove(e); 145 } 146 for(int n = 0; n < from.getIncomingEdgeCount(); n ++) 147 { 148 Edge<T> e = from.getIncomingEdge(n); 149 from.remove(e); 150 Vertex<T> predecessor = e.getFrom(); 151 predecessor.remove(e); 152 } 153 return true; 154 } 155 156 162 public boolean removeEdge(Vertex<T> from, Vertex<T> to) 163 { 164 Edge<T> e = from.findEdge(to); 165 if (e == null) 166 return false; 167 else 168 { 169 from.remove(e); 170 to.remove(e); 171 edges.remove(e); 172 return true; 173 } 174 } 175 176 181 public void clearMark() 182 { 183 for (int i = 0; i < verticies.size(); i++) 184 { 185 Vertex<T> w = verticies.get(i); 186 w.clearMark(); 187 } 188 } 189 190 195 public void clearEdges() 196 { 197 for (int i = 0; i < edges.size(); i++) 198 { 199 Edge<T> e = (Edge<T>) edges.get(i); 200 e.clearMark(); 201 } 202 } 203 204 210 public void depthFirstSearch(Vertex<T> v, final Visitor<T> visitor) 211 { 212 VisitorEX<T, RuntimeException > wrapper = new VisitorEX<T, RuntimeException >() 213 { 214 public void visit(Graph<T> g, Vertex<T> v) throws RuntimeException 215 { 216 visitor.visit(g, v); 217 } 218 }; 219 this.depthFirstSearch(v, wrapper); 220 } 221 public <E extends Exception > void depthFirstSearch(Vertex<T> v, VisitorEX<T, E> visitor) 222 throws E 223 { 224 if( visitor != null ) 225 visitor.visit(this, v); 226 v.visit(); 227 for (int i = 0; i < v.getOutgoingEdgeCount(); i++) 228 { 229 Edge<T> e = v.getOutgoingEdge(i); 230 if (!e.getTo().visited()) 231 { 232 depthFirstSearch(e.getTo(), visitor); 233 } 234 } 235 } 236 237 public void breadthFirstSearch(Vertex<T> v, final Visitor<T> visitor) 239 { 240 VisitorEX<T, RuntimeException > wrapper = new VisitorEX<T, RuntimeException >() 241 { 242 public void visit(Graph<T> g, Vertex<T> v) throws RuntimeException 243 { 244 visitor.visit(g, v); 245 } 246 }; 247 this.breadthFirstSearch(v, wrapper); 248 } 249 public <E extends Exception > void breadthFirstSearch(Vertex<T> v, VisitorEX<T, E> visitor) 250 throws E 251 { 252 LinkedList <Vertex<T>> q = new LinkedList <Vertex<T>>(); 253 254 q.add(v); 255 if( visitor != null ) 256 visitor.visit(this, v); 257 v.visit(); 258 while (q.isEmpty() == false) 259 { 260 v = q.removeFirst(); 261 for (int i = 0; i < v.getOutgoingEdgeCount(); i++) 262 { 263 Edge<T> e = v.getOutgoingEdge(i); 264 if (!e.getTo().visited()) 265 { 266 q.add(e.getTo()); 267 if( visitor != null ) 268 visitor.visit(this, e.getTo()); 269 e.getTo().visit(); 270 } 271 } 272 } 273 } 274 275 public void dfsSpanningTree(Vertex<T> v, DFSVisitor<T> visitor) 277 { 278 v.visit(); 279 if( visitor != null ) 280 visitor.visit(this, v); 281 282 for (int i = 0; i < v.getOutgoingEdgeCount(); i++) 283 { 284 Edge<T> e = v.getOutgoingEdge(i); 285 if (!e.getTo().visited()) 286 { 287 if( visitor != null ) 288 visitor.visit(this, v, e); 289 e.mark(); 290 dfsSpanningTree(e.getTo(), visitor); 291 } 292 } 293 } 294 295 296 303 public Edge<T>[] findCycles() 304 { 305 ArrayList <Edge<T>> cycleEdges = new ArrayList <Edge<T>>(); 306 for(int n = 0; n < verticies.size(); n ++) 308 { 309 Vertex<T> v = getVertex(n); 310 v.setMarkState(VISIT_COLOR_WHITE); 311 } 312 for(int n = 0; n < verticies.size(); n ++) 313 { 314 Vertex<T> v = getVertex(n); 315 visit(v, cycleEdges); 316 } 317 Edge<T>[] cycles = new Edge[cycleEdges.size()]; 318 cycleEdges.toArray(cycles); 319 return cycles; 320 } 321 322 private void visit(Vertex<T> v, ArrayList <Edge<T>> cycleEdges) 323 { 324 v.setMarkState(VISIT_COLOR_GREY); 325 int count = v.getOutgoingEdgeCount(); 326 for(int n = 0; n < count; n ++) 327 { 328 Edge<T> e = v.getOutgoingEdge(n); 329 Vertex<T> u = e.getTo(); 330 if( u.getMarkState() == VISIT_COLOR_GREY ) 331 { 332 cycleEdges.add(e); 334 } 335 else if( u.getMarkState() == VISIT_COLOR_WHITE ) 336 { 337 visit(u, cycleEdges); 338 } 339 } 340 v.setMarkState(VISIT_COLOR_BLACK); 341 } 342 343 public String toString() 344 { 345 StringBuffer tmp = new StringBuffer ("Graph["); 346 for (int i = 0; i < verticies.size(); i++) 347 { 348 Vertex<T> v = verticies.get(i); 349 tmp.append(v); 350 } 351 tmp.append(']'); 352 return tmp.toString(); 353 } 354 355 } 356 | Popular Tags |