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

简介: Java实现最短路径算法

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

目录
相关文章
|
存储 运维 监控
基于 C# 语言的 Dijkstra 算法在局域网内监控软件件中的优化与实现研究
本文针对局域网监控系统中传统Dijkstra算法的性能瓶颈,提出了一种基于优先队列和邻接表优化的改进方案。通过重构数据结构与计算流程,将时间复杂度从O(V²)降至O((V+E)logV),显著提升大规模网络环境下的计算效率与资源利用率。实验表明,优化后算法在包含1000节点、5000链路的网络中,计算时间缩短37.2%,内存占用减少21.5%。该算法适用于网络拓扑发现、异常流量检测、故障定位及负载均衡优化等场景,为智能化局域网监控提供了有效支持。
400 5
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
2977 35
|
存储 算法 搜索推荐
《数据之美》:Java数据结构与算法精要
本系列深入探讨数据结构与算法的核心原理及Java实现,涵盖线性与非线性结构、常用算法分类、复杂度分析及集合框架应用,助你提升程序效率,掌握编程底层逻辑。
|
机器学习/深度学习 编解码 算法
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
850 4
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
算法 机器人 定位技术
基于机器视觉和Dijkstra算法的平面建筑群地图路线规划matlab仿真
本程序基于机器视觉与Dijkstra算法,实现平面建筑群地图的路径规划。通过MATLAB 2022A读取地图图像,识别障碍物并进行路径搜索,支持鼠标选择起点与终点,最终显示最优路径及长度,适用于智能导航与机器人路径规划场景。
|
机器学习/深度学习 算法 Java
Java实现林火蔓延路径算法
记录正在进行的森林防火项目中林火蔓延功能,本篇文章可以较好的实现森林防火蔓延,但还存在很多不足,如:很多参数只能使用默认值,所以蔓延范围仅供参考。(如果底层设备获取的数据充足,那当我没说)。注:因林火蔓延涉及因素太多,如静可燃物载量、矿质阻尼系数等存在估值,所以得出的结果仅供参考。
701 5
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
821 1
|
运维 监控 算法
基于 Java 滑动窗口算法的局域网内部监控软件流量异常检测技术研究
本文探讨了滑动窗口算法在局域网流量监控中的应用,分析其在实时性、资源控制和多维分析等方面的优势,并提出优化策略,结合Java编程实现高效流量异常检测。
575 0
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
719 0

热门文章

最新文章