图论14-最短路径-Dijkstra算法+Bellman-Ford算法+Floyed算法

文章目录

  • 0 代码仓库
  • 1 Dijkstra算法
  • 2 Dijkstra算法的实现
    • 2.1 设置距离数组
    • 2.2 找到当前路径的最小值 curdis,及对应的该顶点cur
    • 2.3 更新权重
    • 2.4 其他接口
      • 2.4.1 判断某个顶点的连通性
      • 2.4.2 求源点s到某个顶点的最短路径
  • 3使用优先队列优化-Dijkstra算法
    • 3.1 设计内部类node
    • 3.2 入队
    • 3.3 记录路径
    • 3.4 整体
  • 4 Bellman-Ford算法
    • 4.1 松弛操作
    • 4.2 负权环
    • 4.3 算法思想
    • 4.4 进行V-1次松弛操作
    • 4.5 判断负权环
    • 4.6 整体
  • 5 Floyed算法
    • 5.1 设置记录两点最短距离的数组,并初始化两点之间的距离
    • 5.2 更新两点之间的距离

0 代码仓库

https://github.com/Chufeng-Jiang/Graph-Theory/tree/main/src/Chapter11_Min_Path

1 Dijkstra算法

在这里插入图片描述

2 Dijkstra算法的实现

2.1 设置距离数组

//用于存储从源点到当前节点的距离,并初始化
dis = new int[G.V()];
Arrays.fill(dis, Integer.MAX_VALUE);
dis[s] = 0;

2.2 找到当前路径的最小值 curdis,及对应的该顶点cur

int cur = -1, curdis = Integer.MAX_VALUE;for(int v = 0; v < G.V(); v ++)if(!visited[v] && dis[v] < curdis){curdis = dis[v];cur = v;}

2.3 更新权重

visited[cur] = true;
for(int w: G.adj(cur))if(!visited[w]){if(dis[cur] + G.getWeight(cur, w) < dis[w])dis[w] = dis[cur] + G.getWeight(cur, w);}

2.4 其他接口

2.4.1 判断某个顶点的连通性

public boolean isConnectedTo(int v){G.validateVertex(v);return visited[v];
}

2.4.2 求源点s到某个顶点的最短路径

public int distTo(int v){G.validateVertex(v);return dis[v];
}

在这里插入图片描述

3使用优先队列优化-Dijkstra算法

3.1 设计内部类node

存放节点编号和距离

    private class Node implements Comparable<Node>{public int v, dis;public Node(int v, int dis){this.v = v;this.dis = dis;}@Overridepublic int compareTo(Node another){return dis - another.dis;}}

3.2 入队

PriorityQueue<Node> pq = new PriorityQueue<Node>();pq.add(new Node(s, 0));

这里的缺点就是,更新node时候,会重复添加节点相同的node,但是路径值不一样。不影响最后结果。

while(!pq.isEmpty()){int cur = pq.remove().v;if(visited[cur]) continue;visited[cur] = true;for(int w: G.adj(cur))if(!visited[w]){if(dis[cur] + G.getWeight(cur, w) < dis[w]){dis[w] = dis[cur] + G.getWeight(cur, w);pq.add(new Node(w, dis[w]));pre[w] = cur;}}
}

3.3 记录路径

private int[] pre;
  • 更新pre数组
for(int w: G.adj(cur))if(!visited[w]){if(dis[cur] + G.getWeight(cur, w) < dis[w]){dis[w] = dis[cur] + G.getWeight(cur, w);pq.add(new Node(w, dis[w]));pre[w] = cur;}}
  • 输出路径
    public Iterable<Integer> path(int t){ArrayList<Integer> res = new ArrayList<>();if(!isConnectedTo(t)) return res;int cur = t;while(cur != s){res.add(cur);cur = pre[cur];}res.add(s);Collections.reverse(res);return res;}

3.4 整体

package Chapter11_Min_Path.Dijkstra_pq;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.PriorityQueue;public class Dijkstra {private WeightedGraph G;private int s;private int[] dis;private boolean[] visited;private int[] pre;private class Node implements Comparable<Node>{public int v, dis;public Node(int v, int dis){this.v = v;this.dis = dis;}@Overridepublic int compareTo(Node another){return dis - another.dis;}}public Dijkstra(WeightedGraph G, int s){this.G = G;G.validateVertex(s);this.s = s;dis = new int[G.V()];Arrays.fill(dis, Integer.MAX_VALUE);pre = new int[G.V()];Arrays.fill(pre, -1);dis[s] = 0;pre[s] = s;visited = new boolean[G.V()];PriorityQueue<Node> pq = new PriorityQueue<Node>();pq.add(new Node(s, 0));while(!pq.isEmpty()){int cur = pq.remove().v;if(visited[cur]) continue;visited[cur] = true;for(int w: G.adj(cur))if(!visited[w]){if(dis[cur] + G.getWeight(cur, w) < dis[w]){dis[w] = dis[cur] + G.getWeight(cur, w);pq.add(new Node(w, dis[w]));pre[w] = cur;}}}}public boolean isConnectedTo(int v){G.validateVertex(v);return visited[v];}public int distTo(int v){G.validateVertex(v);return dis[v];}public Iterable<Integer> path(int t){ArrayList<Integer> res = new ArrayList<>();if(!isConnectedTo(t)) return res;int cur = t;while(cur != s){res.add(cur);cur = pre[cur];}res.add(s);Collections.reverse(res);return res;}static public void main(String[] args){WeightedGraph g = new WeightedGraph("g.txt");Dijkstra dij = new Dijkstra(g, 0);for(int v = 0; v < g.V(); v ++)System.out.print(dij.distTo(v) + " ");System.out.println();System.out.println(dij.path(3));}
}

