【算法导论】单源最短路径之Bellman-Ford算法
单源最短路径指的是从一个顶点到其它顶点的具有最小权值的路径。我们之前提到的广度优先搜索算法就是一种无权图上执行的最短路径算法,即在所有的边都具有单位权值的图的一种算法。单源最短路径算法可以解决图中任意顶点间的最短路径。
对于单源最短路径问题,一般有两种经典解法:1.对于有权值为负的图,采用Bellman-Ford算法;2.对于权值全为正的图,常采用Dijkstra算法。本文介绍Bellman-Ford算法,下一篇介绍Dijkstra算法。
Bellman-Ford算法适用于权值可以为负、无权值为负的回路的图,这比Dijkstra算法的使用范围要广。其基本思想为:首先假设源点到所有点的距离为无穷大,然后从任一顶点u出发,遍历其它所有顶点vi,计算从源点到其它顶点vi的距离与从vi到u的距离的和,如果比原来距离小,则更新,遍历完所有的顶点为止,即可求得源点到所有顶点的最短距离。下面用实例说明:
上图中,顶点内的值表示该顶点到s顶点的距离。在下面的具体程序实现中,我用0 1 2 3 4代表 s t x y z.
具体程序实现如下:
#include<stdio.h>
#define M 10//边数
#define N 5//顶点数
#define MAX 10000
int BellmanFord(int dist[N][N],int d[N],int i);
int flag1=0;
int flag2=0;
typedef struct
{
int startvex;
int endvex;
int length;
}edge;
edge T[M];
void main()
{
int dist[N][N]={{0,6,MAX,7,MAX},
{MAX,0,5,8,-4},
{MAX,-2,0,MAX,MAX},
{MAX,MAX,-3,0,9},
{2,MAX,7,MAX,0}};//图的邻接矩阵
int d[N];
int num=0;
num=BellmanFord(dist,d, 0);//计算下标为0的顶点到其它顶点的距离,num用于统计边数
for(int i=0;i<N;i++)//打印到各个顶点之间的距离
printf("%d ",d[i]);
printf("\n");
for(int j=0;j<num;j++)//打印考虑过的边
printf("start=%d,end=%d,lenth=%d\n",T[j].startvex,T[j].endvex,T[j].length);
}
int BellmanFord(int dist[N][N],int d[N],int i)
{
for(int j=0;j<N;j++)//初始化
d[j]=MAX;
d[i]=0;
int num=0;
for(int k=0;k<N-1;k++)
{
for(int ii=0;ii<N;ii++)
for(int jj=0;jj<N;jj++)
{
if(dist[ii][jj]!=MAX)
{
if(d[jj]>(d[ii]+dist[ii][jj]))//不断更新距离
{
d[jj]=d[ii]+dist[ii][jj];//当原节点到jj节点的距离大于
//原节点到ii节点的距离与从ii节点到jj节点的距离和时更新
T[num].startvex=ii;
T[num].endvex=jj;
T[num].length=dist[ii][jj];
num++;
}
}
}
}
for(int ii=0;ii<N;ii++)
for(int jj=0;jj<N;jj++)//有权值为负的回路的情况
{
if(d[jj]>(d[ii]+dist[ii][jj]))
return 0;
}
return num;
}
结果显示如下:
注意:上述的结果与前面图解的一致,但是用到的边有7条比前面图解的阴影部分的边多3条,这是因为图解过程中省略了中间的一些步骤,直接得到最小权值时的情况。通过阴影部分的边,我们可以轻松的找到最短路径所经过的顶点,当然,当图比较复杂时,就该写程序来打印最短路径了。
注:如果程序出错,可能是使用的开发平台版本不同,请点击如下链接: 解释说明
原文:http://blog.csdn.net/tengweitw/article/details/17451125
作者:nineheadedbird
【算法导论】单源最短路径之Bellman-Ford算法的更多相关文章
- 单源最短路径问题之dijkstra算法
欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 算法的原理 以源点开始,以源点相连的顶点作为向外延伸的顶点,在所有这些向外延伸的顶 ...
- 图->最短路径->单源最短路径(迪杰斯特拉算法Dijkstra)
文字描述 引言:如下图一个交通系统,从A城到B城,有些旅客可能关心途中中转次数最少的路线,有些旅客更关心的是节省交通费用,而对于司机,里程和速度则是更感兴趣的信息.上面这些问题,都可以转化为求图中,两 ...
- Bellman-Ford算法 - 有向图单源最短路径
2017-07-27 08:58:08 writer:pprp 参考书目:张新华的<算法竞赛宝典> Bellman-Ford算法是求有向图单源最短路径的,dijkstra算法的条件是图中 ...
- 【算法】单源最短路径和任意两点最短路径总结(补增:SPFA)
[Bellman-Ford算法] [算法]Bellman-Ford算法(单源最短路径问题)(判断负圈) 结构: #define MAX_V 10000 #define MAX_E 50000 int ...
- 51nod 1445 变色DNA ( Bellman-Ford算法求单源最短路径)
1445 变色DNA 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1 ...
- 【算法】Dijkstra算法(单源最短路径问题)(路径还原) 邻接矩阵和邻接表实现
Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...
- 【算法】Bellman-Ford算法(单源最短路径问题)(判断负圈)
单源最短路问题是固定一个起点,求它到其他所有点的最短路的问题. 算法: 设 d[i] 表示 起点 s 离点 i 的最短距离. [1.初始化] 固定起点s,对所有的点 , 如果 i = s , ...
- 单源最短路径问题2 (Dijkstra算法)
用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...
- 单源最短路径问题1 (Bellman-Ford算法)
/*单源最短路径问题1 (Bellman-Ford算法)样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9] */ ...
- [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)
单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...
随机推荐
- GC对象分配规则
1.对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC. 2.大对象直接进入老年代(大对象是指需要大量连续内存空间的对象).这样做的目的是避免在Eden区和两个S ...
- Programming In Scala笔记-第四章、类和对象
类似于Java,Scala中也有类和对象的概念. 一.类.属性和方法 1.类 类是对一类事物的抽象,当一个类被定义后,就可以以该定义为模板,定义该类的一系列对象.比如说有以下一个模板 人类: 有姓名: ...
- RxJava(二) map操作符用法详解
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51531348 本文出自:[余志强的博客] 1 map操作符的作用 R ...
- Android自定义ViewGroup(四、打造自己的布局容器)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51500304 本文出自:[openXu的博客] 目录: 简单实现水平排列效果 自定义Layo ...
- PhysicsJoint
1 PhysicsJoint的使用 T09Join.h #ifndef__T09Joint_H__ #define__T09Joint_H__ #include"T32.h" cl ...
- java详解final、多态、抽象类、接口原理
1:final关键字(掌握) (1)是最终的意思,可以修饰类,方法,变量. (2)特点: A:它修饰的类,不能被继承. B:它修饰的方法,不能被重写. C:它修饰的变量,是一个常量. (3)面试相关: ...
- Android开源框架ViewPagerIndicator的基本使用
转载本博客请注明出处:点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52495647 很多新闻资讯类的app都有一些共性,那就是 ...
- SYBASE的select into与insert into使用和区别
对于表的部分或全部字段的复制,Sybase数据库提供了两种方式:select into和insert into. select into: 语法:select value1, value2, val ...
- Mybatis3.4.0不支持mybatis-spring1.2.5及以下版本
今天将工程的Mybatis的版本由3.3.0升级到3.4.0导致程序运行错误,使用的mybatis-spring版本是1.2.3,错误内容如下,最后发现是SpringManagedTransactio ...
- UNIX网络编程——客户/服务器程序设计示范(七)
TCP预先创建线程服务器程序,每个线程各自accept 前面讨论过预先派生一个子进程池快于为每个客户线程派生一个子进程.在支持线程的系统上,我们有理由预期在服务器启动阶段预先创建一个线程池以取 ...