闭包运算实验报告1
传递闭包实验报告

一、实验目的1. 理解传递闭包的概念及其在图论中的应用。
2. 掌握利用Floyd-Warshall算法求解传递闭包的方法。
3. 通过编程实现传递闭包的计算,验证算法的正确性。
4. 分析实验结果,加深对传递闭包性质的理解。
二、实验原理传递闭包是指在给定集合X上的二元关系R,找到一个最小的传递关系R,使得对于任意的x, y, z∈X,若xRy且yRz,则xRz成立。
传递闭包可以用来描述图中节点之间的可达性,是图论中一个重要的概念。
Floyd-Warshall算法是一种求解传递闭包的经典算法,它通过构建一个n×n的邻接矩阵A,其中A[i][j]表示节点i到节点j的可达性。
算法的基本思想是:逐步更新矩阵A,使得A[i][j]的值表示节点i到节点j的最短路径可达性。
三、实验内容1. 设计一个图,包括节点和边,并构建相应的邻接矩阵。
2. 利用Floyd-Warshall算法计算邻接矩阵的传递闭包。
3. 分析传递闭包的结果,验证算法的正确性。
4. 对比不同图结构下的传递闭包计算结果,探讨传递闭包的性质。
四、实验步骤1. 设计一个图,包括5个节点和6条边,如下所示:```1 -- 2| || |3 -- 4| || |5 -- 6```2. 构建邻接矩阵A,如下所示:```| 1 2 3 4 5 6 |1| 0 1 0 0 0 0 |2| 0 0 1 0 0 0 |3| 0 0 0 1 0 0 |4| 0 0 0 0 1 0 |5| 0 0 0 0 0 1 |6| 0 0 0 0 0 0 |```3. 编写Floyd-Warshall算法的代码,计算传递闭包。
```pythondef floyd_warshall(adj_matrix):n = len(adj_matrix)for k in range(n):for i in range(n):for j in range(n):if adj_matrix[i][j] > adj_matrix[i][k] + adj_matrix[k][j]:adj_matrix[i][j] = adj_matrix[i][k] + adj_matrix[k][j]return adj_matrix# 初始化邻接矩阵adj_matrix = [[0, 1, 0, 0, 0, 0],[0, 0, 1, 0, 0, 0],[0, 0, 0, 1, 0, 0],[0, 0, 0, 0, 1, 0],[0, 0, 0, 0, 0, 1],[0, 0, 0, 0, 0, 0]]# 计算传递闭包transitive_closure = floyd_warshall(adj_matrix) print(transitive_closure)```4. 分析传递闭包的结果,验证算法的正确性。
离散数学实验报告

“离散数学”实验报告目录一、实验目的 (3)二、实验内容 (3)三、实验环境 (3)四、实验原理和实现过程(算法描述) (3)1、实验原理........................................................................................................2、实验过程.......................................................................................................五、实验数据及结果分析 (13)六、源程序清单 (24)源代码 (24)七、其他收获及体会 (45)一、实验目的实验一:熟悉掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。
实验二:掌握关系的概念与性质,基本的关系运算,关系的各种闭包的求法。
理解等价类的概念,掌握等价类的求解方法。
实验三:理解图论的基本概念,图的矩阵表示,图的连通性,图的遍历,以及求图的连通支方法。
二、实验内容实验一:1. 从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值。
(A)2. 求任意一个命题公式的真值表(B,并根据真值表求主范式(C))实验二:1.求有限集上给定关系的自反、对称和传递闭包。
(有两种求解方法,只做一种为A,两种都做为B)2. 求有限集上等价关系的数目。
(有两种求解方法,只做一种为A,两种都做为B)3. 求解商集,输入集合和等价关系,求相应的商集。
(C)实验三:以偶对的形式输入一个无向简单图的边,建立该图的邻接矩阵,判断图是否连通(A)。
并计算任意两个结点间的距离(B)。
对不连通的图输出其各个连通支(C)。
三、实验环境C或C++语言编程环境实现。
四、实验原理和实现过程(算法描述)实验一:1.实验原理(1)合取:二元命题联结词。
实验一 三元闭包现象的数据验证

