Code with Finding: |
class FixedPointGraphTraversal {
/**
* Compute a fixed point for the given graph, entering from the given nodes.
* @param graph The graph to traverse.
* @param entrySet The nodes to begin traversing from.
*/
public void computeFixedPoint(DiGraph<N, E> graph, Set<N> entrySet) {
int cycleCount = 0;
long nodeCount = graph.getNodes().size();
// Choose a bail-out heuristically in case the computation
// doesn't converge.
long maxIterations = Math.max(nodeCount * nodeCount * nodeCount, 100);
// Use a LinkedHashSet, so that the traversal is deterministic.
LinkedHashSet<DiGraphNode<N, E>> workSet =
Sets.newLinkedHashSet();
for (N n : entrySet) {
workSet.add(graph.getDirectedGraphNode(n));
}
for (; !workSet.isEmpty() && cycleCount < maxIterations; cycleCount++) {
// For every out edge in the workSet, traverse that edge. If that
// edge updates the state of the graph, then add the destination
// node to the resultSet, so that we can update all of its out edges
// on the next iteration.
DiGraphNode<N, E> source = workSet.iterator().next();
N sourceValue = source.getValue();
workSet.remove(source);
List<DiGraphEdge<N, E>> outEdges = source.getOutEdges();
for (DiGraphEdge<N, E> edge : outEdges) {
N destNode = edge.getDestination().getValue();
if (callback.traverseEdge(sourceValue, edge.getValue(), destNode)) {
workSet.add(edge.getDestination());
}
}
}
Preconditions.checkState(cycleCount != maxIterations,
NON_HALTING_ERROR_MSG);
}
}
|