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

举报
赵KK日常技术记录 发表于 2023/06/24 20:42:31 2023/06/24
1k+ 0 0
【摘要】 Java实现最短路径算法(Dijkstra算法):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...

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

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算法):

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代码实现:

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代码实现:

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代码实现:

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代码实现:

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列表,其中包含从起点到每个节点的最短距离。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。