"Algorithm" notes 12-- Shortest Path

  • Weighted to FIG.
  • data structure
    • Weighted directed edges
    • Weighted to FIG.
    • Shortest Path
  • Slack side
  • Dijkstra's algorithm

Maps or navigation system is a typical application of the shortest path, wherein an intersection corresponding to the vertex, corresponding to the road edge, the edge weight through the costs of a corresponding section of the road (time or distance). In this model, the problem can be summarized as: cost to find a smallest vertex to another vertex arrival path. In addition, network routing, scheduling, also belong to the same problem.

Weighted to FIG.

Weighted directed graph models the Shortest Path Problem. Weighted directed graph, each has the right has associated with it to the side of the weight, weight path weight means a sum of the weights of all edges on the path and, therefore weighted directed graph, find a vertex v to the shortest path of w All weights request routing problem become severe vertex v to w is the smallest.

data structure

Weighted directed edges

Weighted directed edges constituting the base unit to the weighted graph, with the starting point, end point, and weight properties.

public class DirectedEdge {
    private final int v; 
    private final int w; 
    private final double weight; 

    public DirectedEdge(int v, int w, double weight) {
        this.v = v;
        this.w = w;
        this.weight = weight;
    }

    public double weight() {
        return this.weight;
    }

    public int from() {
        return this.v;
    }

    public int to() {
        return this.w;
    }

    public String toString() {
        return String.format("%d->%d %.2f", v, w, weight);
    }
}

Weighted to FIG.

Weighted directed graph data structure, the weighting has a similar manner to the embodiment of FIG tissue to tissue edges with the preceding, except that in the adjacent table, the vertices of a graph is previously stored, is now stored edge.

public class EdgeWeightedDigraph {
    private static final String NEWLINE = System.getProperty("line.separator");
    private final int V; // vertex
    private int E; // edge
    private Bag<DirectedEdge>[] adj;

    public EdgeWeightedDigraph(int V) {
        this.V = V;
        this.E = 0;
        adj = (Bag<DirectedEdge>[]) new Bag[V];
        for (int v = 0; v < V; v++) {
            adj[v] = new Bag<DirectedEdge>();
        }
    }

    public EdgeWeightedDigraph(In in) {
        this(in.readInt());
        int E = in.readInt();
        for (int i = 0; i < E; i++) {
            int v = in.readInt();
            int w = in.readInt();
            double weight = in.readDouble();
            DirectedEdge e = new DirectedEdge(v, w, weight);
            addEdge(e);
        }
    }

    public int V() {
        return V;
    }

    public int E() {
        return E;
    }

    public void addEdge(DirectedEdge e) {
        adj[e.from()].add(e);
        E++;
    }

    public Iterable<DirectedEdge> adj(int v) {
        return adj[v];
    }

    public String toString() {
        StringBuilder s = new StringBuilder();
        s.append(V + " vertices, " + E + " edges " + NEWLINE);
        for (int v = 0; v < V; v++) {
            s.append(v + ": ");
            for (DirectedEdge w : adj[v]) {
                s.append(w + " | ");
            }
            s.append(NEWLINE);
        }
        return s.toString();
    }

    public Bag<DirectedEdge> edges() {
        Bag<DirectedEdge> b = new Bag<DirectedEdge>();
        for (int v = 0; v < V; v++) {
            for (DirectedEdge w : adj[v]) {
                b.add(w);
            }
        }
        return b;
    }
}

Shortest Path

Weighted when calculating the shortest path in the figure, it will use an array of objects of DirectedEdge edgeTo [] array type and a double distTo [].

  • edgeTo represents a shortest path tree preservation is the result of the calculation algorithm. S is the starting point of a shortest path tree is a subgraph, which contains all the vertices from s and s reachable. The tree root node s, each path of the tree there is a shortest path in a directed graph.
    edgeTo index node represents a graph, edgeTo [4] of the node pointed edge points is 4, this edge to = 4, from = 4 junction point vertices, weight = edge weight.
    The edgeTo can constantly be traced along the shortest path tree until the root of the tree s. edgeTo [s] is null.

  • distTo [] storage cost shortest path from the starting point s of a node. Therefore distTo [s] = 0, and s and no agreed communication nodes, the corresponding position in distTo Double.POSITIVE_INFINITY value, so that a position determination is equal Double.POSITIVE_INFINITY distTo can know whether it communicates with respect to s .

Slack side

Based on a simple operation called relaxation (Relaxation) of the shortest path algorithm. FIG edges only know the beginning and their weights, distTo [] elements corresponding to only a starting point, the value of the remaining elements are initialized to the value 0 Double.POSITIVE_INFINITY as, with the execution of the algorithm, it will be the starting point to the other vertex the shortest path information into the edgeTo [] and distTo []. In the face of new edges, will be updated to the shortest path through the relaxation operation. Relaxation operation means for edge v-> w, will be the shortest path from s to check whether the elapsed w v, both s-> v-> w, if so, to update edgeTo [w] and distTo [w], or maintained status quo.