实验一:三元闭包现象的数据验证•快照一:{(1,2), (1,6), (1,7), (2,3), (2,6), (3,6), (3,7), (4,5), (4,7), (5,6), (6,7)}•快照二:{(1,2), (1,3), (1,6), (1,7), (2,3), (2,5), (2,6), (3,6), (3,7), (4,5), (4,6), (4,7), (5,6), (5,7), (6,7)}•快照三:{(1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (2,3), (2,5), (2,6), (2,7), (3,5), (3,6), (3,7), (4,5), (4,6), (4,7), (5,6), (5,7), (6,7)}•你的任务是:给出这些数据反映出的两个当前不是朋友的人的“共同朋友个数”与“在下一快照中成为朋友的概率”之间的关系。
•计算“共同朋友个数”(邻接矩阵的相乘)•0 1 1 0 1 0 0 1 1 0 1 0 3 0 0 2 0 3• 1 0 0 1 0 1 1 0 0 1 0 1 0 3 2 0 3 0• 1 0 0 0 0 1 * 1 0 0 0 0 1 = 0 2 2 0 2 0•0 1 0 0 1 0 * 0 1 0 0 1 0 = 2 0 0 2 0 2• 1 0 0 1 0 1 1 0 0 1 0 1 0 3 2 0 3 0•0 1 1 0 1 0 0 1 1 0 1 0 3 0 0 2 0 3•输入:T时刻和T+1时刻n个人之间朋友关系快照(图表示)输出:1)给出反映出的两个当前不是朋友的人的“共同朋友个数”与“在下一快照中成为朋友的概率”之间的关系。
√2)T时刻和T+1时刻的每个人的聚集系数√节点A的聚集系数= A的任意两个朋友之间也是朋友的概率(即邻居间朋友对的个数除以总对数)3)T时刻和T+1时刻的每条边的介数介数:一条边承载的一种“流量”两个节点A和B,设想1个单位的流量从A到B,均分到它们之间所有的最短路径上K条最短路径,则每条路径上分得1/k,若一条边被m条路径共用,则在它上面流过m/k所有节点对都考虑后,一条边上的累记流量就是它的介数(betweenness)介数计算的一种算法从一个节点(A)开始,做广度优先搜索,将节点分层(以便于下面的步骤)两个矩阵树状图矩阵边介质矩阵;路得条数n确定从A到其他每个节点的最短路径的条数确定当从节点A沿最短路径向其他所有节点发送1个单位流量时,经过每条边的流量。
离散实验报告

