算法-贝尔曼-福特算法

注:该文是本博主记录学习之用,没有太多详细的讲解,敬请谅解!

一、简介

贝尔曼-福特算法(Bellman–Ford algorithm )用于计算出起点到各个节点的最短距离,支持存在负权重的情况
  • 它的原理是对图进行最多V-1次松弛操作,得到所有可能的最短路径。其优于狄克斯特拉算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达O(VE)。但算法可以进行若干种优化,提高了效率。

  • 贝尔曼-福特算法每次对所有的边进行松弛,每次松弛都会得到一条最短路径,所以总共需要要做的松弛操作是V - 1次。在完成这么多次松弛后如果还是可以松弛的话,那么就意味着,其中包含负环。

二、场景

  • 从起点出发是否存在到达各个节点的路径。
  • 从起点出发到达各个节点最短路径。
  • 是否存在负环路。

三、实现思路

  • 初始化时将起点s到各个顶点v的距离dist(s->v)赋值为∞,dist(s->s)赋值为0

  • 后续进行最多n-1次遍历操作,对所有的边进行松弛操作,假设:

    所谓的松弛,以边ab为例,若dist(a)代表起点s到达a点所需要花费的总数,
    dist(b)代表起点s到达b点所需要花费的总数,weight(ab)代表边ab的权重, 若存在:

    (dist(a) +weight(ab)) < dist(b)

    则说明存在到b的更短的路径,s->…->a->b,更新b点的总花费为(dist(a) +weight(ab)),父节点为a

  • 遍历都结束后,若再进行一次遍历,还能得到s到某些节点更短的路径的话,则说明存在负环路

四、java实现

如下图,求出A到各节点的最短路径

public class BellmanFord {/*** 实现思路:* 1、初始化时将起点起点到各个顶点的距离赋值为(无穷大)∞,当前起点距离赋值为0* 2、后续进行最多n-1次遍历操作* @param args*/public static void main(String[] args){//创建图Edge ab = new Edge("A", "B", -1);Edge ac = new Edge("A", "C", 4);Edge bc = new Edge("B", "C", 3);Edge be = new Edge("B", "E", 2);Edge ed = new Edge("E", "D", -3);Edge dc = new Edge("D", "C", 5);Edge bd = new Edge("B", "D", 2);Edge db = new Edge("D", "B", 1);//需要按图中的步骤步数顺序建立数组,否则就是另外一幅图了,//从起点A出发,步骤少的排前面Edge[] edges = new Edge[] {ab,ac,bc,be,bd,ed,dc,db};//存放到各个节点所需要消耗的时间HashMap<String,Integer> costMap = new HashMap<String,Integer>();//到各个节点对应的父节点HashMap<String,String> parentMap = new HashMap<String,String>();//初始化各个节点所消费的,当然也可以再遍历的时候判断下是否为Null//i=0的时候costMap.put("A", 0); //源点costMap.put("B", Integer.MAX_VALUE);costMap.put("C", Integer.MAX_VALUE);costMap.put("D", Integer.MAX_VALUE);costMap.put("E", Integer.MAX_VALUE);//进行节点数n-1次循环for(int i =1; i< costMap.size();i++) {boolean hasChange = false;for(int j =0; j< edges.length;j++) {Edge edge = edges[j];//该边起点目前总的路径大小int startPointCost = costMap.get(edge.getStartPoint()) == null ? 0:costMap.get(edge.getStartPoint());//该边终点目前总的路径大小int endPointCost = costMap.get(edge.getEndPoint()) == null ? Integer.MAX_VALUE : costMap.get(edge.getEndPoint());//如果该边终点目前的路径大小 > 该边起点的路径大小 + 该边权重 ,说明有更短的路径了if(endPointCost > (startPointCost + edge.getWeight())) {costMap.put(edge.getEndPoint(), startPointCost + edge.getWeight());parentMap.put(edge.getEndPoint(), edge.getStartPoint());hasChange = true;}}if (!hasChange) {//经常还没达到最大遍历次数便已经求出解了,此时可以优化为提前退出循环break;}}//在进行一次判断是否存在负环路boolean hasRing = false;for(int j =0; j< edges.length;j++) {Edge edge = edges[j];int startPointCost = costMap.get(edge.getStartPoint()) == null ? 0:costMap.get(edge.getStartPoint());int endPointCost = costMap.get(edge.getEndPoint()) == null ? Integer.MAX_VALUE : costMap.get(edge.getEndPoint());if(endPointCost > (startPointCost + edge.getWeight())) {System.out.print("\n图中存在负环路,无法求解\n");hasRing = true;break;}}if(!hasRing) {//打印出到各个节点的最短路径for(String key : costMap.keySet()) {System.out.print("\n到目标节点"+key+"最低耗费:"+costMap.get(key));if(parentMap.containsKey(key)) {List<String> pathList = new ArrayList<String>();String parentKey = parentMap.get(key);while (parentKey!=null) {pathList.add(0, parentKey);parentKey = parentMap.get(parentKey);}pathList.add(key);String path="";for(String k:pathList) {path = path.equals("") ? path : path + " --> ";path = path +  k ;}System.out.print(",路线为"+path);}}}}/***  代表"一条边"的信息对象** @author Administrator**/static class Edge{//起点idprivate String startPoint;//结束点idprivate String endPoint;//该边的权重private int weight;public Edge(String startPoint,String endPoint,int weight) {this.startPoint = startPoint;this.endPoint = endPoint;this.weight = weight;}public String getStartPoint() {return startPoint;}public String getEndPoint() {return endPoint;}public int getWeight() {return weight;}}}

五、小结

1、贝尔曼-福特算法Bellman–Ford主要用于存在负权重的方向图中(没有负权重也可以用,但是效率比狄克斯特拉算法低很多),搜索出源点到各个节点的最短路径

2、Bellman–Ford可以判断出图是否存在负环路,但存在负环路的情况下不支持计算出各个节点的最短路径。只需要在结束(节点数目-1)次遍历后,再执行一次遍历,若还可以更新数据则说明存在负环路

算法-贝尔曼-福特算法相关推荐

