1 25 41 package org.jgrapht.alg; 42 43 import java.util.*; 44 45 import org.jgrapht.*; 46 import org.jgrapht.traverse.*; 47 48 49 57 public class CycleDetector<V, E> 58 { 59 60 62 65 Graph<V, E> graph; 66 67 69 75 public CycleDetector(DirectedGraph<V, E> graph) 76 { 77 this.graph = graph; 78 } 79 80 82 87 public boolean detectCycles() 88 { 89 try { 90 execute(null, null); 91 } catch (CycleDetectedException ex) { 92 return true; 93 } 94 95 return false; 96 } 97 98 105 public boolean detectCyclesContainingVertex(V v) 106 { 107 try { 108 execute(null, v); 109 } catch (CycleDetectedException ex) { 110 return true; 111 } 112 113 return false; 114 } 115 116 122 public Set<V> findCycles() 123 { 124 Set<V> set = new HashSet<V>(); 125 execute(set, null); 126 127 return set; 128 } 129 130 138 public Set<V> findCyclesContainingVertex(V v) 139 { 140 Set<V> set = new HashSet<V>(); 141 execute(set, v); 142 143 return set; 144 } 145 146 private void execute(Set<V> s, V v) 147 { 148 ProbeIterator iter = new ProbeIterator(s, v); 149 150 while (iter.hasNext()) { 151 iter.next(); 152 } 153 } 154 155 157 161 private static class CycleDetectedException 162 extends RuntimeException 163 { 164 private static final long serialVersionUID = 3834305137802950712L; 165 } 166 167 171 private class ProbeIterator 172 extends DepthFirstIterator<V, E> 173 { 174 private List<V> path; 175 private Set<V> cycleSet; 176 177 ProbeIterator(Set<V> cycleSet, V startVertex) 178 { 179 super(graph, startVertex); 180 this.cycleSet = cycleSet; 181 path = new ArrayList<V>(); 182 } 183 184 187 protected void encounterVertexAgain(V vertex, E edge) 188 { 189 super.encounterVertexAgain(vertex, edge); 190 191 int i = path.indexOf(vertex); 192 193 if (i > -1) { 194 if (cycleSet == null) { 195 throw new CycleDetectedException(); 197 } 198 199 for (; i < path.size(); ++i) { 200 cycleSet.add(path.get(i)); 201 } 202 } 203 } 204 205 208 protected V provideNextVertex() 209 { 210 V v = super.provideNextVertex(); 211 212 for (int i = path.size() - 1; i >= 0; --i) { 214 if (graph.containsEdge(path.get(i), v)) { 215 break; 216 } 217 218 path.remove(i); 219 } 220 221 path.add(v); 222 223 return v; 224 } 225 } 226 } 227 | Popular Tags |