离散实验报告专业:数学与应用数学班级:091121学号:2009112125姓名:张鼎珩日期:2011.06.23实验内容:实验一真值计算实验二两个集合运算实验三关系闭包计算实验四关系与函数进行试验:实验一真值计算一、实验目的熟悉联结词合取、析取、条件和双条件的概念,编程求其真值。
二、实验内容(1)求任意一个命题公式的真值表:从键盘输入两个命题P 和Q的真值,求它们的合取、析取、蕴含和等价的真值(2)利用真值表求任意一个命题公式的主范式(3)利用真值表进行逻辑推理三实验程序:#include<stdio.h>/*标准输入输出头文件*/#include<stdlib.h>/*该文件包含了的C语言标准库函数的定义*/#include<string.h>/*字符串数组的函数定义的头文件*/#include<conio.h>/*通用输入输出库*/#include<math.h>#define N 50void jisuan();void zhenzhibiao();void panduan(int b[N],int f);int tkh (char sz[N], char ccu[N], int icu[N], int h0);int fkh (char sz[N], char ccu[N], int icu[N], int h0);main(){int a1;start:do{printf(" 1.求P、Q的合取、析取、条件和双条件的真值\n 2.求任意一个命题公式的真值表,并根据真值表求主范式\n 3.退出\n");printf("\n选择功能选项:");fflush(stdin);/*清空输入缓冲区,通常是为了确保不影响后面的数据读取*/scanf("%d",&a1);switch(a1)/*switch语句实现选择功能*/{case 1:system("cls");jisuan();break;/*功能A*/case 2:system("cls");fflush(stdin);zhenzhibiao();break;/*功能BC*/case 3:system("exit");exit(0);/*结束整个程序的运行*/default:system("cls");goto start;/*控制流转移到start处*/}}while(1);}void jisuan()/*功能A*/{char p,q,t,ch;int p1,q1;do{start:fflush(stdin);printf("请输入P和Q的真值(T或F):");scanf("%c,%c",&p,&q);if((p=='F'||p=='f'||p=='T'||p=='t')&&(q=='F'||q=='f'||q=='T'||q=='t')){if(p=='F'||p=='f')/*赋值*/p1=0;elsep1=1;if(q=='F'||q=='f')q1=0;elseq1=1;if(p1|q1)/*计算*/t='T';elset='F';printf("P析取Q为:%c\n",t);if(p1&q1)t='T';elset='F';printf("P和取Q为:%c\n",t);if((!p1)|q1)t='T';elset='F';printf("P条件Q为:%c\n",t);if(p1==q1)t='T';elset='F';printf("P双条件Q为:%c\n",t);}else{printf("请按正确格式输入!\n");goto start;};printf("是否继续输入?Y/N");fflush(stdin);ch=getch();system("cls");}while(ch!='n'&&ch!='N');}void zhenzhibiao()/*功能BC*/{int i1,i2,d=1,icu[N],kh=0,jg,j=0,h0;int bj=0,hq[N],h=0,x=0,xq[N];char sz[N],ccu[N],sz0[N];hq[0]=-1;xq[0]=-1;printf("请输入一个合法的命题公式(可含与或非及括号):\n");gets(sz);strcpy(sz0,sz);for(i1=0;i1<strlen(sz);i1++){if(sz[i1]==')' || sz[i1]=='(')kh++;if(sz[i1]>='a' && sz[i1]<='z' || sz[i1]>='A' && sz[i1]<='Z'){for(i2=0;i2<j;i2++) /*判断并储存变量*/if(ccu[i2]==sz[i1])d=0;if(d==1){ccu[j]=sz[i1];j++;}d=1;}}printf("\n该式子中的变量个数为:%d\n",j);h0=j;printf("\n输出真值表如下:\n \n");for(i1=0;i1<h0;i1++)printf(" %c ",ccu[i1]);printf(" ");puts(sz);printf("\n");for(i1=0;i1<j;i1++) /*先将所有的变量赋值为零*/icu[i1]=0;for(i2=0;i2<j;i2++)printf(" %d ",icu[i2]);jg=tkh(sz,ccu,icu,h0);if(jg==0)hq[h++]=bj;elsexq[x++]=bj;printf(" ------> %d\n",jg);strcpy(sz,sz0);for(i1=0;i1<(int)pow(2,j)-1;i1++){++bj;panduan(icu,0); /*赋值变量*/jg=tkh(sz,ccu,icu,h0);if(jg==0)hq[h++]=bj;elsexq[x++]=bj;strcpy(sz,sz0); /*恢复被修改的数组*/for(i2=0;i2<j;i2++)printf(" %d ",icu[i2]);printf(" ------> %d\n",jg);}if(hq[0]==-1)printf("\n该命题公式不存在主合取范式。
闭包运算的实验报告

一、实验目的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中的所有元素都与自身存在关系。
离散数学试验报告

