blob: 8f1bad03f1ef4d9e9aed37972c6939a4942e2b1f [file] [log] [blame]
tome3489412014-08-29 02:30:38 -07001package org.onlab.graph;
2
3import java.util.ArrayList;
4import java.util.Comparator;
5import java.util.Set;
6
7/**
8 * Dijkstra shortest-path graph search algorithm capable of finding not just
9 * one, but all shortest paths between the source and destinations.
10 */
11public class DijkstraGraphSearch<V extends Vertex, E extends Edge<V>>
tom144de692014-08-29 11:38:44 -070012 extends AbstractGraphPathSearch<V, E> {
tome3489412014-08-29 02:30:38 -070013
14 @Override
tom2e1f0712014-08-29 13:32:00 -070015 public Result<V, E> search(Graph<V, E> graph, V src, V dst,
16 EdgeWeight<V, E> weight) {
17 checkArguments(graph, src, dst);
tome3489412014-08-29 02:30:38 -070018
19 // Use the default result to remember cumulative costs and parent
20 // edges to each each respective vertex.
21 DefaultResult result = new DefaultResult(src, dst);
22
23 // Cost to reach the source vertex is 0 of course.
24 result.updateVertex(src, null, 0.0, false);
25
26 // Use the min priority queue to progressively find each nearest
27 // vertex until we reach the desired destination, if one was given,
28 // or until we reach all possible destinations.
tom2e1f0712014-08-29 13:32:00 -070029 Heap<V> minQueue = createMinQueue(graph.getVertexes(),
tome3489412014-08-29 02:30:38 -070030 new PathCostComparator(result));
31 while (!minQueue.isEmpty()) {
32 // Get the nearest vertex
33 V nearest = minQueue.extractExtreme();
34 if (nearest.equals(dst)) {
35 break;
36 }
37
38 // Find its cost and use it to determine if the vertex is reachable.
39 double cost = result.cost(nearest);
40 if (cost < Double.MAX_VALUE) {
41 // If the vertex is reachable, relax all its egress edges.
tom2e1f0712014-08-29 13:32:00 -070042 for (E e : graph.getEdgesFrom(nearest)) {
Thomas Vachuska4d690872014-10-27 08:57:08 -070043 result.relaxEdge(e, cost, weight, true);
tome3489412014-08-29 02:30:38 -070044 }
45 }
46
47 // Re-prioritize the min queue.
48 minQueue.heapify();
49 }
50
51 // Now construct a set of paths from the results.
52 result.buildPaths();
53 return result;
54 }
55
56 // Compares path weights using their accrued costs; used for sorting the
57 // min priority queue.
58 private final class PathCostComparator implements Comparator<V> {
59 private final DefaultResult result;
60
61 private PathCostComparator(DefaultResult result) {
62 this.result = result;
63 }
64
65 @Override
66 public int compare(V v1, V v2) {
67 double delta = result.cost(v2) - result.cost(v1);
68 return delta < 0 ? -1 : (delta > 0 ? 1 : 0);
69 }
70 }
71
72 // Creates a min priority queue from the specified vertexes and comparator.
73 private Heap<V> createMinQueue(Set<V> vertexes, Comparator<V> comparator) {
74 return new Heap<>(new ArrayList<>(vertexes), comparator);
75 }
76
77}