Dijstra algorithm of Java's top ten algorithms

Posted by 00tank on Fri, 07 Feb 2020 08:00:35 +0100

Existing scenario: shortest path problem
During the war, there were seven villages (A,B,C,D,E,F,G) in Shengli township. Now there are six oil differentials. Starting from point G, we need to send the mail to six villages (A,B,C,D,E,F,G) respectively. The subgrade of each village is represented by the boundary line. For example, the distance between A and B is 5km. How to calculate the shortest distance from village g to other villages?

1. Dijstra algorithm

Dijkstra algorithm is a typical shortest path algorithm, which is used to calculate the shortest path from one node to other nodes. Its main feature is to expand from the starting point to the outer layer (breadth first idea) until the end point

Dijstra algorithm process:
Set the starting point as v, vertex set V{v1,v2,v3 }The distance from v to the vertices in v constitutes the distance set Dis,Dis{d1,d2,d3 }, Dis set records the distance from v to each vertex in the graph (to itself can be regarded as 0, and the distance from v to vi corresponds to di)
(1) Select the di with the lowest value from Dis, move out Dis set, and move out the corresponding vertex vi in V set. At this time, V to vi is the shortest path
(2) Update the Dis set according to the following rules: compare the distance value between V and the vertex in V set, and keep the smaller one with the distance value between V and the vertex in V set through vi (at the same time, update the precursor node of the vertex to vi, indicating that it is achieved through vi)
(3) Repeat the above two steps to know that the shortest path vertex is the target vertex

Next, the blogger prepared a picture for easy understanding

Code implementation:

package com.self.tenAlgorithm;


import java.util.Arrays;

public class DijkstraAlgorithm {
    private static final int N = 65535;
    public static void main(String[] args) {
        char[] vertex = {'A','B','C','D','E','F','G'};
        int[][] matrix = new int[vertex.length][vertex.length];
        matrix[0] = new int[]{N,5,7,N,N,N,2};
        matrix[1] = new int[]{5,N,N,9,N,N,3};
        matrix[2] = new int[]{7,N,N,N,8,N,N};
        matrix[3] = new int[]{N,9,N,N,N,4,N};
        matrix[4] = new int[]{N,N,8,N,N,5,4};
        matrix[5] = new int[]{N,N,N,4,5,N,6};
        matrix[6] = new int[]{2,3,N,N,4,6,N};
        Graph graph = new Graph(vertex, matrix);
        graph.showGraph();

        graph.djs(2);
        graph.showDJS();
    }
}
class Graph{
    private char[] vertex; //vertex array
    private int[][] matrix;  //adjacency matrix
    private VisitedVertex vv;  //Indicates that the vertex set has been accessed
    public Graph(char[] vertex, int[][] matrix) {
        this.vertex = vertex;
        this.matrix = matrix;
    }
    //Display map
    public void showGraph(){
        for (int[] link : matrix) {
            System.out.println(Arrays.toString(link));
        }
    }

    /**
     * Function: Dijstra algorithm implementation
     * @param index Subscript corresponding to starting vertex
     */
    public void djs(int index){
        vv = new VisitedVertex(vertex.length, index);
        update(index);
        for (int i = 0; i < vertex.length; i++) {
            index = vv.updateArr();  //Select and return to a new access vertex
            update(index);
        }
    }

    /**
     * Function: update the distance from index subscript vertex to surrounding vertex and the precursor node of surrounding vertex
     * @param index
     */
    private void update(int index){
        int len = 0;  //len meaning: sum of distance from starting vertex to index vertex + distance from index vertex to j vertex
        //According to the matrix[index] row traversing our adjacency matrix
        for (int i = 0; i < matrix[index].length; i++) {
            len = vv.getDis(index) + matrix[index][i];
            //If i vertex has not been visited and len is less than the distance from the starting vertex to j vertex, it needs to be updated
            if(!vv.whetherVisited(i) && len < vv.getDis(i)){
                vv.updatePre(i,index);  //Update i vertex to index vertex
                vv.updateDis(i,len);  //Update distance from starting vertex to j vertex
            }
        }
    }