学院理学院学生姓名 xxx学号 xxxxxxxxxxx实验:编程二元关系的传递性判别,二元关系闭包方法一.前言引语:二元关系是离散数学中重要的内容。
因为事物之间总是可以根据需要确定相应的关系。
从数学的角度来看,这类联系就是某个集合中元素之间存在的关系。
二.数学原理:1.传递关系:对任意的x,y,z∈A,如果<x,y>∈R且<y,z>∈R,那么<x,z>∈R,则称关系R是传递的,或称R具有传递性,即R在A上是传递的⇔ (∀x)(∀y)(∀z)[(x ∈A)∧(y∈A)∧(z∈A)∧((<x,y>∈R)∧(<y,z>∈R)→(<x,z>∈R))]=12.自反闭包、对称闭包、传递闭包:设R是定义在A上的二元关系,若存在A 上的关系R′满足:1)R′是自反的(或对称的、或可传递的),2)R⊆ R′,3)对A上任何其它满足1)和2)的关系R〞,都有:R′⊆R〞。
则称R′为R的自反闭包(或对称闭包、或传递闭包),分别记为r(R)、(s(R)和t(R))。
三.实验编程语言:c++四.实验程序源代码:#include<iostream>using namespace std;int cdx(int a[100][100],int n){int b[100][100],i,j;for(i=1;i<=n-1;i++){for(j=1;j<=n;j++){if(a[1][j]==a[i+1][j] && a[1][j]==0)b[i][j]=0;elseb[i][j]=1;}for(j=1;j<=n;j++){if(b[i][j]!=a[1][j])return 0;}}return 1;}void zfbb(int a[100][100],int n){int i,j;for(j=1;j<=n;j++){for(i=1;i<=n;i++){if(a[i][j]==1){a[i][i]=1;a[j][j]=1;}}}cout<<"自Á?反¤¡ä闭À?包㨹关?系¦Ì矩?阵¨®为a:êo"<<endl;for(i=1;i<=n;i++){for(j=1;j<=n;j++){if(a[i][j]>1){a[i][j]=1;cout<<a[i][j]<<" ";}else{cout<<a[i][j]<<" ";}}cout<<""<<endl;}}void dcbb(int a[100][100],int n){int i,j;for(j=1;j<=n;j++){for(i=1;i<=n;i++){if(a[i][j]==1){a[j][i]=1;}}}cout<<"对?称?闭À?包㨹关?系¦Ì矩?阵¨®为a:êo"<<endl;for(i=1;i<=n;i++){for(j=1;j<=n;j++){if(a[i][j]>1){a[i][j]=1;cout<<a[i][j]<<" ";}else{cout<<a[i][j]<<" ";}}cout<<""<<endl;}}void cdbb(int a[100][100],int n){int i,j,k;for(j=1;j<=n;j++){for(i=1;i<=n;i++){if(a[i][j]==1){for(k=1;k<=n;k++){a[i][k]=a[i][k]+a[j][k];}}}}cout<<"传ä?递ÌY闭À?包㨹关?系¦Ì矩?阵¨®为a:êo"<<endl;for(i=1;i<=n;i++){for(j=1;j<=n;j++){if(a[i][j]>1){a[i][j]=1;cout<<a[i][j]<<" ";}else{cout<<a[i][j]<<" ";}}cout<<""<<endl;}}void main(){int i,j,n,a[100][100],sel,ins;cout<<"请?输º?入¨?二t元a关?系¦Ì矩?阵¨®维?数ºyn"<<endl;cin>>n;cout<<"请?按ã¡äa[1,1],a[1,2]...a[1,n],a[2,1]...a[n.n]的Ì?顺3序¨©输º?入¨?关?系¦Ì矩?阵¨®的Ì?元a素?值¦Ì(ê¡§0,ê?1)ê?"<<endl;for(i=1;i<=n;i++)for(j=1;j<=n;j++){cin>>a[i][j];}INDEX:cout<<"请?输º?入¨?要©a判D定¡§的Ì?性?质¨º:êo"<<endl;cout<<"1、¡é传ä?递ÌY性?"<<endl;cout<<"2、¡é自Á?反¤¡ä闭À?包㨹"<<endl;cout<<"3、¡é对?称?闭À?包㨹"<<endl;cout<<"4、¡é传ä?递ÌY闭À?包㨹"<<endl;cout<<"5、¡é退ª?出?"<<endl;cin>>sel;if(sel==1){ins=cdx(a,n);if(ins==0)cout<<"该?二t元a关?系¦Ì不?具?有®D传ä?递ÌY性?。
实验一传递闭包的实现

