Graph theory algorithm--Dijkstra

Algorithms are an important topic when it comes to computer science because they help solve many problems. And some algorithms are amazing with their high efficiency and amazing performance. Let's share the amazing and efficient algorithm you think!

1. What amazing algorithms have you used in your work and study? (Including but not limited to algorithms in data science, computer vision, natural language processing, etc.)

Dijkstra's Algorithm: A greedy algorithm for finding the single-source shortest path in a graph.

Second, please introduce the above algorithm and give a simple demonstration!

1. What is Dijkstra?

  Dijkstra's algorithm is a greedy algorithm for finding the single-source shortest path in a graph. It determines the next node to be processed by continuously expanding the node closest to the current source until the target node is found.
For example, as shown in the figure below, if the path and length are known, then the Dijkstra algorithm can be used to calculate the shortest distance from Xining to all nodes in the figure.
Please add a picture description

2. Dijkstra algorithm process

  The process of Dijkstra algorithm is as follows:

Initialization: Suppose there are n vertices, and each vertex has an array dist representing the distance to the source point. Initialize the dist of all vertices to infinity and the distance from the source to 0.

Select the undetermined node u that is currently closest to the source.

Update the dist value of all nodes adjacent to u, or update their dist value if a shorter path is found.

Repeat steps 2 and 3 until the target node is found or all nodes are processed.

Returns the dist array as the result, where dist[i] represents the shortest distance from the source to vertex i.


Illustration :


