2626
2727import org .javanetworkanalyzer .data .VDijkstra ;
2828import org .javanetworkanalyzer .model .EdgeSPT ;
29+ import org .javanetworkanalyzer .model .TraversalGraph ;
2930import org .jgrapht .DirectedGraph ;
3031import org .jgrapht .Graph ;
3132import org .jgrapht .Graphs ;
@@ -52,6 +53,11 @@ public class Dijkstra<V extends VDijkstra, E extends EdgeSPT>
5253 * have the same length.
5354 */
5455 protected static final double TOLERANCE = 0.000000001 ;
56+ /**
57+ * Distance of the node furthest away in the shortest path tree thus far.
58+ */
59+ private double largestDistanceSoFar = 0.0 ;
60+
5561
5662 /**
5763 * Constructor.
@@ -70,10 +76,20 @@ public Dijkstra(Graph<V, E> graph) {
7076 */
7177 @ Override
7278 public void calculate (V startNode ) {
79+ calculate (startNode , Double .POSITIVE_INFINITY );
80+ }
7381
82+ /**
83+ * Does a Dijkstra search from the given start node to all other nodes,
84+ * limiting the search by the given radius.
85+ *
86+ * @param startNode Start node
87+ * @param radius Radius by which to limit the search
88+ */
89+ public void calculate (V startNode , double radius ) {
7490 init (startNode );
7591
76- while (!queue .isEmpty ()) {
92+ while (!queue .isEmpty () && largestDistanceSoFar < radius ) {
7793 // Extract the minimum element.
7894 V u = queue .poll ();
7995 // Do any pre-relax step.
@@ -150,6 +166,7 @@ protected void shortestPathSoFarUpdate(V startNode, V u, V v, Double uvWeight,
150166 v .addPredecessorEdge (e );
151167 // Set the distance
152168 v .setDistance (u .getDistance () + uvWeight );
169+ largestDistanceSoFar = v .getDistance ();
153170 // Update the queue.
154171 queue .remove (v );
155172 queue .add (v );
@@ -188,6 +205,46 @@ public int compare(V v1, V v2) {
188205 });
189206 }
190207
208+ /**
209+ * Returns the SPT from the last start node {@link #calculate} was called on,
210+ * limited by the given radius. The shortest path "tree" we return may
211+ * contain multiple shortest paths.
212+ *
213+ * @param radius The radius to limit by
214+ * @return The SPT/traversal graph from the last start node {@link #calculate}
215+ * was called on
216+ */
217+ public TraversalGraph <V , E > reconstructTraversalGraphLimitedByRadius (double radius ) {
218+
219+ if (currentStartNode == null ) {
220+ throw new IllegalStateException ("You must call #calculate before " +
221+ "reconstructing the traversal graph." );
222+ }
223+
224+ TraversalGraph <V , E > traversalGraph = new TraversalGraph <V , E >(
225+ graph .getEdgeFactory (), currentStartNode );
226+ for (V v : graph .vertexSet ()) {
227+ Set <E > predEdges = (Set <E >) v .getPredecessorEdges ();
228+ for (E e : predEdges ) {
229+ V source = graph .getEdgeSource (e );
230+ V target = graph .getEdgeTarget (e );
231+ if (source .getDistance () < radius && target .getDistance () < radius ) {
232+ traversalGraph .addVertex (source );
233+ traversalGraph .addVertex (target );
234+ if (v .equals (source )) {
235+ traversalGraph .addEdge (target , source ).setBaseGraphEdge (e );
236+ } else if (v .equals (target )) {
237+ traversalGraph .addEdge (source , target ).setBaseGraphEdge (e );
238+ } else {
239+ throw new IllegalStateException ("A vertex has a predecessor " +
240+ "edge not ending on itself." );
241+ }
242+ }
243+ }
244+ }
245+ return traversalGraph ;
246+ }
247+
191248 /**
192249 * Performs a Dijkstra search from the source, stopping once the target is
193250 * found.
0 commit comments