前置知识,学过离散数学的可以跳到后半页,直接看算法解析
这是floyd中for循环里面两份for循环计算的原理和设计思路。详细解释请看下面。
for(i=0;i<N-1;i++){
for(j=0;j<G;j++){
int u=e[j].u,v=e[j].v;
if(d[u]!=INF&&d[u]+w[u][v]<d[v]) d[v]=d[u]+w[u][v];
}
}
floyd模板,仅供参考.................................
其中A就是我们的邻接矩阵,储存的是一个点到一个点的最短距离。
其中,bij 表示图中 一个点到一个点 两条路径的距离。
比如 如果a12 表示1到2的距离 。
如果A*A 中a12 有数值表示 有路为2条的路径 从1号点 到达2 号点。比如a (1,n)(n从1 开始到 n)*a (n,2) 如果有数值(表示有路径到达)表示 1 号点到 对应的n号点 ,n到2 的路径存在且路径长度为a(1,n)+a(n,2)。
我们可以得到,1号点到2号点 经过两条路,的最短路径。在与只经一条路径的比较,取最小值,得到最新的A矩阵。
(做一次矩阵模拟的运算将会计算所以的点,所以得到的是矩阵中任意一点到任意一点的路的条数小于二的最短路径)。
在上面已经得到只经过两条路的点到点的最段路径。在于只经过一条的比较得到只经过1条到2条路的最短路径。
A在与A进行模拟矩阵运算(模拟是为了运用矩阵运算性质,下面有解释),得到的是3条路的点到点的最短路径。在与之前的1到2条的最短路径比较,得到只经过1到3条路的最短路径。
当运算进行n-1次时,得到的是1到n-1条的最短路径,又因为在图中,如果没有负权圈(就是走一圈路程变短了 比如 走 +2 +3 -6 = -1 的圈),一个点到一个点最多只要经过n-1条路,可以到达另一个点,除非中途走了一个环(比如 1号点->2 ->3 ->1 ->4)//这种走环了。那么就最多走n-1条路。
而模拟矩阵运算的性质以及最短路径,决定了不会形成环,因为一旦形成环肯定比没有形成环的路径长。
那么在比较大小,取值时我们只取小的,就已经不可能是环了,每一步运算都没有取环,所以最后的结果只需要走n-1次就行,因为我们运算就保证每一次取的结果都是无环的结果。
结果可证明floyd原理,更加详细的原理请查看离散数学关于图矩阵的运算性质,可能需要推理一下。
请不要抄袭,转载请给出链接。