Warshall算法 (解决传递闭包问题)
目录
- 1 传递闭包
- 2 求关系的传递闭包可以采用矩阵的表示方法
- 3 实例
1 传递闭包
对于任何关系 R ,R 的传递闭包总是存在的。传递关系的任何家族的交集也是传递的, R 传递闭包给出自包含 R 的所有传递关系的交集。Warshall 算法可以计算一个布尔邻接矩阵的传递闭包。
2 求关系的传递闭包可以采用矩阵的表示方法
设 A = {x1x_1x1,x2x_2x2,…,xnx_nxn},R 为 A 上的二元关系,R 的关系矩阵为 M,那么传递闭包矩阵 M′=M+M2+...+MnM'=M+M^2+...+M^nM′=M+M2+...+Mn
(因为在 R 的关系图中,从顶点 xix_ixi 到 xjx_jxj 且不含回路的路径最多有 n 步长)
手工计算关系的传递闭包,需要不断地计算矩阵M2=M×M,M3=M2×M,......M^2=M×M,M^3=M^2×M,......M2=M×M,M3=M2×M,......
直到找到一定的规律(此处的×表示矩阵的乘法)。倘若遇到维度较大的矩阵,计算起来会十分复杂繁琐,因此我们需要借助计算机的帮助,为我们解决数学问题。
3 实例
接下来,我们通过一个实例说明。如下是一个关系图:
其邻接矩阵 M 为:
[0001111000100010]\begin{bmatrix} 0&0&0&1\\ 1&1&1&0\\ 0&0&1&0\\ 0&0&1&0\\ \end{bmatrix}⎣⎡0100010001111000⎦⎤
经过计算,其传递闭包的矩阵 M’ 为:
[0011111100100010]\begin{bmatrix} 0&0&1&1\\ 1&1&1&1\\ 0&0&1&0\\ 0&0&1&0\\ \end{bmatrix}⎣⎡0100010011111100⎦⎤
现在我们通过代码 C++/Python 来得到 M’ ,代码输出的矩阵即为 M’ 。
算法代码(C++):
#include <iostream>
using namespace std;
int M[100][100] = {0}; //全局变量
int N;int input(){ //输入矩阵M cout<<"please input the matrix's dimention:" ; //输入矩阵维度 cin >> N;cout<<"please input the matrix:"<<endl; //输入矩阵 for(int a = 0; a < N; a++){for(int b = 0; b < N; b++){cin >> M[a][b];if(M[a][b] !=0 && M[a][b] !=1) //报错,矩阵元素只能是0或1 cout<<"error,the elements of the matrix have to be 0 or 1.";}}return 0;
}int output(){ //输出传递闭包矩阵 for(int a = 0; a < N; a++){for(int b = 0; b < N; b++){cout << M[a][b] << " ";} cout << endl;}
}int warshall(){ //沃舍尔算法 for (int i = 0;i < N;i++) { for (int j = 0;j < N;j++) {if (M[j][i]) //如果M[j][i]=1, M[j][k]<--M[j][k] V M[i][k]{for (int k = 0;k < N;k++) {M[j][k] = M[j][k] | M[i][k];//逻辑加 }}}}
}int main()
{input();warshall();cout<<"output the matrix:"<<endl;output();return 0;
}
运行效果为:
算法代码(Python):
import numpy as np #numpy库
import copy #copy库
R = np.array([[0,0,0,1],[1,1,1,0],[0,0,1,0],[0,0,1,0]]) #输入二维数组
M = copy.deepcopy(R) #deepcopy(深度复制)复制的变量完全独立,若是copy()即浅复制
for i in range(4): #warshall算法for j in range(4):if M[j,i]==1:for k in range(4):M[j,k] = M[j,k] or M[i,k]
print(M)
运行效果为:
由算法可知,其时间复杂度为 O(n3)O(n^3)O(n3)
优点:容易理解,代码编写简单。
缺点:时间复杂度比较高,不适合计算大量数据。
Warshall算法 (解决传递闭包问题)相关推荐
- C语言用warshall算法求传递闭包transitive closure(附完整源码)
用warshall算法求传递闭包transitive closure warshall算法求传递闭包完整源码 warshall算法求传递闭包完整源码 #include <stdbool.h> ...
- WarShall算法求传递闭包(可达矩阵)
最近在复习离散数学,顺便记录记录自己对warshall算法的理解. 1.传递闭包(可达矩阵) 传递闭包是有向图的一个重要性质,它指的是在有向图中从任意一个节点出发,可以到达的所有节点的集合.在某些应用 ...
- Warshall 算法(离散数学传递闭包)
Warshall 算法 算法思路: (1)先初始化一个二维数组 (2)利用循环输入N*N的矩阵 (3)进行矩阵的运算 M0的第0列的1和第0行进行逻辑加.比如[1,0]+[0,1]=[1,1]=1 M ...
- warshall算法求传递闭包c++_【建模小课堂】图论算法
图论算法 图论算法在计算机科学中扮演着很重要的角色,它提供了对很多问题都有效的一种简单而系统的建模方式.很多问题都可以转化为图论问题,然后用图论的基本算法加以解决.这类问题算法主要包括Dijkstra ...
- WarShall算法求矩阵传递闭包关系
离散知识 给了你一个矩阵,你如何求他的传递闭包呢? //求出如下矩阵的传递闭包 1 0 1 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 利用WarShall ...
- Warshall算法求有向图的传递闭包
1定义是这样给出的,传递闭包:对于任何关系 R,R 的传递闭包总是存在的.传递关系的任何家族的交集也是传递的.进一步的,至少存在一个包含 R 的传递关系,也就是平凡的: X × X.R 传递闭包给出自 ...
- 离散数学 传递闭包 Warshall算法
老师布置一个作业,要写Warshall算法课后,这里给写出来了. 这个算法本身很简单,倒是学习了一下参数为二维数组的传递方法,正确代码如下: /* Warshall算法 */ #include < ...
- War-shall 算法 【求传递闭包】 离散数学记录
学离散数学时遇到到第一个算法,记录一下: 代码思路: warshall(A[1...n,1...n] r(0)<-A; for(k=1;k<=n;k++)for(i=1;i<=n;i ...
- 基于Warshall算法的连通图及欧拉图判定方法
1736年欧拉解决了哥尼斯堡七桥问题.他在这一具体问题的基础上进一步研究,最终找到了一个简便的原则可以鉴别一个图(多重图)能否一笔画成. 本文中,笔者使用布尔矩阵来存储一个无向图,并结合集合论中&qu ...
- Warshall算法(用法详解,并转换成代码的形式)
关于Warshall算法,我先通过离散数学中求传递闭包来解释他的使用规则. 一般的,给定一个矩阵A(行列相等),我们对其使用Warshall算法: //注,该矩阵上只有0或1两种元素,做加法时,1+1 ...
最新文章
- python bottle框架 运维_python bottle框架(WEB开发、运维开发)教程 | linux系统运维...
- jQuery弹出框示例
- Oracle 常用命令举例
- 使用DOM动态创建标签
- virsh 基于xml create VMs虚机
- MFC资源切换(AFX_MANAGE_STATE)简介
- Matlab查看像素坐标
- fewX(fsod)的预测代码编写--detectron2框架的一般见解(1)
- ISCSI 客户端远程挂载块设备卡住
- chrome浏览器的跨域问题解决
- 卡内基梅隆的计算机科学专业,卡内基梅隆大学计算机科学专业
- Python爬取网页图片
- mysql idb 恢复_mysql靠idb文件恢复数据
- 智遥工作流是如何模拟并优化办公单据审批的
- echarts按照时间显示柱状图_Echarts制作时间柱形离散分布图
- 淘宝/天猫API接口,item_sku - 淘宝商品SKU详细信息查询,淘宝/天猫获取sku详细信息 API 返回值说明
- 2021南京大学计算机考研分数线,2021年南京大学考研分数线公布
- 江苏省赛 JSCPC2018 K. 2018
- 常用的手机宽度 前端切图用 常用的手机尺寸
- 面向未来,镭速助力企业构建文件安全外发新生态