  1. JavaScript实现bellmanFord贝尔曼-福特算法(附完整源码)

    JavaScript实现bellmanFord贝尔曼-福特算法 bellmanFord.js完整源代码 bellmanFord.js完整源代码 export default function bell ...

  2. C++实现bellman ford贝尔曼-福特算法(最短路径)(附完整源码)

    C++实现bellman ford贝尔曼-福特算法 实现bellman ford贝尔曼-福特算法的完整源码(定义,实现,main函数测试) 实现bellman ford贝尔曼-福特算法的完整源码(定义 ...

  3. 算法系列——贝尔曼福特算法(Bellman-Ford)

    本系列旨在用简单的人话讲解算法,尽可能避免晦涩的定义,读者可以短时间内理解算法原理及应用细节.我在努力! 本篇文章编程语言为Python,供参考. 贝尔曼福特算法(Bellman-Ford) 典型最短 ...

  4. 贝尔曼-福特算法(Bellman-Ford)最短路径问题

    贝尔曼-福特算法(Bellman-Ford) 一.贝尔曼-福特算法(Bellman-Ford) 二.代码实现 一.贝尔曼-福特算法(Bellman-Ford) 贝尔曼-福特算法与迪科斯彻算法类似,都以 ...

  5. 了解贝尔曼·福特算法

    文章目录 为什么在现实生活中会有负权重的边? 为什么我们要留意负权重? 贝尔曼·福特算法如何工作 贝尔曼·福特伪码 Bellman Ford vs Dijkstra C示例 贝尔曼·福特算法的复杂度 ...

  6. Python实现迪杰斯特拉算法和贝尔曼福特算法求解最短路径

    文章目录 (一).题目 (二).导库 (三).绘制带权无向图 (四).获得最短路径 (四).实现最短路径高亮 (五).完整代码 (六).结果展示 关于Python数据分析在数学建模中的更多相关应用:P ...

  7. Bellman-Ford贝尔曼福特算法实现

    作为一种单源最短路径算法,Bellman-Ford对于有向图和无向图都能适用,它还有一个Dijkstra算法无法具备的特点,那就是对含负权图的最短路径搜索. 每i轮对边的遍历之后,只要不存在负权回路, ...

  8. 算法:贝尔曼-福特算法

    算法:贝尔曼-福特算法 1.简介 贝尔曼-福特算法(Bellman–Ford algorithm)是一个查找最短路径算法主要优点是支持负权重,但时间复杂度较高,还会有负权环的问题. 如果不需要权重应该 ...

  9. 算法/最短路径/Bellman-Ford贝尔曼福特算法

    ##问题描述 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的 ...

最新文章

  1. C#获取存储过程返回值和输出参数值的方法
  2. No module named 'dlframework.common.utils.local'
  3. 【Java面试题】13 Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?...
  4. Agentless方式监控,让所有网络都有管理员
  5. 在java.library.path中找不到允许在生产环境中实现最佳性能的基于APR的Apache Tom.....
  6. 小米8对一加6打开软件速度测试,买一加6还是小米8?小米8和一加6区别对比
  7. 怎样申请 Google Map apiKey
  8. Java编程:哈希表
  9. 光伏电池最大功率跟踪
  10. c语言程序设计 k,《C语言程序设计》谭浩强版-教学教案 k.doc
  11. 【设计原则】软件开发中的原则
  12. 制动计算机,一种基于摩擦制动的计算机主机底座
  13. Django 修改时区时间
  14. cpu,内存条,硬盘,显卡,主板,显示器之间的关系
  15. 同网络的计算机能共享音箱吗,2019年PC“老爷机”局域网内DLNA共享音乐到小度智能音箱全记录...
  16. 亚马逊封号,新规则来了,你知道了吗?
  17. 取消endnotes参考文献格式域的步骤_EndNote参考文献格式的更改(转载)
  18. flex中换行符的使用
  19. error: expected ‘}’ at end of input }问题处理
  20. Linux - top命令详解

热门文章

  1. 程序猿咆哮体--纯娱乐,勿认真
  2. 没有网络怎么配置传奇SF登陆器自动读取列表
  3. 张维迎:知识的本质与企业家精神
  4. Unable to locate package expat-devel:
  5. 2022上海国际边缘计算产业大会暨展览会
  6. MPU6050内部DMP固件移植解析,STM32获取欧拉角串口显示
  7. (动图详解)汇编视角观察函数栈帧的创建和销毁
  8. 《大数据算法》一第1章 绪论
  9. iptables firewalld
  10. 清华计算机系行政面试,清华大学复试面试过程及成功经验分享