离散数学关系的闭包运算
- 格式:doc
- 大小:68.50 KB
- 文档页数:6
离散数学如何求r的传递闭包离散数学的传递闭包是指在一个关系 R 上,通过不断地迭代是否存在一些元素关系可以联通,扩展出一个新的关系闭包集合,使得 R 中任何两个元素之间都存在一条路径。
其中,R 是原始关系,而 R 的传递闭包是所有可以从 R 中的元素得到的路径的集合。
传递闭包是在关系上的一个重要属性,因为它可以表示元素之间的隐含关系,从而有助于更详细地分析和描述数据。
计算 R 的传递闭包有多种方法,其中最经典的是 Warshall 算法。
下面是使用Warshall 算法计算 R 的传递闭包的步骤。
1)建立一个大小为n × n 的布尔矩阵 T,其中 T[i][j] 表示从 i 到 j 是否存在一条路径。
2)将布尔矩阵 T 的初始值设置为 R 的布尔矩阵。
3)进行 n 次迭代,每次迭代更新布尔矩阵 T 的值。
具体地,对于 T 中的每一个元素 T[i][j],如果存在一个 k 使得 T[i][k] 和 T[k][j] 均为 true,则将 T[i][j] 设为 true。
4)最终的 T 就是 R 的传递闭包。
下面是 Warshall 算法的详细代码实现:```int[][] transitiveClosure(int[][] R) {int n = R.length;int[][] T = new int[n][n];// 初始化 T 为 R 的布尔矩阵for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (R[i][j] == 1) {T[i][j] = 1;}}}// 根据 Warshall 算法进行迭代for (int k = 0; k < n; k++) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {T[i][j] |= (T[i][k] & T[k][j]);}}}return T;}```该算法的时间复杂度为 O(n^3),其中 n 是 R 的大小。
离散数学传递闭包求法一、引言离散数学是计算机科学中的重要分支,它研究离散对象及其关系的数学理论。
其中,传递闭包是离散数学中的一个重要概念,它在图论、关系代数等领域有着广泛的应用。
本文将介绍传递闭包的求法,以及其在实际应用中的作用。
二、传递闭包的定义传递闭包是指在一个关系上,若存在从一个元素到另一个元素的路径,则这两个元素之间存在传递关系。
传递闭包就是将这些传递关系全部加入到原有关系中所得到的新关系。
例如,若关系R={(1,2),(2,3)},则其传递闭包为R*={(1,2),(2,3),(1,3)}。
三、传递闭包的求法1. Warshall算法Warshall算法是一种经典的传递闭包求法,其基本思想是利用矩阵乘法的性质,通过多次迭代来求得传递闭包。
具体步骤如下:(1)初始化矩阵T为原有关系矩阵R;(2)对于矩阵T中的每一个元素T[i][j],若存在T[i][k]和T[k][j]均为1,则将T[i][j]置为1;(3)重复执行步骤(2),直到矩阵T不再发生变化。
最终得到的矩阵T即为原有关系R的传递闭包。
2. Floyd算法Floyd算法也是一种常用的传递闭包求法,其基本思想是通过多次迭代来求得传递闭包。
具体步骤如下:(1)初始化矩阵T为原有关系矩阵R;(2)对于矩阵T中的每一个元素T[i][j],若存在T[i][k]和T[k][j]均为1,则将T[i][j]置为1;(3)重复执行步骤(2),直到矩阵T不再发生变化。
最终得到的矩阵T即为原有关系R的传递闭包。
四、传递闭包的应用传递闭包在实际应用中有着广泛的应用,例如:1. 图论中的可达性分析:通过求解传递闭包,可以判断图中任意两个节点之间是否存在路径,从而进行可达性分析。
2. 关系代数中的等价类划分:通过求解传递闭包,可以将原有关系划分为若干个等价类,从而进行等价类划分。
3. 数据库中的关系查询:通过求解传递闭包,可以进行关系查询,例如查询某个节点的所有后继节点。
一、实验目的1. 理解闭包运算的概念及其在离散数学中的应用。
2. 掌握关系闭包运算(自反闭包、对称闭包、传递闭包)的求解方法。
3. 利用编程语言实现关系闭包运算,并分析实验结果。
二、实验内容1. 自反闭包运算:给定一个关系R,求出R的自反闭包R^。
2. 对称闭包运算:给定一个关系R,求出R的对称闭包R^s。
3. 传递闭包运算:给定一个关系R,求出R的传递闭包R^t。
三、实验环境1. 操作系统:Windows 102. 编程语言:Python3.73. 开发工具:PyCharm四、实验步骤1. 定义关系R:以矩阵形式表示关系R,其中R[i][j]表示元素i和元素j之间的关系,1表示存在关系,0表示不存在关系。
2. 求自反闭包R^:a. 初始化一个与R同样大小的矩阵R^。
b. 遍历R^,对于每个元素R^[i][j],若R[i][j]=1或i=j,则R^[i][j]=1。
3. 求对称闭包R^s:a. 初始化一个与R同样大小的矩阵R^s。
b. 遍历R,对于每个元素R[i][j],若R[i][j]=1,则R^[i][j]=1且R^[j][i]=1。
c. 遍历R^s,对于每个元素R^[i][j],若R^[i][j]=1,则R^[j][i]=1。
4. 求传递闭包R^t:a. 初始化一个与R同样大小的矩阵R^t。
b. 遍历R,对于每个元素R[i][j],若R[i][j]=1,则R^[i][j]=1。
c. 循环执行以下步骤,直到R^t不再变化:i. 遍历R^t,对于每个元素R^[i][j],若R^[i][k]=1且R^[k][j]=1,则R^[i][j]=1。
五、实验结果与分析1. 自反闭包运算:给定关系R如下:0 1 01 0 10 1 0求自反闭包R^,结果如下:1 1 11 1 11 1 12. 对称闭包运算:给定关系R如下:0 1 01 0 10 1 0求对称闭包R^s,结果如下:1 1 11 1 11 1 13. 传递闭包运算:给定关系R如下:0 1 01 0 10 1 0求传递闭包R^t,结果如下:1 1 11 1 11 1 1通过实验,我们可以发现:1. 自反闭包运算使得关系R中的所有元素都与自身存在关系。
离散数学闭包求法一、闭包的概念在离散数学中,闭包是指从一个给定的集合中生成一个更大的集合的过程。
闭包的目的是为了将原始集合中的元素与其他元素进行组合,以生成一个包含所有可能组合的新集合。
闭包操作可以用来补充原始集合中缺失的元素,或者生成满足某种条件的元素。
二、闭包的分类根据不同的应用领域和问题要求,闭包可以分为几种不同的类型,包括传递闭包、反对称闭包、自反闭包等。
1. 传递闭包:传递闭包是指在一个关系集合中,通过迭代地应用传递规则,生成一个包含所有相关元素的新集合。
传递闭包可以帮助我们分析集合之间的关系,例如在图论中,通过计算传递闭包可以确定两个节点之间是否存在路径。
2. 反对称闭包:反对称闭包是指在一个关系集合中,通过添加一些额外的元素,使得原始关系对称的元素对被移除。
反对称闭包可以帮助我们分析集合中的对称关系,例如在关系代数中,通过计算反对称闭包可以确定两个元素是否存在对称关系。
3. 自反闭包:自反闭包是指在一个关系集合中,通过添加一些额外的元素,使得原始关系中所有元素都与自身存在关系。
自反闭包可以帮助我们分析集合中的自反关系,例如在关系代数中,通过计算自反闭包可以确定一个元素是否与自身存在某种关系。
三、闭包的求解方法根据不同的闭包类型,可以使用不同的求解方法来计算闭包。
下面将介绍几种常见的求解方法。
1. 传递闭包的求解方法:传递闭包可以通过迭代地应用传递规则来计算。
具体步骤如下:(1)初始化闭包集合为原始关系集合。
(2)重复以下步骤,直到闭包集合不再变化:a. 对于每对元素(a, b)和(b, c),如果(a, c)不在闭包集合中,则将(a, c)添加到闭包集合中。
(3)输出闭包集合。
2. 反对称闭包的求解方法:反对称闭包可以通过移除对称的元素对来计算。
具体步骤如下:(1)初始化闭包集合为原始关系集合。
(2)对于每对元素(a, b),如果(b, a)也在闭包集合中,则将(b, a)从闭包集合中移除。
《离散数学》
实验报告
学院软件学院
专业软件工程
指导教师邹丽娜
学号********
姓名冯立勇
提交日期2011-12-25
实验二 关系的闭包运算
一 、实验目的
熟悉关系的闭包运算,编程实现关系闭包运算算法。
一 、实验内容
利用矩阵求解有限集上给定关系的自反、对称和传递闭包。
三. 实验过程
1. 算法分析:
在三种闭包中自反和对称闭包的求解很容易,对矩阵表示的关系,其自反闭包只要将矩阵的主对角线全部置为1就可;对称闭包则加上关系的转置矩阵(逻辑加法);传递闭包则有两种算法(二选一即可):
算法1:直接根据 n i i R
R t 1)(==计算,过程略。
算法2:Warshall 算法(1962)
设R 的关系矩阵为M
(1)令矩阵A=M
(2)置i=1
(3)对所有的j ,若A[j ,i]=1,则
对于 k=1,2,…,n ,令A[j ,k]=A[j ,k]+A[i ,k]
注:此处为逻辑加,可以使用运算符||
(4) i=i+l .
(5)若i ≤n ,则转到(3),否则结束.
流程图
2. 程序代码:
#include<stdio.h>
void output(int s[][100]);
void zifan(int s2[][100]);
void duichen(int s2[][100]);
void chuandi2(int s2[][100]);
void chuandi1(int s2[][100]);
void aa();
int s[100][100],z;
int d,n ,i,j;
int main(){aa();return 0;}
void aa()
{
printf("请输入矩阵的行数(必须小于10)\n ");
scanf("%d",&n);
printf("请输入矩阵的列数(必须小于10)\n ");
scanf("%d",&d);
printf("请输入关系矩阵\n");
for(i=0;i<n;i++)
{ printf("\n");
printf("请输入矩阵的第%d行元素",i);
for(j=0;j<d;j++)
scanf("%d",&s[i][j]);
}
printf("输入对应序号选择算法\n1:自反闭包\n2:传递闭包1\n3:传递闭包(Warhall算法)2\n4:对称闭包\n");
scanf("%d",&z);
switch(z)
{
case 1:zifan(s); break;
case 2:chuandi1(s);break;
case 3:chuandi2(s);break;
case 4:duichen(s); break;
}
}
void output(int s[][100])
{printf("所求关系矩阵为\n"); for(i=0;i<n;i++)
{for(j=0;j<d;j++)
printf("%d",s[i][j]);
printf("\n");
}
}
void zifan(int s2[][100])
{
for(i=0;i<n;i++)
s2[i][i]=1;
output(s2);aa();
}
void duichen(int s2[][100])
{int s1[100][100];
for(i=0;i<n;i++)
for(j=0;j<d;j++)
s1[j][i]=s2[i][j];
for(i=0;i<n;i++)
for(j=0;j<d;j++)
{s2[i][j]=s2[i][j]+s1[i][j];
if(s2[i][j]>1)
s2[i][j]=1;
}
output(s2);
aa();
}
void chuandi1(int s2[][100]) {int m[100][100],a[100][100],k,h; int t[100][100];
for(i=0;i<n;i++)
for(j=0;j<d;j++)
{ a[i][j]=0;
t[i][j]=s2[i][j];
m[i][j]=s2[i][j];}
for(h=0;h<n;h++)
{for(i=0;i<n;i++)
for(j=0;j<d;j++)
if(m[i][j]==1)
{for(k=0;k<n;k++)
if(s2[j][k]==1)
a[i][k]=1;
}
for(i=0;i<n;i++)
for(j=0;j<d;j++)
{ m[i][j]=a[i][j];
t[i][j]+=a[i][j];
a[i][j]=0;
if(t[i][j]>1)
t[i][j]=1;
}
}
output(t);aa();
}
void chuandi2(int s2[][100]) {int k;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(s2[j][i]==1)
for(k=0;k<n;k++) s2[j][k]+=s2[i][k];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(s2[i][j]>1)
s2[i][j]=1;
output(s2);aa();
}
3.实验数据及结果分析。