目录
1.传递闭包的概念
通俗的说就是,当我们定义了一个关系R是传递的,一切满足这个R的结果集合
例如:我有一个具有传递性的R集合{(1,2),(1,3),(2,4),(4,1),(2,3)},假设这个传递关系是X,1与2有X,2与4有X,那1与4有X,依次把所有的关系找出来,结果就是R的传递闭包{(1,1),(1,2),(1,3),(1,4),(2,1),(2,3),(2,4),(4,1),(4,2),(4,3),(4,4)}
2.warshall算法求传递闭包步骤
设我们要求A这个n阶方阵的传递闭包
数学公式:R(传递闭包)=A(一阶矩阵)+A^2(二阶)+A^3(三阶)+…+A^n(n阶)
(注意,这里的+是逻辑运算中的析取运算)
1.设矩阵 A=R;
2.设i=1;
3.对所有j(1,2,3...,n),如果A[j,i]=1,那么对于k=1,2,...,n。A[j,k]+A[i,k]=A[j,k];
4.i加1;
5.i<=n,循环3)的步骤;不满足则结束。
3.C语言实现
用4*4的数组举例吧
#include <stdio.h>
#define ROW 4
#define COL 4
void warshall(int arr[ROW][COL], int row, int col) //warshall算法函数实现
{
int i = 0;
int j = 0;
int k = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[j][i] == 1)
{
for (k = 0; k < col; k++)
{
arr[j][k] = (arr[j][k] || arr[i][k]);
}
}
}
}
}
void print(int arr[ROW][COL], int row, int col) //用表的形式呈现数组的函数
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[ROW][COL] = { {0,1,0,1},{0,1,1,0},{0,0,0,0},{1,0,1,1} }; //1.定义一个4*4数组
print(arr, 4, 4); //2.用表的形式呈现之前的数组的函数
printf("\n"); //3.分一下行,跟后面要呈现的数组分开
warshall(arr, 4, 4); //4.warshall算法函数实现
print(arr, 4, 4); //5.打印实现算法后的数组
return 0;
}
最后的结果演示: