public static boolean isAcyclic(Digraph digraph) { int order = digraph.order(); if (order == 0) return true; Set spanned = new HashSet(order); DepthFirstStampSearch dfs = new DepthFirstStampSearch(digraph, digraph.vertexIterator().next()); for (Iterator i = digraph.vertexIterator(); i.hasNext(); ) { Object dfsRoot = i.next(); if (spanned.contains(dfsRoot)) continue; dfs.reset(dfsRoot); Map dfsOrders = dfs.traverse(new HashMap(digraph.order())); for (Iterator j = dfsOrders.entrySet().iterator(); j.hasNext(); ) { Map.Entry entry = (Map.Entry) j.next(); Object origin = entry.getKey(); DepthFirstStampSearch.OrderPair orgOrders = (DepthFirstStampSearch.OrderPair) entry.getValue(); spanned.add(origin); for (ArcIterator k = digraph.outgoingIterator(origin); k.hasNext(); ) { k.next(); Object dst = k.getDestination(); DepthFirstStampSearch.OrderPair dstOrders = (DepthFirstStampSearch.OrderPair) dfsOrders.get(dst); if (dstOrders.getPostOrder() > orgOrders.getPostOrder()) return false; } } if (dfsOrders.size() == order) break; } return true; }
public static boolean isTree(Digraph digraph) { Object root = null; for (Iterator i = digraph.vertexIterator(); i.hasNext(); ) { Object vertex = i.next(); int inSize = digraph.incomingSize(vertex); if (inSize == 0) { root = vertex; break; } } // not a tree - no vertex with 0 in-degree if (root == null) return false; // try to reach all vertices from the root candidate BreadthFirstSearch traversal = new BreadthFirstSearch(digraph, root); while (traversal.isValidTree() && traversal.hasNext()) traversal.next(); // not a tree - one of vertices has been seen more than once by the BFS if (!traversal.isValidTree()) return false; // has every vertex been reached? Set seenVertices = traversal.getSeenVertices(); for (Iterator i = digraph.vertexIterator(); i.hasNext(); ) if (!seenVertices.contains(i.next())) return false; // all tests are passed - good! return true; }
public static List findCycles(DigraphIteration graph) { ArrayStack stack = new ArrayStack(); ArrayStack path = new ArrayStack(); Set seen = new HashSet(); List cycles = new ArrayList(); Iterator vertexIterator = graph.vertexIterator(); while (vertexIterator.hasNext()) { while (vertexIterator.hasNext()) { Object vertex = vertexIterator.next(); if (seen.add(vertex)) { stack.push(graph.outgoingIterator(vertex)); path.push(vertex); break; } } while (!stack.isEmpty()) { ArcIterator i = (ArcIterator) stack.peek(); Object origin = i.getOrigin(); boolean subtreeIsTraversed = true; while (i.hasNext()) { i.next(); Object dst = i.getDestination(); int index = path.indexOf(dst); if (index < 0) { seen.add(dst); stack.push(graph.outgoingIterator(dst)); path.push(dst); subtreeIsTraversed = false; break; } else { cycles.add(new ArrayList(path.subList(index, path.size()))); } } if (subtreeIsTraversed) { stack.pop(); path.pop(); } } } return cycles; }