insert image description here
  • Repeat the second operation until all points are determined.
    insert image description here

  • The time complexity of Dijkstra's algorithm is O(n^2), which is illustrated by a graph:

      Suppose there is the following undirected graph, where the edge weight of each edge is a positive integer.

    A-B-C-D-E
    |         |
    F         G
    
    

      We want to calculate the shortest path length from vertex A to vertex E. This can be achieved using Dijkstra's algorithm.
    First, initialize the dist value of all vertices to infinity and the distance from the source to 0. Then select the undetermined node u that is currently closest to the source point. In this example, vertex A is selected as the currently processed node.

         u       v       dist    A->E
    A       B       1      0   / \     / \
    A       C       2      1   |   |     |
    A       D       3      2   |   |     |
    A       E       4      3   |   |     |
    B       C       2      1  / \    / \     |
    B       D       3      2  / \    / \     |
    B       E       4      3  / \    / \     |
    C       D       3      2     |   |     |
    C       E       4      3     |   |     |
    D       E       4      3     |   |     |
    
    

      Next, we need to update the dist value of all nodes adjacent to u, or update their dist value if a shorter path is found. In this example, we need to update the dist value of vertices B, C and D. Specifically, we need to compare the edge weights of vertices B, C, and D with vertex A, and update their dist values ​​if a shorter path is found. The final result is as follows:

         u       v       dist    A->E
    A       B       1      0   / \     / \
    A       C       2      1   |   |     |
    A       D       3      2   |   |     |
    A       E       4      3   |   |     |
    B       C       2      1  / \    / \     |
    B       D       3      2  / \    / \     | // 将B的dist更新为1,因为它与A相连的边的边权更小
    B       E       4      3  / \    / \     | // 将B的dist更新为1,因为它与A相连的边的边权更小
    C       D       3      2     |   |     | // 将C的dist更新为2,因为它与A相连的边的边权更小
    C       E       4      3     |   |     | // 将C的dist更新为2,因为它与A相连的边的边权更小
    D       E       4      3     |   |     | // 将D的dist更新为3,因为它与A相连的边的边权更小
    
    

      Finally, we get a dist array of length 4, representing the length of the shortest path from source A to vertex E.


    3. Algorithm implementation:

    package 图论;
    
    import java.util.ArrayDeque;
    import java.util.Comparator;
    import java.util.PriorityQueue;
    import java.util.Queue;
    import java.util.Scanner;
    
    public class dijkstra {
          
          
    	static class node
    	{
          
          
    		int x; //节点编号
    		int lenth;//长度
    		public node(int x,int lenth) {
          
          
    			this.x=x;
    			this.lenth=lenth;
    		}
    	}
    
    	public static void main(String[] args) {
          
          
    		 
    		int[][] map = new int[6][6];//记录权值,顺便记录链接情况,可以考虑附加邻接表
    		initmap(map);//初始化
    		boolean bool[]=new boolean[6];//判断是否已经确定
    		int len[]=new int[6];//长度
    		for(int i=0;i<6;i++)
    		{
          
          
    			len[i]=Integer.MAX_VALUE;
    		}
    		Queue<node>q1=new PriorityQueue<node>(com);
    		len[0]=0;//从0这个点开始
    		q1.add(new node(0, 0));
    		int count=0;//计算执行了几次dijkstra
    		while (!q1.isEmpty()) {
          
          
    			node t1=q1.poll();
    			int index=t1.x;//节点编号
    			int length=t1.lenth;//节点当前点距离
    			bool[index]=true;//抛出的点确定
    			count++;//其实执行了6次就可以确定就不需要继续执行了  这句可有可无,有了减少计算次数
    			for(int i=0;i<map[index].length;i++)
    			{
          
          
    				if(map[index][i]>0&&!bool[i])
    				{
          
          
    					node node=new node(i, length+map[index][i]);
    					if(len[i]>node.lenth)//需要更新节点的时候更新节点并加入队列
    					{
          
          
    						len[i]=node.lenth;
    						q1.add(node);
    					}
    				}
    			}
    		}		
    		for(int i=0;i<6;i++)
    		{
          
          
    			System.out.println(len[i]);
    		}
    	}
    	static Comparator<node>com=new Comparator<node>() {
          
          
    
    		public int compare(node o1, node o2) {
          
          
    			return o1.lenth-o2.lenth;
    		}
    	};
    
    	private static void initmap(int[][] map) {
          
          
    		map[0][1]=2;map[0][2]=3;map[0][3]=6;
    		map[1][0]=2;map[1][4]=4;map[1][5]=6;
    		map[2][0]=3;map[2][3]=2;
    		map[3][0]=6;map[3][2]=2;map[3][4]=1;map[3][5]=3;
    		map[4][1]=4;map[4][3]=1;
    		map[5][1]=6;map[5][3]=3;	
    	}
    }
    
    
    

    Please add a picture description


    3. How to optimize the algorithm to get better results? From what ideas do you usually optimize?

    1. Advantages and disadvantages of the algorithm:

      Dijkstra's algorithm is suitable for the following scenarios:

    • Find the shortest path between two points.
    • Shortest paths need to be computed in graphs with negative or floating-point edge weights.
    • The number of vertices in the graph is relatively small, which can bear the time complexity of O(n^2).
    • Edges with negative weights do not need to be considered.
    • The source and destination points are fixed, and only the shortest path between them needs to be calculated.

      Dijkstra's algorithm is not suitable for the following scenarios:

    • The number of vertices in the graph is very large, and the calculation time will be very long.
    • Edge weights may be negative or floating point numbers, which need to be handled using other algorithms.
    • To consider edges with negative weights, you can use the Bellman-Ford algorithm or the Edmonds-Karp algorithm.
    • If you need to find the shortest path from multiple starting points to a fixed point at the same time, you can use the Dinic algorithm.

    2. Algorithm optimization:

    1. Use the minimum heap to speed up the process of selecting the undetermined node that is currently closest to the source point, and the heap can be adjusted to the maximum heap to ensure the minimum heap property.
    2. For graphs with negative edge weights or floating-point edge weights, other algorithms can be used, such as the Bellman-Ford algorithm or the Edmonds-Karp algorithm.
    3. For dense graphs or graphs with a limited number of vertices, variants of Dijkstra's algorithm such as the SPFA algorithm or the A* algorithm can be used.
    4. Use parallelization techniques to speed up the execution of Dijkstra's algorithm, such as using multithreading or distributed computing techniques.
    5. In practical applications, the appropriate optimization method can be selected according to the specific situation, such as combining multiple algorithms for hybrid optimization.

    4. What details need to be paid attention to in the process of using the algorithm in order to maximize its effectiveness?

    Attention to details :
      The following are some details that need to be paid attention to when using Dijkstra's algorithm in order to maximize its effectiveness:

    1. Determine the source and target points: Before using Dijkstra's algorithm, the source and target points must be determined. The source point represents the starting point of the shortest path to be calculated, and the target point represents the end point of the shortest path to be calculated.

    2. Choose an appropriate data structure: Dijkstra's algorithm needs to use a minimum heap to store the information of undetermined nodes. Therefore, in practical applications, it is necessary to select an appropriate data structure to store vertex information. Commonly used data structures include arrays, linked lists, binary heaps, etc.

    3. Initialize the dist array: Before using the Dijkstra algorithm, the dist array needs to be initialized. For each vertex i in an undirected or directed graph, initialize dist[i] to infinity (indicating that the distance from the vertex to the source is infinite).

    4. Update the dist array: When updating the dist array, it is necessary to compare the dist values ​​of all nodes adjacent to the current node, and update the dist value of the undetermined node closest to the source point. When updating the dist value, you need to use min-heap to ensure the correct order.

    5. Dealing with negative edge weights or floating-point edge weights: If there are negative edge weights or floating-point edge weights, other algorithms need to be used to deal with them. For example, the Bellman-Ford algorithm or the Edmonds-Karp algorithm can be used to handle graphs with negative edge weights or floating-point edge weights.

    6. Avoid repeated traversal: In the process of updating the dist array, it is necessary to avoid repeated traversal of the same vertex. In order to avoid this situation, a hash table can be used to record the vertices that have been traversed.

    7. Consider border cases: When using Dijkstra's algorithm, you need to consider border cases. For example, when the dist values ​​of all vertices are infinite, it means that there is no path from the source point to the target point; when the dist values ​​of all vertices are equal, it means that there are multiple paths from the source point to the target point.



    Partial reference:
    Dijkstra algorithm in detail (single-source shortest path algorithm)

Guess you like

Origin blog.csdn.net/wodejiaAA/article/details/131007589