1 25 package classycle.graph; 26 27 import java.util.Enumeration ; 28 import java.util.Hashtable ; 29 import java.util.Stack ; 30 import java.util.Vector ; 31 32 39 public class StrongComponentProcessor extends GraphProcessor { 40 private final boolean _calculateAttributes; 41 private int _counter; 42 private Stack _vertexStack = new Stack (); 43 private Vector _strongComponents = new Vector (); 44 private Hashtable _vertexToComponents = new Hashtable (); 45 private StrongComponent[] _graph; 46 47 52 public StrongComponentProcessor(boolean calculateAttributes) { 53 _calculateAttributes = calculateAttributes; 54 } 55 56 59 public StrongComponent[] getStrongComponents() { 60 return _graph; 61 } 62 63 protected void initializeProcessing(Vertex[] graph) { 64 _counter = 0; 65 _vertexStack.setSize(0); 66 _strongComponents.setSize(0); 67 _vertexToComponents.clear(); 68 } 69 70 74 protected void processBefore(Vertex vertex) { 75 final AtomicVertex atomicVertex = castAsAtomicVertex(vertex); 76 atomicVertex.setOrder(_counter); 77 atomicVertex.setLow(_counter++); 78 _vertexStack.push(atomicVertex); 79 } 80 81 85 protected void processArc(Vertex tail, Vertex head) { 86 final AtomicVertex t = castAsAtomicVertex(tail); 87 final AtomicVertex h = castAsAtomicVertex(head); 88 if (h.isGraphVertex()) { 89 if (!h.isVisited()) { 90 process(h); 91 t.setLow(Math.min(t.getLow(), h.getLow())); 92 } else if (h.getOrder() < t.getOrder() && _vertexStack.contains(h)) { 93 t.setLow(Math.min(t.getLow(), h.getOrder())); 94 } 95 } 96 } 97 98 104 protected void processAfter(Vertex vertex) { 105 final AtomicVertex atomicVertex = castAsAtomicVertex(vertex); 106 if (atomicVertex.getLow() == atomicVertex.getOrder()) { 107 StrongComponent component = new StrongComponent(); 108 while (!_vertexStack.isEmpty() 109 && ((AtomicVertex) _vertexStack.peek()).getOrder() 110 >= atomicVertex.getOrder()) { 111 AtomicVertex vertexOfComponent = (AtomicVertex) _vertexStack.pop(); 112 component.addVertex(vertexOfComponent); 113 _vertexToComponents.put(vertexOfComponent, component); 114 } 115 _strongComponents.addElement(component); 116 } 117 } 118 119 124 protected void finishProcessing(Vertex[] graph) { 125 _graph = new StrongComponent[_strongComponents.size()]; 126 for (int i = 0; i < _graph.length; i++) { 127 _graph[i] = (StrongComponent) _strongComponents.elementAt(i); 128 if (_calculateAttributes) { 129 _graph[i].calculateAttributes(); 130 } 131 } 132 133 Enumeration keys = _vertexToComponents.keys(); 134 while (keys.hasMoreElements()) { 135 AtomicVertex vertex = (AtomicVertex) keys.nextElement(); 136 StrongComponent tail = (StrongComponent) _vertexToComponents.get(vertex); 137 for (int i = 0, n = vertex.getNumberOfOutgoingArcs(); i < n; i++) { 138 AtomicVertex h = (AtomicVertex) vertex.getHeadVertex(i); 139 if (h.isGraphVertex()) { 140 StrongComponent head = (StrongComponent) _vertexToComponents.get(h); 141 if (head != null && head != tail) { 142 tail.addOutgoingArcTo(head); 143 } 144 } 145 } 146 } 147 } 148 149 154 private AtomicVertex castAsAtomicVertex(Vertex vertex) { 155 if (vertex instanceof AtomicVertex) { 156 return (AtomicVertex) vertex; 157 } else { 158 throw new IllegalArgumentException ( 159 vertex + " is not an instance of AtomicVertex"); 160 } 161 } 162 } | Popular Tags |