|
| 1 | +package ca.mcmaster.chapter.four.graph.spt; |
| 2 | + |
| 3 | +import java.io.File; |
| 4 | +import java.io.FileInputStream; |
| 5 | +import java.io.FileNotFoundException; |
| 6 | +import java.util.Stack; |
| 7 | + |
| 8 | +import edu.princeton.cs.algs4.IndexMinPQ; |
| 9 | + |
| 10 | +public class DijkstraSP implements SP { |
| 11 | + private DirectedEdge[] edgeTo; |
| 12 | + private double[] distTo; |
| 13 | + private IndexMinPQ<Double> pq; //优先级队列,存储了到每个顶点的dist |
| 14 | + public DijkstraSP(EdgeWeightedDigraph g, int s) { |
| 15 | + edgeTo = new DirectedEdge[g.V()]; |
| 16 | + distTo = new double[g.V()]; |
| 17 | + pq = new IndexMinPQ<>(g.V()); |
| 18 | + for(int v = 0; v < g.V(); v++) |
| 19 | + distTo[v] = Double.POSITIVE_INFINITY; |
| 20 | + distTo[s] = 0D; |
| 21 | + pq.insert(s, 0D); |
| 22 | + while(!pq.isEmpty()) |
| 23 | + relax(g, pq.delMin()); |
| 24 | + } |
| 25 | + @Override |
| 26 | + public double distTo(int v) { |
| 27 | + return distTo[v]; |
| 28 | + } |
| 29 | + @Override |
| 30 | + public boolean hasPathTo(int v) { |
| 31 | + return distTo[v] < Double.POSITIVE_INFINITY; |
| 32 | + } |
| 33 | + @Override |
| 34 | + public Iterable<DirectedEdge> pathTo(int v) { |
| 35 | + if(!hasPathTo(v)) return null; |
| 36 | + Stack<DirectedEdge> stack = new Stack<>(); |
| 37 | + while(edgeTo[v] != null){ |
| 38 | + DirectedEdge e = edgeTo[v]; |
| 39 | + stack.push(e); |
| 40 | + v = e.from(); |
| 41 | + } |
| 42 | + return stack; |
| 43 | + } |
| 44 | + /** |
| 45 | + * @Description: Relax the edge e. |
| 46 | + * @param e |
| 47 | + */ |
| 48 | + @SuppressWarnings("unused") |
| 49 | + private void relax(DirectedEdge e){ |
| 50 | + int v = e.from(); int w = e.to(); |
| 51 | + if(distTo(w) > distTo(v) + e.weight()){ |
| 52 | + distTo[w] = distTo[v] + e.weight(); |
| 53 | + edgeTo[w] = e; |
| 54 | + } |
| 55 | + } |
| 56 | + /** |
| 57 | + * @Description: G is digraph and v is a vertex. |
| 58 | + * @param g |
| 59 | + * @param v |
| 60 | + */ |
| 61 | + private void relax(EdgeWeightedDigraph g, int v){ |
| 62 | + for(DirectedEdge e:g.adj(v)){ |
| 63 | + int w = e.to(); //e is from v to w. |
| 64 | + if(distTo[w] > distTo[v] + e.weight()){ |
| 65 | + distTo[w] = distTo[v] + e.weight(); |
| 66 | + edgeTo[w] = e; |
| 67 | + if(pq.contains(w)) pq.changeKey(w, distTo[w]); |
| 68 | + else pq.insert(w, distTo[w]); |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + public static void main(String[] args) throws FileNotFoundException { |
| 73 | + FileInputStream is = new FileInputStream(new File("src/ca/mcmaster/chapter/four/graph/spt/tinyEWD.txt")); |
| 74 | + EdgeWeightedDigraph g = new EdgeWeightedDigraph(is); |
| 75 | + DijkstraSP dijkstraSP = new DijkstraSP(g, 0); |
| 76 | + Stack<DirectedEdge> pathTo = (Stack<DirectedEdge>) dijkstraSP.pathTo(6); |
| 77 | + StringBuilder sb = new StringBuilder(); |
| 78 | + DirectedEdge edge = pathTo.pop(); |
| 79 | + sb.append(edge.from() + "->"); |
| 80 | + sb.append(edge.to() + "->"); |
| 81 | + while(!pathTo.empty()){ |
| 82 | + sb.append(pathTo.pop().to() + "->"); |
| 83 | + } |
| 84 | + System.out.println(sb.toString()); |
| 85 | + } |
| 86 | +} |
0 commit comments