44. 蛤蟆的数据结构笔记之四十四弗洛伊德Floyd算法

44. 蛤蟆的数据结构笔记之四十四弗洛伊德Floyd算法

本篇名言:“希望是厄运的忠实的姐妹。 --普希金”

我们继续来看下数据结构图中的一个算法,这个算法来自图灵奖得主。

1.  Floyd算法介绍

Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。注意这个可不是心理学的那个弗洛伊德。

是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题。

算法的时间复杂度为O(N3),空间复杂度为O(N2)。

优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。

缺点:时间复杂度比较高,不适合计算大量数据。

2.  核心思路

通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。

从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。

采用的是(松弛技术),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);

其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]}

map[i,j]表示i到j的最短距离,K是穷举i,j的断点,map[n,n]初值应该为0.当然,如果这条路没有通的话,还必须特殊处理,比如没有map[i,k]这条路

3.  算法原理

Floyd算法的原理是动态规划

设Di,j,k为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。

1.        若最短路径经过点k,则Di,j,k = Di,k,k ? 1 + Dk,j,k ? 1;

2.        若最短路径不经过点k,则Di,j,k = Di,j,k ? 1。

因此,Di,j,k = min(Di,k,k ? 1 + Dk,j,k ?1,Di,j,k ? 1)。

Floyd-Warshall算法的描述如下:

for k ← 1 to n do

fori ← 1 to n do

for j ← 1 to n do

if (Di,k + Dk,j < Di,j) then

Di,j ← Di,k + Dk,j;

其中Di,j表示由点i到点j的代价,当Di,j为 ∞ 表示两点之间没有任何连接。

4.  图解法

如下图1所示

点与点之间的举例用矩阵来表示。INF表示点之间不连通。

具体步骤如下图2,3

初始状态:S是记录各个顶点间最短路径的矩阵。

第1步:初始化S。

矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。实际上,就是将图的原始矩阵复制到S中。

注:a[i][j]表示矩阵S中顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

第2步:以顶点A(第1个顶点)为中介点,若a[i][j]> a[i][0]+a[0][j],则设置a[i][j]=a[i][0]+a[0][j]。

以顶点a[1]6,上一步操作之后,a[1][6]=∞;而将A作为中介点时,(B,A)=12,(A,G)=14,因此B和G之间的距离可以更新为26。

同理,依次将顶点B,C,D,E,F,G作为中介点,并更新a[i][j]的大小。

5.  代码实现

原理什么的都抽象难懂,那么就来看下代码吧!代码其实很少的。

5.1         main

输入两个参数赋值给n和m.

m值表示输入m个值的数量。

N表示输入矩阵的大小。

将任何两个点间的最大距离设置成无限大。

输入m数值,3个值,前两个表示坐标,后一个表示值。

(如 1 0 12 表示a[1][0]=12,表示第1个点到第0个点的权值是12)

然后将矩阵 a和矩阵的对角线清零。

其中矩阵a是初始化的图,所有直接相连的顶点才有权值。

矩阵d是不断更新的图,会计算当前最新的顶点与顶点之间的最小权值,默认是所有都是无限大。

然后循环判断a[i][k]+a[k][j]<d[i][j],如果成立说明i和j两点之间有更短路径可达,则更新d矩阵,如果该值小于a矩阵的值,a矩阵也需要更新。

最后如下图所示(是图解法中的输入,顶点0 ,1,2,3,4,5,6分别表示顶点A,B,C,D,E,F,G)

6.  源码

#include<stdio.h>

#include<stdlib.h>

#define
max1000000000;

int a[1000][1000],d[1000][1000];

