Implement Dijkstra's Shortest Path Algorithm with Adjacency List and Min Heap (PriorityQueue)

  • Algorithm Features:

    Dijkstra's algorithm uses breadth-first search to solve the single-source shortest path problem of a weighted directed or undirected graph, and the algorithm finally obtains a shortest path tree. This algorithm is often used in routing algorithms or as a submodule of other graph algorithms.

  • algorithm idea

    Dijkstra's algorithm adopts a greedy strategy, declaring an array dis to save the shortest distance from the source point to each vertex and a collection of vertices that have found the shortest path: T, initially, the path weight of the origin s is assigned is 0 (dis[s] = 0). If there is a directly reachable edge (s, m) for vertex s, set dis[m] to w(s, m), and set the path lengths of all other (s unreachable) vertices to infinity. Initially, the set T has only vertex s. 
    Then, select the minimum value from the dis array, then the value is the shortest path from the source point s to the vertex corresponding to this value, and add this point to T, OK, then a vertex is completed, 
    and then we need to look at the new Whether the added vertices can reach other vertices and see if the path length to reach other points through this vertex is shorter than the source point directly, if so, then replace the value of these vertices in dis. 
    Then, find the minimum value from dis, and repeat the above actions until T contains all the vertices of the graph.

      For those who are not familiar with the adjacency list, you can see the following link, the adjacency list

      Simply paste the code directly below

       

 
 
import java.util.Comparator;
import java.util.PriorityQueue;

/*
     D algorithm using adjacency list and priority queue (small root heap)
    Vertices
 start at 1 */
 public class Dijkstra {
     int n ; // number of points
 int m ; // number of edges
     // adjacency list
 private int [] U ; / /The starting point of the ith edge
 private int [] V ; //The end point of the ith edge
 private int [] W ; //The length of the ith edge
 private int [] first ; //The starting point is the first line of i Edge
 private int [] next ; //The starting point is the next edge of i, -1 means there is no
 class distanceTo {
         int                            of ;
        int distance ;
        distanceTo(int des, int distance) {
            this.des = des;
            this.distance = distance;
        }
    }
    Dijkstra( int n, int m, int [][] edges) {   // number of points, number of edges, input array (start, end, length)
 if (m != edges. length ) throw new IllegalArgumentException();
         U = new int [m+ 1 ];
         V = new int [m+ 1 ];
         W = new int [m+ 1 ];
         first = new int [n+ 1 ];
         next = new int [n+ 1 ];
                for (int i = 0; i < edges.length; ++i) { //读入每一条边
if (edges[i].length != 3) throw new IllegalArgumentException();
            U[i+1] = edges[i][0];
            V[i+1] = edges[i][1];
            W[i+1] = edges[i][2];            
        }
        for (int i = 1; i < first.length; ++i) {
            first[i] = -1;
        }
        for (int i = 1; i <= m; ++i) {
            next[i] = first[U[i]]; //邻接表的关键
first[U[i]] = i;            
        }
    }
    public int[] findNearestPath(int s) { //源点i到其他点的最短路
        PriorityQueue<distanceTo> updatingDistance = new PriorityQueue<>(new Comparator<distanceTo>() {
            @Override
public int compare(distanceTo o1, distanceTo o2) {
                return o1.distance - o2.distance;            
            }
        });
        int[] distance = new int[n+1];
        for (int i = 1; i < first.length; ++i) {
            if (i == s) continue;
            distance[i] = Integer.MAX_VALUE;
        }
        int[] path = new int[n+1];

        int i = first [s];
         if (i == - 1 ) return path;
         while (i != - 1 ) { //traverse all edges where s is the source
             distance[ V [i]] = W [i] ;
            updatingDistance.offer(new distanceTo(V[i], W[i]));
            i = next[i];
        }
        for (i = 1 ; i <= n ; i++) { //because the adjacency list does not store inaccessible points
 if (distance[i] == Integer. MAX_VALUE ) updatingDistance.offer( new distanceTo(i,distance[i ]));            
        }
        for (i = 1 ; i <= n - 1 ; ++i) { //The D algorithm needs to loop n-1 times
 int t = first [updatingDistance.poll(). des ]; //The current distance to point w is the shortest
 while (t != - 1 ) {
                 if (distance[ V [i]] > distance[ U [i]] + W [i]) {            
            
                    distance[V[i]] = distance[U[i]] + W[i];
                    updatingDistance.offer( new distanceTo( V [i],distance[ V [i]])); //No need to delete the overwritten ones, because they will be listed later
                     path[ V [i]] = U [i ];
                }
            }
        }
        return path;
    }
}
The path array returned at last records the shortest path. For example, path[5] = 3, indicating that the shortest path to point 5 is the previous step at point 3, until a certain value is equal to the starting point, that is, the complete path is obtained.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324851045&siteId=291194637