版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
最短路问题:
最短路:给定两顶点,在以这两个点为起始点和终点的路径中,边的权值和最小的路径。权值为点之间的距离
bellman-ford算法
思想: 首先先定义一个数组d ,数组的每个元素代表 起点s到每个顶点的距离 d[s] = 0,d[j]其余的为无穷,
就是起点到自己的距离为0,到其他顶点的距离为无穷。
假设以A为起点的话,初始化如下图
然后开始遍历边集
---edge,以i,j作为起点和终点
---如果起点s->i(d[i])存在的话,比较s->i->j和s->j的大小,如果s->i->j小于s->j,则更新d[j],d[j] = d[i]+i->j
---在这一趟中没有更新的话,退出循环。此时数组d里面的元素为:起点s到各个顶点的最短距离
代码如下:
/**
* 求起点到各顶点的最短距离
* @param s 起点
* @return
*/
private static int[] shortestPath(int s)
{
int n = graph.length; //顶点数
//记录s到各顶点的最短距离
int[] d = new int[n];
for(int i = 0;i<n;i++)
{
d[i] = Integer.MAX_VALUE;
}
d[s] = 0; //自己到自己的距离为0
while(true)
{
boolean update = false;
//扫描所有的边
for(int i = 0;i<n;i++)
{
//起点到i的最短距离还没算出来
if(d[i] == Integer.MAX_VALUE)
{
continue;
}
for(int j = 0;j<n;j++)
{
int cost = graph[i][j];//i,j之间的距离
if(cost>0) //i,j两点之间有边,起点是i
{
if(d[j] > d[i]+cost)// 起点先到i,i->j 两端距离加起来比起点直接到j的距离短,则更新
{
update = true;
d[j] = d[i]+cost;
}
}
}
}
//无需任何更新,退出外循环
if(update == false)
{
break;
}
}
return d;
}
//图用邻接矩阵来表示
static int[][] graph = {
{0,2,5,0,0,0,0},
{2,0,4,6,10,0,0},
{5,4,0,2,0,0,0},
{0,6,2,0,0,1,0},
{0,10,0,0,0,3,5},
{0,0,0,1,3,0,9},
{0,0,0,0,5,9,0}
};
测试:以0为起点
public static void main(String[] args) {
int[] shortestPath = shortestPath(0);
System.out.println(Arrays.toString(shortestPath));
}
测试结果:
[0, 2, 5, 7, 11, 8, 16]