int main(){

inti,j,k,m,n;

intx,y,z;

printf("inputthe numbers you should to storage\n");

scanf("%d",&m);

printf("inputthe scale of your matrix\n");

scanf("%d",&n);

for(i=0;i<n;i++)

for(j=0;j<n;j++){

a[i][j]=max;

}

for(i=0;i<m;i++){

scanf("%d%d%d",&x,&y,&z);

a[x][y]=z;

a[y][x]=z;

}

for(i=0;i<n;i++)

for(j=0;j<n;j++)

d[i][j]=max;

for(i=0;i<n;i++){

d[i][i]=0;

a[i][i]=0;

}

for(k=0;k<n;k++)

for(i=0;i<n;i++)

for(j=0;j<n;j++){

if(a[i][k]+a[k][j]<d[i][j]){

d[i][j]=a[i][k]+a[k][j];

if(a[i][j] > d[i][j] )

a[i][j]= d[i][j];

}

}

printf("inputthe node a & node b\n");

scanf("%d%d",&n,&m);

printf("%d",d[n][m]);

return0;

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-26 16:11:33

44. 蛤蟆的数据结构笔记之四十四弗洛伊德Floyd算法的相关文章

45. 蛤蟆的数据结构笔记之四十五克鲁斯卡尔算法

本篇名言:"假如生活欺骗了你 ,不要忧郁 , 也不要愤慨 !不顺心的时候暂且容忍 : 相信吧 , 快乐的日子就会到来.--普希金" 上两篇学习了弗洛伊德和迪杰特斯拉算法.这次来看下克鲁斯卡尔算法. 欢迎转载,转载请标明出处:http://write.blog.csdn.net/postedit/47071539 1.  克鲁斯卡尔算法 克鲁斯卡尔(Kruskal)算法是在剩下的所有未选取的边中,找最小边,如果和已选取的边构成回路,则放弃,选取次小边.是实现图的最小生成树最常用的算法.

42. 蛤蟆的数据结构笔记之四十二图的遍历之广度优先

42. 蛤蟆的数据结构笔记之四十二图的遍历之广度优先 本篇名言:"生活真象这杯浓酒 ,不经三番五次的提炼呵 , 就不会这样一来可口 ! -- 郭小川" 继续看下广度优先的遍历,上篇我们看了深度遍历是每次一个节点的链表是走到底的. 欢迎转载,转载请标明出处:http://write.blog.csdn.net/postedit/47029275 1.  原理 首先,从图的某个顶点v0出发,访问了v0之后,依次访问与v0相邻的未被访问的顶点,然后分别从这些顶点出发,广度优先遍历,直至所有的

48. 蛤蟆的数据结构笔记之四十八的有向无环图的应用关键路径

48. 蛤蟆的数据结构笔记之四十八的有向无环图的应用关键路径 本篇名言:"富贵不淫贫贱乐 ,男儿到此是豪雄.-- 程颢" 这次来看下有向无环图的另一个应用关键路径. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47135061 1.  关键路径 与AOV-网相对应的是AOE-网(Activity On Edge)即边表示活动的网.AOE-网是一个带权的有向无环图,其中,顶点表示事件(Event),弧表示活动,权表

49. 蛤蟆的数据结构笔记之四十九图的连通性问题

49. 蛤蟆的数据结构笔记之四十九图的连通性问题 本篇名言:"我们不得不饮食.睡眠.游惰.恋爱,也就是说,我们不得不接触生活中最甜蜜的事情:不过我们必须不屈服于这些事物 .....--约里奥?居里"     此篇就作为数据结构入门笔记的最后一篇吧. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47135259 设图G=(V,E)是一个无向图,G的一个连通分支是一个最大的连通子图,即一个连通分支是不包含在任何更大的

46. 蛤蟆的数据结构笔记之四十六普里姆算法

46. 蛤蟆的数据结构笔记之四十六普里姆算法 本篇名言:"手莫伸 ,伸手必被捉.党与人民在监督 ,万目睽睽难逃脱.汝言惧捉手不伸 ,他道不伸能自觉 , 其实想伸不敢伸 ,人民咫尺手自缩.-- 陈毅" 连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小.构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree). 找连通图的最

34. 蛤蟆的数据结构笔记之三十四树的概念

34. 蛤蟆的数据结构笔记之三十四树的概念 本篇名言:"过去属于死神,未来属于你自己.--雪莱" 本篇笔记开始我们要进入新的概念了,树!是不是有点小激动呢?让我们从概念开始吧 当然概念要理解,如果当前不能立刻理解,可以后续结合代码一起理解效果更佳. 1.  树型结构 之前我们学习的那么多,其实都是线性数据结构. 树 则不同,它是非线性结构. 树形结构指的是数据元素之间存在着"一对多"的树形关系的数据结构,是一类重要的非线性数据结构.在树形结构中,树根结点没有前驱结点

14、蛤蟆的数据结构笔记之十四栈的应用之栈与递归之阿克曼函数

14.蛤蟆的数据结构笔记之十四栈的应用之栈与递归之阿克曼函数 本篇名言:"今天就是生命 ----- 是唯一你能确知的生命." 继续递归应用,阿克曼函数. 欢迎转载,转载请标明出处: 1.  阿克曼函数 阿克曼函数(Ackermann)是非原始递归函数的例子.它需要两个自然数作为输入值,输出一个自然数.它的输出值增长速度非常高,仅是对于(4,3)的输出已大得不能准确计算. Ackermann函数定义如下: 若m=0,返回n+1. 若m>0且n=0,返回Ackermann(m-1,1

41 蛤蟆的数据结构笔记之四十一图的遍历之深度优先

41  蛤蟆的数据结构笔记之四十一图的遍历之深度优先 本篇名言:"对于我来说 , 生命的意义在于设身处地替人着想 , 忧他人之忧 , 乐他人之乐. -- 爱因斯坦" 上篇我们实现了图的邻接多重表表示图,以及深度遍历和广度遍历的代码,这次我们先来看下图的深度遍历. 欢迎转载,转载请标明出处: 1.  原理 图遍历又称图的遍历,属于数据结构中的内容.指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次.图的遍历操作和树的遍历操作功能相似.图的遍历是图的一种基本操作,图的许多其它

15、蛤蟆的数据结构笔记之十五栈的应用之栈与递归之八皇后问题

15.蛤蟆的数据结构笔记之十五栈的应用之栈与递归之八皇后问题 本篇名言:"人的一生应当这样度过:当回忆往事的时候,他不致于因为虚度年华而痛悔,也不致于因为过去的碌碌无为而羞愧:在临死的时候,他能够说:"我的整个生命和全部精力,都已经献给世界上最壮丽的事业--为人类的解放而斗争." 继续递归问题,本次是经典的八皇后问题: 欢迎转载,转载请标明出处: 1.  八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出