图论:Froyd算法(含 C/C++、python实现)

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]))
                

测试图同上

结果:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼卡尼卡尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值