数据结构(12)Dijkstra算法JAVA版:图的最短路径问题

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: 12.1.概述12.1.1.无权图的最短路径无权图的最短路径,即最少步数,使用BFS+贪心算法来求解最短路径,比较好实现,此处不做展开讨论。

12.1.概述

12.1.1.无权图的最短路径

无权图的最短路径,即最少步数,使用BFS+贪心算法来求解最短路径,比较好实现,此处不做展开讨论。

cb5502e3ea764783ad658c7759691e4f.png

12.1.2.带权图的最短路径

有权图的最短路径,不考虑权重为负数的情况,因为权重为负数的情况极有可能出现负值圈,在这个圈子上形成环路,最短路径是无限兜圈,趋于负无穷。

所以此处我们只考虑权重不为负数的带权图的最短路径求解问题。带权图的最短路径求解问题主要求两种最短路径:

  • 单源最短路径,某个点到全图各点之间的最短路径。
  • 多源最短路径,遍历全图的最短路径。

单源最短路径Dijkstra算法求解,多源最短路径用Floyd算法求解。

1.单源最短路径

单源最短路径用Dijkstra算法求解,Dijkstra算法其本质是个贪心算法。整个过程就是选择局部最优解,组成最后的解。

以下展示一个Dijkstra求解v1的单源最短路径的过程:

d3c666b361f74b538f71cafe30e5f7b4.png

记录两个值:

distance,到某个结点的最短距离,初始化值为无穷大,表示暂时未记录。

route,全局最短路径,初始化值为-1,表示暂时未记录。

下标 1 2 3 4 5 6 7
distance 无穷大 无穷大 无穷大 无穷大 无穷大 无穷大 无穷大
route -1 -1 -1 -1 -1 -1 -1


v1开始,刷新distance和route的值:

v1—>v1,distance为0

v1—>v2,distance为2<∞,将2刷新为v1—>v2的最短距离,将1(指代v1)刷新为最短路径。

v4同理……

下标 1 2 3 4 5 6 7
distance 0 2 无穷大 1 无穷大 无穷大 无穷大
route -1 1 -1 1 -1 -1 -1

扫描distance表发现distance最小的v4,于是将v4上得到的数据刷新进distance和route:

下标 1 2 3 4 5 6 7
distance 0 2 3 1 3 9 5
route -1 1 4 1 4 4 4

一直重复上面步骤,直到图里所有结点都被遍历一次,会得到如下结果:

下标 1 2 3 4 5 6 7
distance 0 2 3 1 3 6 5
route -1 1 4 1 4 7 4

distance记录的是v1到每个结点的最短路径,route里面记录的最大值是全局遍历一遍的最短路径。

2.多源最短路径

多源最短路径用floyd算法求解,多源最短路径不能只关注于当前最优解,还要关注全局最优解,求解此类问题一般使用动态规划,floyd算法就是个求解多源最短路径的经典动态规划算法。本文主要论述Dijkstra算法,floyd算法暂时不展开。

12.2.代码实现

以遍历如下无向图为例(为什么不遍历上面的例子喃?因为代码是很久前写的了。上面的例子是写文的时候新写的,偷个懒不想改代码了~嘿嘿):

b978f463464f43d9ad937d6112a796f2.png

public class Dijkstra {
    static int[][] graph;
    static int[] dist;
    static int[] path=new int[7];
    static boolean[] isUsed=new boolean[7];
    static {
        graph=new int[][]{
                {0,1,4,3,0,0,0},
                {1,0,3,0,0,0,0},
                {4,3,0,2,1,5,0},
                {3,0,2,0,2,0,0},
                {0,0,1,2,0,0,0},
                {0,0,5,0,0,0,2},
                {0,0,0,0,0,2,0}
        };
        dist=new int[]{Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE};
    }
    public static void dijkstra(){
        while(true){
            //判断节点是否已经全部纳入
            if(isOver()){
                break;
            }
            //寻找未纳入的dist最小节点
            int i=findMin();
            //设置为已遍历状态
            isUsed[i]=true;
            //遍历该节点邻接节点
            for (int j=0;j<graph[i].length;j++) {
                if(graph[i][j]!=0&&isUsed[j]==false){
                    //更新dist、path
                    flashDistAndPath(i,j);
                }
            }
        }
    }
    public static int findMin(){
        int min=Integer.MAX_VALUE;
        int index=-1;
        for(int i=0;i<dist.length;i++){
            if(min>dist[i]&&isUsed[i]==false){
                min=dist[i];
                index=i;
            }
        }
        return index;
    }
    //之前的dist值一定是之前该节点到根节点的最短路径开销
    public static void flashDistAndPath(int i,int j){
            if(isUsed[j]==false) {
                if (graph[i][j] + dist[i] < dist[j]) {
                    dist[j] = graph[i][j] + dist[i];
                    path[j] = j;
                }
            }
    }
    public static boolean isOver(){
        int trues=0;
        for (boolean isused:isUsed) {
            if(isused==true){
                trues++;
            }
        }
        if(trues==dist.length){
            return true;
        }
        return false;
    }
    public static void main(String[] args) {
        isUsed[0]=true;
        dist[1]=1;
        dist[2]=4;
        dist[3]=3;
        path[1]=0;
        path[2]=0;
        path[3]=0;
        dijkstra();
        for (int i=0;i<dist.length;i++){
            System.out.println(dist[i]);
        }
    }
}


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

热门文章

最新文章