实验一传递闭包的实现实验一:传递闭包的实现摘要:本实验通过使用离散数学中的传递闭包的概念,设计了一种算法来实现传递闭包的计算。
实验首先介绍了传递闭包的定义和性质,然后详细描述了实现算法的步骤。
接着,通过编程语言来实现算法,并使用一个具体的例子进行了测试。
最后,对实验结果进行了分析和总结,验证了算法的正确性和有效性。
1.引言在离散数学中,传递闭包是一个重要的概念,它在关系理论以及图论中都有广泛的应用。
传递闭包是指对于给定集合上的关系R,存在一个最小的传递关系R',它是R的一个子关系且满足传递性。
计算传递闭包的问题是离散数学中的一个经典问题,解决该问题对于理解传递关系的性质以及进行相应的推理和分析非常重要。
2.传递闭包的定义和性质给定集合A上的关系R,传递闭包R'满足以下条件:-R'是R的一个子关系,即R'⊆R;-R'是传递的,即对于任意的a,b,c∈A,如果aR'b且bR'c,则aR'c。
传递闭包的计算有多种方法,本实验将介绍一种基于矩阵运算的方法。
3.实现算法的步骤给定集合A和关系R,计算传递闭包R'的步骤如下:1)构建集合A上的关系矩阵M,其中M[i][j]表示a[i]Rb[j]是否成立;2)对矩阵M进行幂运算,即计算M的n次幂,其中n为集合A的元素个数;3)对矩阵M每个元素进行逻辑或运算,得到最终的传递闭包关系矩阵;4)根据传递闭包关系矩阵构建传递闭包关系R'。
4.实现代码及测试下面给出了使用Python实现传递闭包计算的代码:```pythondef transitive_closure(A, R):n = len(A)M = [[False] * n for _ in range(n)]for i, a in enumerate(A):for j, b in enumerate(A):if (a, b) in R:M[i][j] = Truefor k in range(n):for i in range(n):for j in range(n):M[i][j] = M[i][j] or (M[i][k] and M[k][j])R_prime = []for i in range(n):for j in range(n):if M[i][j]:R_prime.append((A[i], A[j]))return R_prime#测试A=[1,2,3,4]R=[(1,2),(2,3),(3,4)]R_prime = transitive_closure(A, R)print("传递闭包R':", R_prime)```运行以上代码,输出结果为:```传递闭包R':[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]```可以看到,计算得到的传递闭包R'包含了所有满足传递性的关系。
闭包运算实验报告

