Warshall传递闭包算法的学习与实现
来源:互联网 发布:河南极速网络 编辑:程序博客网 时间:2024/05/16 06:47
1、问题引入
一个有n个顶点的有向图的传递闭包为:有向图中的初始路径可达情况可以参见其邻接矩阵A,邻接矩阵中A[i,j]表示i到j是否直接可达,若直接可达,则A[i,j]记为1,否则记为0;两个有向图中i到j有路径表示从i点开始经过其他点(或者不经过其他点)能够到达j点,如果i到j有路径,则将T[i,j]设置为1,否则设置为0;有向图的传递闭包表示从邻接矩阵A出发,求的所有节点间的路径可达情况,该矩阵就为所要求的传递闭包矩阵。。。
例如:
有向图为:
由该有向图可以得到初始的邻接矩阵为:
那么warshall传递闭包算法的目的就是由邻接矩阵出发,进行探索求出最终的传递闭包:
2、动态规划求解思路
动态规划将问题分段,本例warshall算法是通过一系列n阶矩阵r(k)来构造最终阶段n阶传递闭包矩阵r(n)
R(k) 由它的前趋 R(k-1) 计算得到(分级推进计算)。
R(0) ——该矩阵不允许它的路径中包含任何中间顶点,即从该矩阵的任意顶点出发的路径不含有中间顶点,此即邻接矩阵。
R(1) ——允许路径中包含第1个顶点(本例编号 1)作为中间顶点。
R(2) ——允许路径中包含前2个顶点(本例编号1 2)作为中间顶点。
R(k) ——允许路径中包含前k个顶点作为中间顶点。
R(n) ——允许路径中包含全部 n 个顶点作为中间顶点。
每个后继矩阵 R(k) 对其前趋 R(k-1) 来说,在路径上允许增加一个顶点, 因此有可能包含更多的1(增加前为1的在增加后依然为1)。
3、具体的算法描述
warshall(A[1...n,1...n]r(0)<-A;for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) r(k)[i,j]=r(k-1)[i,j] or(r(k-1)[i,k] and r(k-1)[k,j]);return r(n);
4、具体实现代码如下
说明:(1)有向图的顶点个数和初始邻接矩阵存储在2.txt中(具体如下图),其中4表示有向图中有4 个顶点,其他表示初始邻接矩阵。
(2)有向图的顶点个数和初始邻接矩阵个数可以随意更改,,,,
具体代码:
#include<stdio.h>#include<stdlib.h>void Warshall(int,int**);void main(){ int i,j,num; FILE*p; p=fopen("2.txt","r"); if(p==NULL) { printf("cannot open 2.txt"); exit(-1); } fscanf(p,"%d",&num); int **r=(int**)malloc(sizeof(int*)*(num+1)); for(i=0;i<num+1;i++) r[i]=(int*)malloc(sizeof(int)*(num+1)); for(i=1;i<num+1;i++) for(j=1;j<num+1;j++) fscanf(p,"%d",&r[i][j]); printf("顶点个数为:%d\n",num); printf("邻接矩阵为:\n"); for(i=1;i<num+1;i++) { for(j=1;j<num+1;j++) printf(" %d ",r[i][j]); printf("\n"); } Warshall(num,r); printf("最终的传递闭包为\n"); for(i=1;i<num+1;i++) { for(j=1;j<num+1;j++) printf(" %d ",r[i][j]); printf("\n"); }}//三重循环实现的warshall算法//r为邻接矩阵,中间存储初试的可达与非可达路径情况,1表示可达,0表示不可达void Warshall(int num,int**r){ int i,j,k; int **temp=(int**)malloc(sizeof(int*)*(num+1)); for(i=0;i<num+1;i++) temp[i]=(int*)malloc(sizeof(int)*(num+1)); for(k=1;k<=num;k++)//依次取得的可以作为中间点的顶点 { for(i=1;i<=num;i++) { for(j=1;j<=num;j++) { temp[i][j]=(r[i][j])||(r[i][k]&r[k][j]); } } for(i=1;i<=num;i++) for(j=1;j<=num;j++) r[i][j]=temp[i][j]; }}
5、结果如下:
6、参考文献
(1)算法导论
(2)数据结构 严蔚敏
阅读全文
0 0
- Warshall传递闭包算法的学习与实现
- Warshall传递闭包算法的学习与实现
- 传递闭包的warshall算法
- Warshall 传递闭包算法
- Warshall传递闭包算法
- 【离散数学】Warshall算法实现 传递闭包对应矩阵
- 求传递闭包Warshall算法代码实现
- 传递闭包计算warshall算法C语言实现
- Floyd-Warshall算法求矩阵的传递闭包
- Warshall算法求传递闭包
- Floyd-Warshall算法(传递闭包)
- WarShall算法--图的传递闭包(进一步演变成flayd算法)
- 任意两点最短路 Floyd-Warshall算法 传递闭包
- 关系传递闭包Warshall算法之思想的一种解说
- 图的多源点最短路问题和传递闭包之Floyd-Warshall算法 By ACReaper
- Warshall 算法的c++实现
- Floyd-Warshall方法求有向图的传递闭包
- Floyd-Warshall方法求有向图的传递闭包 收藏
- Java 控制流
- JSCore的基本使用====
- linux社区工作经验总结
- vim-manual学习
- 深度学习word2vec笔记之基础篇算法篇应用篇--写的非常到位
- Warshall传递闭包算法的学习与实现
- QT中设置QTreeWidget某一列可编辑
- 重置密码逻辑
- P1019 单词接龙
- Qt文件封包
- WebView加载H5界面后的返回键问题
- 表分区
- 统计学习方法-学习总结
- 学习java必知的概念