java和python实现最短路径算法

2023-03-18 12:09:17 浏览数 (2)

Java实现最短路径算法(Dijkstra算法):

代码语言:java复制
import java.util.*;

public class Dijkstra {

    public static void main(String[] args) {
        int[][] graph = {{0, 2, 4, 0, 0, 0},
                         {2, 0, 3, 5, 0, 0},
                         {4, 3, 0, 1, 7, 0},
                         {0, 5, 1, 0, 4, 2},
                         {0, 0, 7, 4, 0, 6},
                         {0, 0, 0, 2, 6, 0}};
        int startNode = 0;
        int[] dist = dijkstra(graph, startNode);
        System.out.println(Arrays.toString(dist));
    }

    public static int[] dijkstra(int[][] graph, int startNode) {
        int n = graph.length;
        int[] dist = new int[n];
        boolean[] visited = new boolean[n];
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[startNode] = 0;
        for (int i = 0; i < n - 1; i  ) {
            int u = findMinDist(dist, visited);
            visited[u] = true;
            for (int v = 0; v < n; v  ) {
                if (!visited[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u]   graph[u][v] < dist[v]) {
                    dist[v] = dist[u]   graph[u][v];
                }
            }
        }
        return dist;
    }

    private static int findMinDist(int[] dist, boolean[] visited) {
        int minDist = Integer.MAX_VALUE;
        int minNode = -1;
        for (int i = 0; i < dist.length; i  ) {
            if (!visited[i] && dist[i] < minDist) {
                minDist = dist[i];
                minNode = i;
            }
        }
        return minNode;
    }
}

Python实现最短路径算法(Dijkstra算法):

代码语言:python代码运行次数:0复制
import heapq

def dijkstra(graph, startNode):
    n = len(graph)
    dist = [float('inf')] * n
    visited = [False] * n
    dist[startNode] = 0
    heap = [(0, startNode)]
    while heap:
        (d, u) = heapq.heappop(heap)
        if visited[u]: continue
        visited[u] = True
        for v, w in graph[u]:
            if not visited[v] and dist[u]   w < dist[v]:
                dist[v] = dist[u]   w
                heapq.heappush(heap, (dist[v], v))
    return dist

graph = [[(1, 2), (2, 4)],
         [(0, 2), (2, 3), (3, 5)],
         [(0, 4), (1, 3), (3, 1), (4, 7)],
         [(1, 5), (2, 1), (4, 4), (5, 2)],
         [(2, 7), (3, 4), (5, 6)],
         [(3, 2), (4, 6)]]
startNode = 0
dist = dijkstra(graph, startNode)
print(dist)
  1. Floyd算法

Floyd算法是一种动态规划算法,用于寻找所有节点对之间的最短路径。该算法通过对每对节点之间的距离进行递推,来计算出所有节点之间的最短路径。

Java代码实现:

代码语言:java复制
public static int[][] floyd(int[][] graph) {
    int n = graph.length;
    int[][] dist = new int[n][n];
    for (int i = 0; i < n; i  ) {
        for (int j = 0; j < n; j  ) {
            dist[i][j] = graph[i][j];
        }
    }
    for (int k = 0; k < n; k  ) {
        for (int i = 0; i < n; i  ) {
            for (int j = 0; j < n; j  ) {
                if (dist[i][k] != Integer.MAX_VALUE && dist[k][j] != Integer.MAX_VALUE && dist[i][k]   dist[k][j] < dist[i][j]) {
                    dist[i][j] = dist[i][k]   dist[k][j];
                }
            }
        }
    }
    return dist;
}

Python代码实现:

代码语言:python代码运行次数:0复制
import sys

def floyd(graph):
    n = len(graph)
    dist = [[0] * n for i in range(n)]
    for i in range(n):
        for j in range(n):
            dist[i][j] = graph[i][j]
    for k in range(n):
        for i in range(n):
            for j in range(n):
                if dist[i][k] != sys.maxsize and dist[k][j] != sys.maxsize and dist[i][k]   dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k]   dist[k][j]
    return dist
  1. Bellman-Ford算法

Bellman-Ford算法是一种动态规划算法,用于解决带有负权边的最短路径问题。该算法通过对每条边进行逐步松弛操作,来计算出从起点到其他节点的最短路径。

Java代码实现:

代码语言:java复制
public static int[] bellmanFord(int[][] graph, int start) {
    int n = graph.length;
    int[] dist = new int[n];
    Arrays.fill(dist, Integer.MAX_VALUE);
    dist[start] = 0;
    
    for (int i = 0; i < n-1; i  ) {
        for (int u = 0; u < n; u  ) {
            for (int v = 0; v < n; v  ) {
                if (graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u]   graph[u][v] < dist[v]) {
                    dist[v] = dist[u]   graph[u][v];
                }
            }
        }
    }
    return dist;
}

Python代码实现:

代码语言:python代码运行次数:0复制
import sys

def bellman_ford(graph, start):
    n = len(graph)
    dist = [sys.maxsize] * n
    dist[start] = 0
    
    for i in range(n-1):
        for u in range(n):
            for v in range(n):
                if graph[u][v] != 0 and dist[u] != sys.maxsize and dist[u]   graph[u][v] < dist[v]:
                    dist[v] = dist[u]   graph[u][v]
    return dist

分析:

  1. Dijkstra算法和Floyd算法适用于无负权边的最短路径问题,而Bellman-Ford算法适用于带有负权边的最短路径问题。
  2. Dijkstra算法的时间复杂度为O(V^2),其中V为节点数,但是可以通过使用优先队列将时间复杂度优化至O(E VlogV),其中E为边数。Floyd算法的时间复杂度为O(V^3),空间复杂度为O(V^2)。Bellman-Ford算法的时间复杂度为O(VE),其中V为节点数,E为边数。
  3. 在实际应用中,通常情况下使用Dijkstra算法和Floyd算法,因为它们的时间复杂度较低,而且适用范围广。但是,如果存在负权边,则必须使用Bellman-Ford算法。

Java和Python都可以很方便地实现最短路径算法,其中Dijkstra算法是一种基于贪心思想的算法,可以在有向或无向图中找到单源最短路径。Java和Python都有很好的支持数据结构的库,如Java中的Arrays和PriorityQueue,Python中的heapq和list等,可以方便地实现Dijkstra算法。

在Java中,我们使用了一个数组dist来记录从起点到每个节点的最短距离,使用一个布尔数组visited来记录每个节点是否已经被访问过。在每次迭代中,我们选择未访问并且距离起点最近的节点,并将其标记为已访问。然后,我们遍历从该节点出发的所有边,如果该边的目标节点未被访问并且通过该边到达目标节点的距离比已知的最短距离更小,则更新该节点的最短距离。最后,我们返回dist数组,其中包含从起点到每个节点的最短距离。

在Python中,我们使用了一个列表dist来记录从起点到每个节点的最短距离,使用一个布尔列表visited来记录每个节点是否已经被访问过。我们还使用了Python的heapq模块来实现优先队列。在每次迭代中,我们选择未访问并且距离起点最近的节点,并将其标记为已访问。然后,我们遍历从该节点出发的所有边,如果该边的目标节点未被访问并且通过该边到达目标节点的距离比已知的最短距离更小,则更新该节点的最短距离。最后,我们返回dist列表,其中包含从起点到每个节点的最短距离。

0 人点赞