source: osm/applications/editors/josm/plugins/utilsplugin2/src/edu/princeton/cs/algs4/DijkstraSP.java

Last change on this file was 30737, checked in by donvip, 11 years ago

[josm_plugins] fix Java 7 / unused code warnings

File size: 6.1 KB
Line 
1// License: GPL v3 or later courtesy of author Kevin Wayne
2package edu.princeton.cs.algs4;
3
4/*************************************************************************
5 * Compilation: javac DijkstraSP.java
6 * Execution: java DijkstraSP input.txt s
7 * Dependencies: EdgeWeightedDigraph.java IndexMinPQ.java Stack.java DirectedEdge.java
8 * Data files: http://algs4.cs.princeton.edu/44sp/tinyEWD.txt
9 * http://algs4.cs.princeton.edu/44sp/mediumEWD.txt
10 * http://algs4.cs.princeton.edu/44sp/largeEWD.txt
11 *
12 * Dijkstra's algorithm. Computes the shortest path tree.
13 * Assumes all weights are nonnegative.
14 *
15 * % java DijkstraSP tinyEWD.txt 0
16 * 0 to 0 (0.00)
17 * 0 to 1 (1.05) 0->4 0.38 4->5 0.35 5->1 0.32
18 * 0 to 2 (0.26) 0->2 0.26
19 * 0 to 3 (0.99) 0->2 0.26 2->7 0.34 7->3 0.39
20 * 0 to 4 (0.38) 0->4 0.38
21 * 0 to 5 (0.73) 0->4 0.38 4->5 0.35
22 * 0 to 6 (1.51) 0->2 0.26 2->7 0.34 7->3 0.39 3->6 0.52
23 * 0 to 7 (0.60) 0->2 0.26 2->7 0.34
24 *
25 * % java DijkstraSP mediumEWD.txt 0
26 * 0 to 0 (0.00)
27 * 0 to 1 (0.71) 0->44 0.06 44->93 0.07 ... 107->1 0.07
28 * 0 to 2 (0.65) 0->44 0.06 44->231 0.10 ... 42->2 0.11
29 * 0 to 3 (0.46) 0->97 0.08 97->248 0.09 ... 45->3 0.12
30 * 0 to 4 (0.42) 0->44 0.06 44->93 0.07 ... 77->4 0.11
31 * ...
32 *
33 *************************************************************************/
34
35public class DijkstraSP {
36 private double[] distTo; // distTo[v] = distance of shortest s->v path
37 private DirectedEdge[] edgeTo; // edgeTo[v] = last edge on shortest s->v path
38 private IndexMinPQ<Double> pq; // priority queue of vertices
39
40 public DijkstraSP(EdgeWeightedDigraph G, int s) {
41 distTo = new double[G.V()];
42 edgeTo = new DirectedEdge[G.V()];
43 for (int v = 0; v < G.V(); v++)
44 distTo[v] = Double.POSITIVE_INFINITY;
45 distTo[s] = 0.0;
46
47 // relax vertices in order of distance from s
48 pq = new IndexMinPQ<>(G.V());
49 pq.insert(s, distTo[s]);
50 int count = 0;
51 while (!pq.isEmpty()) {
52 int v = pq.delMin();
53 for (DirectedEdge e : G.adj(v))
54 relax(e);
55 count++;
56 if (count > G.V())
57 throw new RuntimeException("Exceeded limit");
58 }
59
60 // check optimality conditions
61 assert check(G, s);
62 }
63
64 // relax edge e and update pq if changed
65 private void relax(DirectedEdge e) {
66 int v = e.from(), w = e.to();
67 if (distTo[w] > distTo[v] + e.weight()) {
68 distTo[w] = distTo[v] + e.weight();
69 edgeTo[w] = e;
70 if (pq.contains(w)) pq.change(w, distTo[w]);
71 else pq.insert(w, distTo[w]);
72 }
73 }
74
75 // length of shortest path from s to v
76 public double distTo(int v) {
77 return distTo[v];
78 }
79
80 // is there a path from s to v?
81 public boolean hasPathTo(int v) {
82 return distTo[v] < Double.POSITIVE_INFINITY;
83 }
84
85 // shortest path from s to v as an Iterable, null if no such path
86 public Iterable<DirectedEdge> pathTo(int v) {
87 if (!hasPathTo(v)) return null;
88 Stack<DirectedEdge> path = new Stack<>();
89 for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.from()]) {
90 path.push(e);
91 }
92 return path;
93 }
94
95
96 // check optimality conditions:
97 // (i) for all edges e: distTo[e.to()] <= distTo[e.from()] + e.weight()
98 // (ii) for all edge e on the SPT: distTo[e.to()] == distTo[e.from()] + e.weight()
99 private boolean check(EdgeWeightedDigraph G, int s) {
100
101 // check that edge weights are nonnegative
102 for (DirectedEdge e : G.edges()) {
103 if (e.weight() < 0) {
104 System.err.println("negative edge weight detected");
105 return false;
106 }
107 }
108
109 // check that distTo[v] and edgeTo[v] are consistent
110 if (distTo[s] != 0.0 || edgeTo[s] != null) {
111 System.err.println("distTo[s] and edgeTo[s] inconsistent");
112 return false;
113 }
114 for (int v = 0; v < G.V(); v++) {
115 if (v == s) continue;
116 if (edgeTo[v] == null && distTo[v] != Double.POSITIVE_INFINITY) {
117 System.err.println("distTo[] and edgeTo[] inconsistent");
118 return false;
119 }
120 }
121
122 // check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()
123 for (int v = 0; v < G.V(); v++) {
124 for (DirectedEdge e : G.adj(v)) {
125 int w = e.to();
126 if (distTo[v] + e.weight() < distTo[w]) {
127 System.err.println("edge " + e + " not relaxed");
128 return false;
129 }
130 }
131 }
132
133 // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()
134 for (int w = 0; w < G.V(); w++) {
135 if (edgeTo[w] == null) continue;
136 DirectedEdge e = edgeTo[w];
137 int v = e.from();
138 if (w != e.to()) return false;
139 if (distTo[v] + e.weight() != distTo[w]) {
140 System.err.println("edge " + e + " on shortest path not tight");
141 return false;
142 }
143 }
144 return true;
145 }
146
147
148// public static void main(String[] args) {
149// In in = new In(args[0]);
150// EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
151// int s = Integer.parseInt(args[1]);
152//
153// // compute shortest paths
154// DijkstraSP sp = new DijkstraSP(G, s);
155//
156//
157// // print shortest path
158// for (int t = 0; t < G.V(); t++) {
159// if (sp.hasPathTo(t)) {
160// StdOut.printf("%d to %d (%.2f) ", s, t, sp.distTo(t));
161// if (sp.hasPathTo(t)) {
162// for (DirectedEdge e : sp.pathTo(t)) {
163// StdOut.print(e + " ");
164// }
165// }
166// StdOut.println();
167// }
168// else {
169// StdOut.printf("%d to %d no path\n", s, t);
170// }
171// }
172// }
173
174}
Note: See TracBrowser for help on using the repository browser.