| 1 | |
|
| 2 | |
|
| 3 | |
|
| 4 | |
|
| 5 | |
|
| 6 | |
|
| 7 | |
|
| 8 | |
|
| 9 | |
|
| 10 | |
|
| 11 | |
|
| 12 | |
|
| 13 | |
|
| 14 | |
|
| 15 | |
|
| 16 | |
|
| 17 | |
|
| 18 | |
|
| 19 | |
|
| 20 | |
|
| 21 | |
|
| 22 | |
package net.sourceforge.combean.graph.alg.traversal; |
| 23 | |
|
| 24 | |
import java.util.BitSet; |
| 25 | |
|
| 26 | |
import net.sourceforge.combean.graph.alg.AbstractGraphAlg; |
| 27 | |
import net.sourceforge.combean.graph.containers.NodeSetAdvisor; |
| 28 | |
import net.sourceforge.combean.interfaces.graph.EdgeIterator; |
| 29 | |
import net.sourceforge.combean.interfaces.graph.Node; |
| 30 | |
import net.sourceforge.combean.interfaces.graph.NodeIterator; |
| 31 | |
import net.sourceforge.combean.interfaces.graph.alg.traverse.GraphTraversalAlg; |
| 32 | |
import net.sourceforge.combean.interfaces.graph.alg.traverse.TraversalVisitor; |
| 33 | |
import net.sourceforge.combean.interfaces.graph.containers.NodeSet; |
| 34 | |
import net.sourceforge.combean.interfaces.graph.prop.GlobalNodesGraphProp; |
| 35 | |
import net.sourceforge.combean.interfaces.graph.prop.NeighborhoodGraphProp; |
| 36 | |
import net.sourceforge.combean.interfaces.graph.prop.OutgoingEdgeNeighborhoodGraphProp; |
| 37 | |
|
| 38 | |
|
| 39 | |
|
| 40 | |
|
| 41 | |
|
| 42 | |
|
| 43 | |
|
| 44 | |
public abstract class AbstractGraphTraversalAlg extends AbstractGraphAlg implements |
| 45 | |
GraphTraversalAlg { |
| 46 | |
|
| 47 | 78 | private TraversalVisitor visitor = null; |
| 48 | |
|
| 49 | 78 | private Node startNode = null; |
| 50 | |
|
| 51 | 78 | private GlobalNodesGraphProp globalNodes = null; |
| 52 | 78 | private NeighborhoodGraphProp graph = null; |
| 53 | 78 | private OutgoingEdgeNeighborhoodGraphProp outgoingNeigh = null; |
| 54 | |
|
| 55 | 78 | private NodeSet visitedNodes = null; |
| 56 | |
|
| 57 | 78 | private boolean useOnlyOutgoingEdges = false; |
| 58 | |
|
| 59 | |
|
| 60 | |
|
| 61 | |
|
| 62 | |
public AbstractGraphTraversalAlg() { |
| 63 | 78 | super(); |
| 64 | 78 | } |
| 65 | |
|
| 66 | |
|
| 67 | |
|
| 68 | |
|
| 69 | |
public void setVisitor(TraversalVisitor visitor) { |
| 70 | 93 | this.visitor = visitor; |
| 71 | 93 | } |
| 72 | |
|
| 73 | |
|
| 74 | |
|
| 75 | |
|
| 76 | |
public final TraversalVisitor getVisitor() { |
| 77 | 1557 | return this.visitor; |
| 78 | |
} |
| 79 | |
|
| 80 | |
|
| 81 | |
|
| 82 | |
|
| 83 | |
public final void setLocalStartNode(Node startNode) { |
| 84 | 45 | this.startNode = startNode; |
| 85 | 45 | } |
| 86 | |
|
| 87 | |
|
| 88 | |
|
| 89 | |
|
| 90 | |
private final Node getStartNode() { |
| 91 | 354 | return this.startNode; |
| 92 | |
} |
| 93 | |
|
| 94 | |
|
| 95 | |
|
| 96 | |
|
| 97 | |
|
| 98 | |
|
| 99 | |
|
| 100 | |
|
| 101 | |
public final void setVisitedNodes(NodeSet visitedNodes) { |
| 102 | 30 | this.visitedNodes = visitedNodes; |
| 103 | 30 | } |
| 104 | |
|
| 105 | |
|
| 106 | |
|
| 107 | |
|
| 108 | |
protected final NodeSet getVisitedNodes() { |
| 109 | 1059 | return this.visitedNodes; |
| 110 | |
} |
| 111 | |
|
| 112 | |
|
| 113 | |
|
| 114 | |
|
| 115 | |
public void setUseOnlyOutgoingEdges(boolean useOnlyOutgoingEdges) { |
| 116 | 39 | this.useOnlyOutgoingEdges = useOnlyOutgoingEdges; |
| 117 | 39 | } |
| 118 | |
|
| 119 | |
|
| 120 | |
|
| 121 | |
|
| 122 | |
protected final NeighborhoodGraphProp getNeighborhood() { |
| 123 | 771 | return this.graph; |
| 124 | |
} |
| 125 | |
|
| 126 | |
|
| 127 | |
|
| 128 | |
|
| 129 | |
protected void init() { |
| 130 | 99 | if (this.useOnlyOutgoingEdges) { |
| 131 | 27 | this.outgoingNeigh = (OutgoingEdgeNeighborhoodGraphProp) getGraph(); |
| 132 | |
} |
| 133 | |
|
| 134 | 99 | if (this.visitedNodes == null) { |
| 135 | 48 | this.visitedNodes = NodeSetAdvisor.getFastestNodeSet(getNeighborhood(), |
| 136 | |
new BitSet(NodeSetAdvisor.NUM_PROPS)); |
| 137 | |
} |
| 138 | 99 | this.visitedNodes.clear(); |
| 139 | 99 | } |
| 140 | |
|
| 141 | |
|
| 142 | |
|
| 143 | |
|
| 144 | |
|
| 145 | |
|
| 146 | |
|
| 147 | |
protected abstract void runTraversalWithSingleStartNode(Node v); |
| 148 | |
|
| 149 | |
protected final EdgeIterator getNeighborIterator(Node v) { |
| 150 | 552 | if (this.useOnlyOutgoingEdges) { |
| 151 | 114 | return this.outgoingNeigh.getOutgoingEdges(v); |
| 152 | |
} |
| 153 | 438 | return this.graph.getIncidentEdges(v); |
| 154 | |
} |
| 155 | |
|
| 156 | |
|
| 157 | |
|
| 158 | |
|
| 159 | |
public void run() { |
| 160 | 99 | init(); |
| 161 | |
|
| 162 | 99 | if (getStartNode() == null) { |
| 163 | 48 | getVisitor().init(getNeighborhood()); |
| 164 | 48 | runTraversalForAllNodes(); |
| 165 | |
} |
| 166 | |
else { |
| 167 | 51 | getVisitor().initLocal(getNeighborhood(), getStartNode()); |
| 168 | 51 | getVisitor().visitComponent(getStartNode()); |
| 169 | 51 | getVisitedNodes().add(getStartNode()); |
| 170 | 51 | runTraversalWithSingleStartNode(getStartNode()); |
| 171 | 51 | getVisitor().leaveComponent(getStartNode()); |
| 172 | |
} |
| 173 | 99 | } |
| 174 | |
|
| 175 | |
|
| 176 | |
|
| 177 | |
|
| 178 | |
|
| 179 | |
private void runTraversalForAllNodes() { |
| 180 | 48 | NodeIterator allNodesIt = this.globalNodes.getAllNodesIterator(); |
| 181 | 342 | while (allNodesIt.hasNext()) { |
| 182 | 294 | Node v = allNodesIt.next(); |
| 183 | 294 | if (!getVisitedNodes().contains(v)) { |
| 184 | 90 | getVisitor().visitComponent(v); |
| 185 | 90 | getVisitedNodes().add(v); |
| 186 | 90 | runTraversalWithSingleStartNode(v); |
| 187 | 90 | getVisitor().leaveComponent(v); |
| 188 | |
} |
| 189 | 294 | } |
| 190 | 48 | } |
| 191 | |
} |