2023 Mathematical Modeling National Competition: Using Dijkstra's Algorithm to Find the Shortest Path

After subscribing to the column, ideas and Matlab codes will be shared during the competition in September

Dijkstra's algorithm is a classic graph theory algorithm that can find the shortest path between two vertices in a graph. In this article, we will introduce the principle of Dijkstra's algorithm and its implementation, and implement a practical case of the shortest path through Matlab code.

The principle of Dijkstra algorithm

Dijkstra's algorithm is a greedy algorithm. Its basic idea is to start from the starting point, find the one with the shortest distance among its adjacent vertices in turn, and then continue to expand outward with the vertex as the center until the end point is found.

Dijkstra's algorithm is a labeling method, that is, to record a number for each vertex of the weighted graph, which is called the label of the vertex. The T label represents the upper bound of the shortest path length from the initial vertex to the punctuation point; the P label is the shortest path length from the initial vertex to the vertex. During the execution of the algorithm, we use an array dist[i] to represent the length of the shortest path from the starting point to the vertex i. At the same time, we use an array visited[i] to record which vertices have been visited.

The specific algorithm flow is as follows:

  1. Initialize the dist array and visited array. Set the dist value of the starting point to 0, set the dist value of the remaining vertices to infinity (indicating that it has not been visited), and initialize the visited array to false.

  2. Starting from the starting point, label its adjacent vertices and update their dist values. For vertices that have not been visited, if the distance from the starting point to the vertex is smaller than the existing dist value, update its dist value.

  3. Select an unvisited vertex with the smallest dist value as the current starting point. Mark the vertex as visited, indicating that it has been visited.

  4. Repeat steps 2 and 3 until the end point is found or all vertices have been visited.

The complexity of Dijkstra's algorithm is O(N^2), where N is the number of vertices. When N is relatively large, the efficiency of the algorithm may be relatively low, so data structures such as a heap can be used to optimize the execution efficiency of the algorithm.

Implementation of Dijkstra's Algorithm

We use Matlab to implement Dijkstra's algorithm, and demonstrate its use through a practical case.

First, we need to define an adjacency matrix to represent the graph. An adjacency matrix is ​​an N*N matrix where each element represents the distance between two vertices. If no edge connects the two vertices, the element is infinite.

For example, here is an example of an adjacency matrix:

0   2   4   1   inf
2   0   4   32  inf
1  inf  3   0   5
inf inf 2   5   0

In Matlab, we can use a two-dimensional array to represent the adjacency matrix. The specific implementation is as follows:
 

% 定义邻接矩阵
adj_matrix = [0 2 4 1 inf; 2 0 4 3 inf; 4 4 0 2 2; 1 3 2 0 5; inf inf 2 5 0];

Next, we can use Dijkstra's algorithm to find the shortest path from the start point to the end point. We can realize the algorithm as a Matlab function, the input parameters of this function are the numbers of the start point and the end point, and the output parameters are the shortest path length from the start point to the end point and the numbers of all vertices on the path.

function [dist, path] = dijkstra(adj_matrix, start, end)
% 计算邻接矩阵的大小
N = size(adj_matrix, 1);

% 初始化dist和visited数组
dist = inf(1, N);
visited = false(1, N);

% 将起点的dist值设置为0
dist(start) = 0;

% 计算起点到终点的最短路径
for i = 1:N
    % 找到未被访问的dist值最小的顶点
    [~, u] = min(dist .* ~visited);
    
    % 如果所有顶点都已被访问,则退出循环
    if dist(u) == inf
        break;
    end
    
    % 标记该顶点为已访问
    visited(u) = true;
    
    % 更新与该顶点相邻的顶点的dist值
    for v = 1:N
        if adj_matrix(u, v) ~= inf && ~visited(v)
            alt = dist(u) + adj_matrix(u, v);
            if alt < dist(v)
                dist(v) = alt;
                path(v) = u;
            end
        end
    end
end

% 构建最短路径的顶点编号序列
path = [end];
while path(1) ~= start
    path = [path(1) path(path(1))];
end

end

The implementation of this function is relatively simple. It is mainly a loop, each time finding the vertex with the smallest dist value that has not been visited, and then updating the dist value of the vertices adjacent to this vertex. Ultimately, the function returns the length of the shortest path from the start point to the end point and the numbers of all vertices on the path.

Practical case: Find the shortest path between two cities on the map

Now, we use the Dijkstra algorithm implemented above to solve a practical problem: finding the shortest path between two cities on the map.

Suppose we have a map with 5 cities and the distance between them as follows:

City A city ​​B city ​​C city ​​D City E
City A 0 2 4 1 inf
city ​​B 2 0 4 3 inf
city ​​C 4 4 0 2 2
city ​​D 1 inf 3 0 5
City E inf inf 2 5 0

Now, we want to go from city A to city E and find the shortest path between them.

We can use Dijkstra's algorithm mentioned above to solve this problem. For specific implementation, please refer to the code above. Here, we will not repeat it.

Assuming we use the above function to find the shortest path, the final output should look like this:

dist = 6
path = [1 4 3 5]

This means that the length of the shortest path from city A to city E is 6, and the vertices passed on the path are city A, city D, city C, and city E in turn.

Through this actual combat case, we can see the practical application of Dijkstra's algorithm. In practical problems, we can model the problem as a graph theory problem and use Dijkstra's algorithm to find the optimal solution.

Besides Dijkstra's algorithm, there are many other graph theory algorithms that can be used to solve the shortest path problem. For example, both the Bellman-Ford algorithm and the Floyd algorithm can find the shortest path between two vertices in a graph.

The Bellman-Ford algorithm is a dynamic programming algorithm that can handle the presence of negatively weighted edges in a graph. Unlike Dijkstra's algorithm, the Bellman-Ford algorithm can handle negative weight edges and can detect whether there are negative weight cycles in the graph. The time complexity of the Bellman-Ford algorithm is O(VE), where V is the number of vertices and E is the number of edges.

Floyd's algorithm is a dynamic programming algorithm that deals with the shortest paths between all vertices in a graph. The time complexity of Floyd's algorithm is O(V^3), where V is the number of vertices. Although the time complexity of Floyd's algorithm is higher than that of Dijkstra's algorithm and Bellman-Ford's algorithm, it has a wider range of applications and can handle the shortest path between any two vertices.

Besides graph theory algorithms, there are many other mathematical modeling methods that can be used to solve the shortest path problem. For example, methods such as linear programming, integer programming, and network flows can all be used to solve optimization problems.

In conclusion, the shortest path problem is a classic mathematical modeling problem, which is widely used in practical applications. Whether it is Dijkstra algorithm, Bellman-Ford algorithm or Floyd algorithm, they can all be used to solve the shortest path problem, and the appropriate algorithm can be selected according to the different characteristics of the actual problem. When solving the shortest path problem, we also need to model according to the actual situation, and use appropriate tools to realize the modeling process.

おすすめ

転載: blog.csdn.net/m0_68036862/article/details/130478915