if (distTo[w] > distTo[v] + e.weight()) {
    distTo[w] = distTo[v] + e.weight();
    edgeTo[w] = e;
}

This term comes from the slack with a rubber band firmly expanded along the path connecting the two points analogy, the slack side is similar to a rubber band on a transfer path shorter, more relaxed compared to the previous rubber band.

In the shortest path algorithm, we will try relaxation from a vertex pointed out that all the edges, if a particular relaxation operation changes the value of distTo and edgeTo, then this operation is successful, will eventually find the shortest of each vertex path.

Dijkstra's algorithm

Dijkstra algorithm is implemented based on the above discussion, and in addition distTo edgeTo array, the index also needs a priority queue (IndexMinPQ), needs to be relaxed to save the apex of the next vertex and confirmed to be relaxed. IndexMinPQ addition MinPQ function can also be modified by a value corresponding to the position of the index, using the algorithm to associate IndexMinPQ vertex v and distTo [v], and the index provided from the corresponding path in a relaxed operation.

public class DijkstraSP {
    private DirectedEdge[] edgeTo;
    private double[] distTo;
    private IndexMinPQ<Double> pq;
    int s;

    public DijkstraSP(EdgeWeightedDigraph G, int s) {
        edgeTo = new DirectedEdge[G.V()];
        distTo = new double[G.V()];
        pq = new IndexMinPQ<Double>(G.V());
        this.s = s;

        for (int v = 0; v < G.V(); v++) {
            distTo[v] = Double.POSITIVE_INFINITY;
        }

        distTo[s] = 0.0;
        pq.insert(s, 0.0);
        while (!pq.isEmpty()) {
            relax(G, pq.delMin());
        }
    }

    private void relax(EdgeWeightedDigraph G, int v) {
        for (DirectedEdge e : G.adj(v)) {
            int w = e.to();
            if (distTo[w] > distTo[v] + e.weight()) {
                distTo[w] = distTo[v] + e.weight();
                edgeTo[w] = e;
                if (pq.contains(w))
                    pq.change(w, distTo[w]);
                else
                    pq.insert(w, distTo[w]);
            }
        }
    }

    public double distTo(int w) {
        return distTo[w];
    }

    public boolean hasPathTo(int w) {
        return distTo(w) < Double.POSITIVE_INFINITY;
    }

    public Iterable<DirectedEdge> pathTo(int v) {
        if (!hasPathTo(v))
            return null;

        Stack<DirectedEdge> path = new Stack<DirectedEdge>();
        for (DirectedEdge a = edgeTo[v]; a != null; a = edgeTo[a.from()]) {
            path.push(a);
        }
        return path;
    }

    // cmd /c --% java algs4.four.DijkstraSP ..\..\..\algs4-data\tinyEWG.txt
    public static void main(String[] args) {
        In in = new In(args[0]);
        EdgeWeightedDigraph ewdg = new EdgeWeightedDigraph(in);
        int s = Integer.parseInt(args[1]);
        DijkstraSP dijkstraSP = new DijkstraSP(ewdg, s);

        for (int t = 0; t < ewdg.V(); t++) {
            StdOut.print(s + " to " + t);
            StdOut.printf(" (%4.2f): ", dijkstraSP.distTo(t));
            if (dijkstraSP.hasPathTo(t)) {
                for (DirectedEdge e : dijkstraSP.pathTo(t)) {
                    StdOut.print(e + " ");
                }
            }
            StdOut.println();
        }
    }
}
8
16
4 5 0.35
4 7 0.37
5 7 0.28
0 7 0.16
1 5 0.32
0 4 0.38
2 3 0.17
1 7 0.19
0 2 0.26
1 2 0.36
1 3 0.29
2 7 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93

For the contents of the above tinyEWG.txt FIG specified, to calculate the points to the starting point 0 of the shortest path algorithm to perform the track:

  • Added to the priority queue 0 vertex, vertex 0 slack side as a starting point, from the point vertex 2 0 4 was added and priority queues, the edge 0_> 2 and 0-> 4 added to the tree;
  • Remove vertices from the priority queue 2, 2-> 7 added to the tree, will be added to the priority queue vertex 7;
  • 4, 4-> 5 is added to the priority queue remove vertices from the tree, but because 4-> 7 relaxation failure, failure of this edge, vertex 5 is added the priority queue;
  • 从优先队列删除顶点7,将7->3添加到树中,7->5松弛失败,将顶点3加入优先队列;
  • 从优先队列删除顶点5,将5->1添加到树中,5->7松弛失败,将顶点5加入优先队列;
  • 从优先队列删除顶点3,将3->6添加到树中,将顶点6加入优先队列;
  • 从优先队列删除顶点6,优先队列为空,执行完毕。

Guess you like

Origin www.cnblogs.com/zhixin9001/p/12129226.html