    /**
     * Show final results
     */
    public void showDJS(){
        vv.show();
    }
}
//Vertex collection accessed
class VisitedVertex{
    //Record whether each vertex has been visited or not 1 indicates that it has been visited 0 indicates that it has not been visited and will be updated dynamically
    public int[] already_arr;
    //The corresponding value of each subscript is the subscript of the previous vertex, which will be updated dynamically
    public int[] pre_visited;
    //Record the distance from the starting vertex to all other vertices. For example, if G is the starting vertex, the distance from G to other vertices will be recorded and updated dynamically. The shortest distance will be stored in dis
    public int[] dis;

    /**  Construction method
     * @param length  Represents the number of vertices
     * @param index The subscript corresponding to the starting vertex, such as G vertex, is 6
     */
    public VisitedVertex(int length,int index) {
        this.already_arr = new int[length];
        this.pre_visited = new int[length];
        this.dis = new int[length];
        //Initialize array
        Arrays.fill(dis,65535);
        this.already_arr[index] = 1;
        this.dis[index] = 0;  //Set the access distance of the starting vertex to 0
    }

    /**
     * @Function: judge whether index has been accessed
     * @param index
     * @return Return true if accessed, otherwise access false
     */
    public boolean whetherVisited(int index){
        return already_arr[index] == 1;
    }

    /**
     * Function: update the distance from the starting vertex to the index vertex
     * @param index
     * @param len
     */
    public void updateDis(int index,int len){
        dis[index] = len;
    }

    /**
     * Function: update pre to index
     * @param pre
     * @param index
     */
    public void updatePre(int pre,int index){
        pre_visited[pre] = index;
    }

    /**
     * Function: return the distance from the starting vertex to the index vertex
     * @param index
     * @return
     */
    public int getDis(int index){
        return dis[index];
    }

    /**Function: continue to select and return to the new vertex. For example, after the completion of G here, point A is used as the new access vertex (note that it is not the starting vertex)
     * @return
     */
    public int updateArr(){
        int min = 65535,index = 0;
        for (int i = 0; i < already_arr.length; i++) {
            if(already_arr[i] == 0 && dis[i] < min){
                min = dis[i];
                index = i;
            }
        }
        //Update index vertex accessed
        already_arr[index] = 1;
        return index;
    }

    /**
     * Function: display the final result and output the situation of three arrays
     */
    public void show(){
        System.out.println("============");
        for (int i : already_arr) {
            System.out.print(i+" ");
        }
        System.out.println();
        for (int i : pre_visited) {
            System.out.print(i+" ");
        }
        System.out.println();
        for (int i : dis) {
            System.out.print(i+" ");
        }
        System.out.println();
        //For the convenience of looking at the shortest distance at the end
        char[] vertex = {'A','B','C','D','E','F','G'};
        int count = 0;
        for (int i : dis) {
            if(i != 65535){
                System.out.print(vertex[count] + "("+i+")");
            }else{
                System.out.println("N");
            }
            count++;
        }
        System.out.println();
    }
}

The code is complex, so the blogger made detailed comments in the code
Operation result:

[65535, 5, 7, 65535, 65535, 65535, 2]
[5, 65535, 65535, 9, 65535, 65535, 3]
[7, 65535, 65535, 65535, 8, 65535, 65535]
[65535, 9, 65535, 65535, 65535, 4, 65535]
[65535, 65535, 8, 65535, 65535, 5, 4]
[65535, 65535, 65535, 4, 5, 65535, 6]
[2, 3, 65535, 65535, 4, 6, 65535]
============
1 1 1 1 1 1 1 
2 0 0 5 2 4 0 
7 12 0 17 8 13 9 
A(7)B(12)C(0)D(17)E(8)F(13)G(9)

You can choose your own starting point for testing, and then manually compare to verify, welcome to leave a message, welcome to technical exchange

43 original articles published, praised 9, 2772 visitors
Private letter follow

Topics: Java less