4 Bellman-Ford算法

4.1 松弛操作

在这里插入图片描述

4.2 负权环

在这里插入图片描述

4.3 算法思想

在这里插入图片描述

4.4 进行V-1次松弛操作

// 进行V-1次松弛操作
for(int pass = 1; pass < G.V(); pass ++){for(int v = 0; v < G.V(); v ++)for(int w: G.adj(v))if(dis[v] != Integer.MAX_VALUE && // 避免对无穷值的点进行松弛操作dis[v] + G.getWeight(v, w) < dis[w]){dis[w] = dis[v] + G.getWeight(v, w);pre[w] = v;}
}

4.5 判断负权环

// 多进行一次操作,如果还有更新,那么存在负权换
for(int v = 0; v < G.V(); v ++)for(int w : G.adj(v))if(dis[v] != Integer.MAX_VALUE &&dis[v] + G.getWeight(v, w) < dis[w])hasNegCycle = true;

4.6 整体

package Chapter11_Min_Path.BellmanFord;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;public class BellmanFord {private WeightedGraph G;private int s;private int[] dis;private int[] pre;private boolean hasNegCycle = false;public BellmanFord(WeightedGraph G, int s){this.G = G;G.validateVertex(s);this.s = s;dis = new int[G.V()];Arrays.fill(dis, Integer.MAX_VALUE);dis[s] = 0;pre = new int[G.V()];Arrays.fill(pre, -1);// 进行V-1次松弛操作for(int pass = 1; pass < G.V(); pass ++){for(int v = 0; v < G.V(); v ++)for(int w: G.adj(v))if(dis[v] != Integer.MAX_VALUE && // 避免对无穷值的点进行松弛操作dis[v] + G.getWeight(v, w) < dis[w]){dis[w] = dis[v] + G.getWeight(v, w);pre[w] = v;}}// 多进行一次操作,如果还有更新,那么存在负权换for(int v = 0; v < G.V(); v ++)for(int w : G.adj(v))if(dis[v] != Integer.MAX_VALUE &&dis[v] + G.getWeight(v, w) < dis[w])hasNegCycle = true;}public boolean hasNegativeCycle(){return hasNegCycle;}public boolean isConnectedTo(int v){G.validateVertex(v);return dis[v] != Integer.MAX_VALUE;}public int distTo(int v){G.validateVertex(v);if(hasNegCycle) throw new RuntimeException("exist negative cycle.");return dis[v];}public Iterable<Integer> path(int t){ArrayList<Integer> res = new ArrayList<Integer>();if(!isConnectedTo(t)) return res;int cur = t;while(cur != s){res.add(cur);cur = pre[cur];}res.add(s);Collections.reverse(res);return res;}static public void main(String[] args){WeightedGraph g = new WeightedGraph("gw2.txt");BellmanFord bf = new BellmanFord(g, 0);if(!bf.hasNegativeCycle()){for(int v = 0; v < g.V(); v ++)System.out.print(bf.distTo(v) + " ");System.out.println();System.out.println(bf.path(3));}elseSystem.out.println("exist negative cycle.");WeightedGraph g2 = new WeightedGraph("g2.txt");BellmanFord bf2 = new BellmanFord(g2, 0);if(!bf2.hasNegativeCycle()){for(int v = 0; v < g2.V(); v ++)System.out.print(bf2.distTo(v) + " ");System.out.println();}elseSystem.out.println("exist negative cycle.");}
}

5 Floyed算法

在这里插入图片描述

5.1 设置记录两点最短距离的数组,并初始化两点之间的距离

private int[][] dis;
  • 初始化两点之间的距离
for(int v = 0; v < G.V(); v ++){dis[v][v] = 0;for(int w: G.adj(v))dis[v][w] = G.getWeight(v, w);
}

5.2 更新两点之间的距离

第一重循环:测试两点之间经过点t是否存在更短的路径。

        for(int t = 0; t < G.V(); t ++)for(int v = 0; v < G.V(); v ++)for(int w = 0; w < G.V(); w ++)if(dis[v][t] != Integer.MAX_VALUE && dis[t][w] != Integer.MAX_VALUE&& dis[v][t] + dis[t][w] < dis[v][w])dis[v][w] = dis[v][t] + dis[t][w];

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/177588.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

北邮22级信通院数电:Verilog-FPGA(9)第九周实验(4)实现寄存器74LS374

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 1.1 reg_74LS374.v 1.2 reg_LS3…

阿里达摩院开源DAMO-YOLO

1.简介 DAMO-YOLO是一个兼顾速度与精度的目标检测框架&#xff0c;其效果超越了目前的一众YOLO系列方法&#xff0c;在实现SOTA的同时&#xff0c;保持了很高的推理速度。DAMO-YOLO是在YOLO框架基础上引入了一系列新技术&#xff0c;对整个检测框架进行了大幅的修改。具体包括…

2023版Idea创建JavaWeb时,右键new没有Servlet快捷键选项

问题&#xff1a;右键时&#xff0c;没有创建servlet的快捷键&#xff0c;如下图&#xff1a; 解决方法&#xff1a; 1.打开idea&#xff0c;点击File>settings(设置)&#xff0c;进入settings页面&#xff0c;如下 从上图中的Files选项中没看到有servlet选项&#xff0c;…

简易搜索引擎SEWeibo

背景 有一组微博事件数据&#xff0c;之前做了一些数据分析与挖掘的工作。想着用C做一个简单的搜索引擎玩玩。 亮点&#xff1a; 搜索支持关系关键字作为搜索条件&#xff0c;以文本情感极性作为初筛条件&#xff0c;以TF-IDF为搜索排序依据以Reactor模式为基础&#xff0c;…

2013年7月18日 Go生态洞察:Go语言的第一个程序

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

什么是数据泄露?泄露途径有哪些?企业如何免遭数据泄露?

数据泄露指将机密信息、私人信息或其他敏感信息发布到不安全的环境中。数据泄露可能由意外引起&#xff0c;也可能是蓄意攻击的结果。 每年都有数百万人卷入数据泄露&#xff0c;包括意外看错病人图表的医生&#xff0c;以及大规模尝试访问政府计算机以发现敏感信息。 因为敏…

spring cloud alibaba 简介

微服务搭建组件选型 1.服务注册中心 Nacos(spring-cloud-alibaba) 2.服务通信 OpenFeign(spring-cloud) 3.服务熔断、降级、限流 Sentinel(spring-cloud-alibaba) 4.网关 Gateway(spring-cloud) 5.服务配置中心 …

查询站点真实IP地址,绕过CDN

一.如何判断站点是否使用了CDN&#xff1f; 使用其他省市的电脑进行ping看返回的IP地址是否相同通过第三方网站查询 站长工具 3.nslookup命令 二. 如何绕过CDN获取真实IP 子域名查询&#xff0c;因为很多站点只对主域名进行了CDN加速网站邮件头信息微步在线DNS查询

Java学习之路 —— 异常、集合、Stream

文章目录 1. 异常2. 集合2.1 遍历2.1.1 迭代器2.1.2 增强for循环2.1.3 Lambda 2.2 List2.3 Set2.3.1 HashSet2.3.2 LinkedHashSet2.3.3 TreeSet 2.4 Map 3. Stream 1. 异常 Exception&#xff1a;叫异常&#xff0c;是程序员可以捕捉的。异常又分为了2类&#xff1a; 运行时异…

吊椅在欧盟做EN581报告认证

什么是EN 581标准&#xff1f; EN 581标准是欧洲标准化委员会制定的关于户外家具机械物理性能要求的标准。该标准主要涉及耐候性、抗静态载荷、耐磨性、抗腐蚀性等方面的要求。 5.2 如何提高家具的抗静态载荷性能&#xff1f; 提高家具的抗静态载荷性能可以通过增加家具结构的…

无烟火焰:探索酒精壁炉的魅力

随着技术的不断发展&#xff0c;现代生活的很多方面都发生了变化&#xff0c;包括我们如何取暖和装饰我们的家。酒精壁炉是一个迅速崭露头角的家居装饰方式&#xff0c;为家庭带来了一种别具一格的现代化火焰体验。 过去&#xff0c;我们可能依赖于传统的木材壁炉或煤气取暖系统…

.pcd文件格式

更详细的格式介绍可以查看我的这篇博客 『Open3D』安装与点云格式通识_open3d安装_NNNNNathan的博客-CSDN博客文章浏览阅读1.9k次。介绍了open3d的安装和当前适用与存储点云信息的文件格式&#xff0c;并详细介绍了pcd与ply两种格式。_open3d安装https://blog.csdn.net/qq_413…