一、实验目的了解和掌握闭包运算的概念,熟悉Warshall算法,掌握求关系的自反闭包、对称闭包和传递闭包的方法。
二、实验内容从键盘输入一个关系的关系矩阵,计算其自反闭包、对称闭包和传递闭包,传递闭包要求使用Warshall算法,用C语言实现。
三、思路分析(即代码分析)声明:R[][]表示关系R;x[]表示集合X; r[]表示自反闭包;s[]表示对称闭包;t[]表示传递闭包(一),输入形式:先输出提示符:请先输入集合X中元素的个数,之后输入集合X中的元素(不同元素之间用空格隔开,行末用回车结束):第一行:先输入集合X中元素的个数n,空一格之后输入集合X中的元素,不同元素之间用空格隔开,行末用回车结束:输出提示符:请先输入集合X上的二元关系R的序偶对个数,再输入集合X上的二元关系R,每一对序偶用a,b表示,序偶之间用空格隔开,行末用回车结束:第二行:先输入集合X上的二元关系R的序偶对个数,空一格之后输入集合X上的二元关系R,每一对序偶用a,b表示,序偶之间用空格隔开,行末用回车结束:(二)、输入记录:记录时将X中的元素按照输入的次序依次编号,存储在数组x[]中对应编号的位置1,通过输入的集合X中元素的个数n来控制之后的元素输入循环次数;2,通过输入的集合X上二元关系序偶对的个数来控制之后序偶对的输入循环次数;3,输入序偶对时,每次直接输入到临时变量a,b中,之后在集合x[]中遍历,找到此次输入的序偶对在x[]所对应的位置,之后将二维矩阵R[][]对应位置置1,表示有此对应关系(三),自反闭包计算将关系R[][]复制到自反闭包 r[][] 矩阵中,之后将行数等于列数的元素置1,便按照自反闭包定义将矩阵r[][]扩充到符合要求(四),对称闭包计算扫瞄关系矩阵R[][],记录其中不为1的元素的行列数,之后将对称矩阵s[][]相应的行列数和行数和列数相反的位置都置1;便按照对称闭包定义将矩阵r[][]扩充到符合要求(五),传递闭包计算1,按照Warshall算法,先将R[][]复制到r[][]中,2,遍历r[][]的每列,在每列中找到不为0的元素r[i][j],之后将j行与i行对应的元素进行逻辑加,将结果赋值到第i行上去;3,遍历完每一列后所得的矩阵就是传递闭包的对应矩阵四、实验结果与分析对于输出的闭包关系中,每对序偶用a,b表示,序偶之间用空格隔开,每输出一次用回车结束(例)每次输出时先输出提示符:关系R的自反闭包为:Sample Output:关系R的自反闭包为:a,a a,b b,b b,d c,a c,c d,d d,e e,b e,e关系R的对称必包为:a,b a,c b,a b,d b,e c,a d,b d,e e,b e,d关系R的传递必包为:a,b a,d a,e b,b b,d b,e c,a c,b c,d c,e d,b d,d d,e e,b e,d e,e五、VS2010中验证结果(全视图):请先输入集合X中元素的个数,之后输入集合X中的元素(不同元素之间用空格隔开,行末用回车结束):5 a b c d e请先输入集合X上的二元关系R的序偶对个数,再输入集合X上的二元关系R,每一对序偶用a,b表示,序偶之间用空格隔开,行末用回车结束:5 a,b b,d c,a d,e e,b关系R的自反闭包为:a,a a,b b,b b,d c,a c,c d,d d,e e,b e,e关系R的对称必包为:a,b a,c b,a b,d b,e c,a d,b d,e e,b e,d关系R的传递必包为:a,b a,d a,e b,b b,d b,e c,a c,b c,d c,e d,b d,d d,e e,b e,d e,e 请按任意键继续. . .六、实际输出:。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
闭包运算实验报告
姓名:卢志华学号:1045532116
一、实验目的
1.通过上机程序,进一步加深对关系中自反闭包,对称闭包,传递闭包的理解。
2.掌握Warshall算法。
3.学会用程序解决离散数学中的问题。
4.增强我们编写程序的能力。
二、实验内容
计算已输入集合的关系的自反闭包、对称闭包和传递闭包,传递闭包要求使用Warshall 算法
三、实验环境
我的实验是在VC++6.0实验环境下完成的,而所设计的程序也在这个环境下通过了编译,运行和测试。
四、实验原理和实现过程
下面我就具体分析一下每一种闭包运算的设计:
自反闭包的设计:我们只要把关系矩阵的对角线的元素全赋值为1就可以了。
求自反闭包的程序如下:
void Relation::R_r()
{
for(int i=0;i<LenA;i++)
{
T_R[i][i]=1;
}
}
对称闭包的设计:对于对称闭包,我们只需要将矩阵中数值为1的元素的对称位置的元素数值也设为1就可以了。
具体程序如下:
void Relation::R_s()
{
for(int i=0;i<LenA;i++)
{
for(int j=0;j<LenA;j++)
{
if(T_R[i][j]==1)
T_R[j][i]=1;
}
}
}
传递闭包设计:传递闭包我主要用Warshall算法来求。
设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),否则结束
具体程序如下:
void Relation::R_t()
{
for(int i=0;i<LenA;i++)
{
for(int j=0;j<LenA;j++)
{
if(T_R[j][i]==1)
{
for(int k=0;k<LenA;k++)
{
T_R[j][k]+=T_R[i][k];
if(T_R[j][k]>1)
T_R[j][k]=1;
}
}
}
}
}
五、实验输入输出和数据
程序运行前,首先需要你在main函数中输入一个集合和建立在这个集合上的关系的偶序,然后运行程序就会输出结果。
测试用例一:A={1、2、3},A上的关系R={<12>,<23>,<31>}
输出情况如图:
测试用例二:A={8、6、4、2},A上的关系R={<8,6><6,8><6,4><4,2>}
输出情况如图:
经过计算后对比,程序输出于理论上计算的结果一致,实验成功。
六、心得体会
通过本次实验,我进一步加深了对关系和闭包运算的理解,也掌握了有关关系的一些运算,同时也提高了我的编程能力,学会了使用Warshall算法。
我认为这是一次还有意义的
实验。