m_traversal.init();
//reset edge visited flags
m_graph.visitNodes(
new GraphVisitor() {
public int visit(Graphable component) {
component.setVisited(false);
return 0;
}
}
);
//perform the traversal
m_traversal.traverse();
//if all nodes of degree 2 have been visited, we are finished
if (m_ndegree2 > 0) {
//if there are still nodes of degree 2 that havent been visited, it means
// that the graph has a cycle and that the remaining degree 2 nodes are
// internal to the cycle, so the strategy for the second stage is to
// find all unvisited nodes of degree 2 that are not visited and start
// a no bifurcation traversal from them
Iterator sources = m_graph.queryNodes(
new GraphVisitor() {
public int visit(Graphable component) {
Node node = (Node)component;
if (!node.isVisited() && node.getDegree() == 2) {
//check for adjacent node of degree > 2
for (Iterator itr = node.getRelated(); itr.hasNext(); ) {
Node rel = (Node)itr.next();
if (rel.getDegree() > 2) return(Graph.PASS_AND_CONTINUE);
}
}
return(Graph.FAIL_QUERY);
}
}
).iterator();
//if the query returned no nodes, it means that all the cycle is
// disconnected from the rest of graph, so just pick any node of degree 2
if (!sources.hasNext()) {
sources = m_graph.queryNodes(
new GraphVisitor() {
public int visit(Graphable component) {
if (!component.isVisited()) return(Graph.PASS_AND_STOP);
return(Graph.FAIL_QUERY);
}
}