Froyd算法:
1.这是一个典型的动态规划的图论最优点距算法。其动态转移方程为:distance(i , j) = min(distance(i , k) , distance(k , j)),其含义表示为:从图中一个点i 到另一个点j 的最短路径, 就是先从点i 到另一个点j 之中某一个点k 的距离 加上点k 到 j 的距离的最小值
*(k可以是从i点到j点中的任意一个点,包括点 i , j 点)
2.作为动态规划的求解应用, 则必然是从已有条件 通过转移方程 推导出目标值的过程。当已知任意两点之间的直接距离后, 就能得到推导的初始条件。那么除了初始条件,最重要的是确定边界。
*(边界就是动态规划的终止线或者不规划的区域,比如以“走地图游戏”例子,左上角到右下角行走过程,其边界就是1.到达右下角就停止;2.只能向右或向下行走;3.不能走出方格棋盘)
3.假设现在已经知道任意两个点之间的 ‘直接距离’ ,那么接下来就是从他的二级距离中找到最小的值与直接距离比较,取小的距离作为新距离。
*(二级距离,这里代表起始点先到一个中间点,然后再从中间点到目标点的两段距离的和。另外不考虑起始点是如何到达中间点,也不考虑中间点是如何到达目标点的,即看作其之间已经有了一个最优距离的通道)
实现Froyd算法:
1.C++实现:
#include <iostream>
#define maxsize 100
#define INFINITY 999
using namespace std;
int dis[maxsize][maxsize];
int main(){
int n;
cout << "输入点的个数:" << endl;
cin >> n;
cout << "输入图的邻接矩阵:" << endl;
for(int i=1;i <= n;i++)
for(int j=1;j <= n;j++){
cin >> dis[i][j];
if(dis[i][j] == 0 && i!=j){
dis[i][j] = INFINITY;
}
}
for(int i=1;i <= n;i++){
for(int j=1;j <= n;j++){
int min = INFINITY;
for(int k=1;k <= n;k++){
if(min > dis[i][k]+dis[k][j]){
min = dis[i][k]+dis[k][j];
}
}
if(dis[i][j] > min){
dis[i][j] = min;
dis[j][i] = min;
}
}
}
for(int i=1;i <= n;i++){
for(int j=i+1;j <= n;j++){
cout << i << "点到" << j << "点的最短距离为:" << dis[i][j] << endl;
}
}
return 0;
}
测试图:
测试数据:
8
0 10 0 5 12 0 0 0
10 0 6 0 0 0 0 0
0 6 0 0 2 0 0 0
5 0 0 0 0 0 17 0
12 0 2 0 0 0 8 13
0 0 0 0 0 0 0 3
0 0 0 17 8 0 0 10
0 0 0 0 13 3 10 0
结果:
1点到2点的最短距离为:10
1点到3点的最短距离为:14
1点到4点的最短距离为:5
1点到5点的最短距离为:12
1点到6点的最短距离为:28
1点到7点的最短距离为:20
1点到8点的最短距离为:25
2点到3点的最短距离为:6
2点到4点的最短距离为:15
2点到5点的最短距离为:8
2点到6点的最短距离为:24
2点到7点的最短距离为:16
2点到8点的最短距离为:21
3点到4点的最短距离为:19
3点到5点的最短距离为:2
3点到6点的最短距离为:18
3点到7点的最短距离为:10
3点到8点的最短距离为:15
4点到5点的最短距离为:17
4点到6点的最短距离为:30
4点到7点的最短距离为:17
4点到8点的最短距离为:27
5点到6点的最短距离为:16
5点到7点的最短距离为:8
5点到8点的最短距离为:13
6点到7点的最短距离为:13
6点到8点的最短距离为:3
7点到8点的最短距离为:10
2.python实现
from pylab import *
INFINITY = 9999
D = array([[0,10,INFINITY,5,12,INFINITY,INFINITY,INFINITY],
[10,0,6,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY],
[INFINITY,6,0,INFINITY,2,INFINITY,INFINITY,INFINITY],
[5,INFINITY,INFINITY,0,INFINITY,INFINITY,17,INFINITY],
[12,INFINITY,2,INFINITY,0,INFINITY,8,13],
[INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,0,INFINITY,3],
[INFINITY,INFINITY,INFINITY,17,8,INFINITY,0,10],
[INFINITY,INFINITY,INFINITY,INFINITY,13,3,10,0]])
lengthD = len(D)
P = D;
for i in range(lengthD):
for j in range(lengthD):
min = INFINITY
for k in range(lengthD):
if(min > P[i,k]+P[k,j]):
min = P[i,k]+P[k,j]
if(P[i,j] > min):
P[i,j] = min
P[j,i] = min
for i in range(lengthD):
for j in range(lengthD):
if (i < j):
print('{0}点到{1}点的最短路径为:{2}'.format(i,j,P[i,j]))
测试图同上
结果: