离散数学实验报告四个实验汇编Word文档格式.docx
《离散数学实验报告四个实验汇编Word文档格式.docx》由会员分享,可在线阅读,更多相关《离散数学实验报告四个实验汇编Word文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
∈R,则称关系R是传递的,或称R具有传递性,即R在A上是传递的⇔(∀x)(∀y)(∀z)[(x∈A)∧(y∈A)∧(z∈A)∧((<
∈R)∧(<
∈R))]=1
三、实验原理:
通过二元关系与关系矩阵的联系,可以引入N维数组,以数组的运算来实现二元关系的判断。
图示:
性质
关系矩阵特性
自反性
主对角线元素全为1
反自反性
主对角线元素全为0
对称性
对称矩阵
反对称性
非主对角线上的元素等于1且与之对称的元素等于0
传递性
矩阵(M*M)中1所在的位置,M中与之相对应位置鲜红都为1
四、实验环境:
Windows7UltimateDEVC++
五、实验语言:
C语言
六、程序源代码:
#include"
stdio.h"
#defineN4
main()
{
inti,j,k;
intf,e,z;
intM[N][N];
printf("
判断R是否为自反关系、对称关系、是否可传递?
\n"
);
请输入一个4*4的矩阵。
for(i=0;
i<
N;
i++)/*输入一个4*4的矩阵*/
for(j=0;
j<
j++)
scanf("
%d"
&
M[i][j]);
for(i=0;
i++)
{
for(j=0;
printf("
%4d"
M[i][j]);
}
{
if(M[i][i]==1)//判断自反性
{
if(i=N-1
e=0;
else
;
}
elseif(M[i][i]==0)//判断反自反性
{
if(i=N-1)
e=1;
e=2;
break;
}
if(M[i][j]!
=M[j][i])//判断对称性
f=1;
if(M[i][j]==1)//判断反对称性
if(M[j][i]==0)
if(i==(N-1)&
&
j==N-1)
f=0;
if(f!
=0&
f!
=1)
f=2;
i++)//判断可传递性
if(M[i][j]==1)
continue;
for(k=0;
k<
k++)
if(M[i][k]*M[k][i]==0)
z=0;
if(e==0)
关系R是自反关系\n"
elseif(e==1)
关系R是反自反关系\n"
elseif(e==2)
if(f==0)
关系R是反对称关系\n"
elseif(f==1)
关系R不是对称关系\n"
elseif(f==2)
关系R是对称关系\n"
if(z==0)
关系R是不可传递关系\n"
关系R是可传递关系\n"
system("
PAUSE"
}
七、程序运行截图:
、程序启动截图:
、程序输入截图:
、程序运行结果截图:
八、实验总结:
实验简洁高效地判断二元关系的性质。
实验二、编程求一个二元关系的自反闭包、对称闭包、传递闭包
一、前言引语
一个二元关系可能具有某种性质,也可能不具有这种性质。
现在讨论怎样使一个二元关系变成具有指定性质的新关系,并且还要满足最小性条件。
二、数学原理
自反闭包、对称闭包、传递闭包
设R是定义在A上的二元关系,若存在A上的关系R′满足:
1)R′是自反的(或对称的、或可传递的),
2)R⊆R′,
3)对A上任何其它满足1)和2)的关系R〞,都有:
R′⊆R〞。
则称R′为R的自反闭包(或对称闭包、或传递闭包),分别记为r(R)、(s(R)和t(R))。
三、实验原理
Warshall算法的基本思想
对每个结点(从第一列开始),找出所有具有到此结点的有向边的结点(即该列中元素为1的所在行的结点),再将这些结点所在行同该结点所在行进行逻辑加后作为这些结点所在的新行(添加新的有向边)(反映了如果这些结点没有到其它结点的有向边,但有到该结点的有向边,再通过该结点间接到达其它结点,根据传递闭包的定义,这些结点就必然有一条有向边到达其它结点)。
▪设R是集合上的二元关系,Mr是R的关系矩阵
▪
(1)置新矩阵A:
=Mr
▪
(2)置(列)j:
=1
▪(3)对所有的i(1≤i≤n)
如A(i,j)=1,则对k=1,2,…,n
A(i,k):
=A(i,k)∨A(j,k)
▪(即将A的第i行与A的第j行进行逻辑加后送回A的第i行)
▪(4)j:
=j+1
▪(5)如j≤n转(3),否则停止。
五、实验编程语言:
C语言
六、实验程序源代码
//sourcefile:
War.cpp
#include<
stdio.h>
voidWar(intm,intn)
inti,j,k;
设置临时变量
inta=0,b=0;
intarr[10][10];
for(a=0;
a<
m;
++a)
printf("
请输入矩阵第%d行元素:
"
a);
for(b=0;
b<
n;
++b)
scanf("
arr[a][b]);
for(i=0;
i<
i++)
for(j=0;
j<
j++)
if(arr[j][i]==1)
for(k=0;
k<
k++)
arr[j][k]=arr[i][k]||arr[j][k];
所得的可传递闭包关系矩阵是:
i<
++i)
for(j=0;
j<
++j)
%d"
arr[i][j]);
//file:
test.cpp
voidmain()
利用Warshall算法求二元关系的可传递闭包\n"
voidWar(int,int);
intm,n;
请输入矩阵的行数(必须小于10):
&
m);
请输入矩阵的列数(必须小于10):
n);
War(m,n);
system(“PAUSE”);
return0;
七、实验截图
.程序启动画面:
.输入关系矩阵的行数和列数以及关系矩阵的各个元素。
.得出结果,并打印在屏幕上。
八、实验总结
如果当一个集合的元素的个数n很大时,求在该集合上的二元关系的可传递闭包是非常复杂的。
幸好Warshall算法给我们提供了一个求二元关系的可传递闭包的高效方法。
结合计算机程序技术,利用warshall算法我们可以轻松的求出一个二元关系的可传递闭包。
本次实验便捷高效地达到了实验的目的。
实验三、编程求一个二元关系的复合运算
一、实验引语:
关系作为集合,除了具有一般的运算功能外,还具有自身独特的复合运算。
设R是集合A到B的二元关系,S是集合B到C的二元关系,则
R。
S={(x,z)
A
C|(
y
B)[(x,y)
R∧(y,z)
S]}称为R和S的复合关系。
矩阵的运算
C语言
string.h"
#defineM3
#defineN3
#defineP3
inti,j,k,x;
charp;
intA[N][M],B[M][P],C[N][P];
关系的复合运算\n"
printf(“请输入一个3*3的矩阵”);
A:
for(i=1;
=N;
for(j=1;
=M;
scanf("
A[i][j]);
B:
=P;
B[i][j]);
经过复合运算后得到C:
for(i=1;
x=0;
for(k=1;
x=x+A[i][k]*B[k][j];
if(x>
0)
C[i][j]=1;
C[i][j]=0;
C[i][j]);
return0;
、程序输入截图:
、程序运行结果截图:
本实验利用计算机技术,快速便捷地实现了关系的运算,极大提高了效率。
实验四:
编程实现拓扑排序算法
一、实验引言
一个复杂的工程通常可以分解成一组小任务的集合,完成这些小任务意味着整个工程的完成,,任务之间具有先后关系,任务的先后顺序可用有向图表示。
拓扑排序
)定义:
由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
)实现方法:
从有向图中选择一个没有前驱的顶点并输出它。
从网中删去该顶点并删去从该顶点发出的全部有向边。
重复上述两步直到剩余的网中不存在没有前驱的顶点。
首先对有向图,我们采取邻接表作为数据结构。
且将表头指针改为头结点,其数据域存放该结点的入度,入度设为零的结点即没有前趋。
在建立邻接表输入之前,表头向量的每个结点的初始状态为数据域VEX(入度)为零,指针域NXET为空,每输入一条弧<
J,K>
建立链表的一个结点,同时令k的入度加1,因此在输入结束时,表头的两个域分别表示顶点的入度和指向链表的第一个结点指针。
在拓扑排序的过程之中,输入入度为零(即没有前趋)的顶点,同时将该顶点的直接后继的入度减1。
(1)、查邻接表中入度为零的顶点,并进栈。
(2)、当栈为空时,进行拓扑排序。
(a)、退栈,输出栈顶元素V。
(b)、在邻接表中查找Vj的直接后继Vk,将Vk的入度减一,并令入度减至零的顶点进栈。
(3)、若栈空时输出的顶点数不是N个则说明有向回路,否则拓扑排序结束。
为建立存放入度为零的顶点的栈,不需要另分配存储单元,即可借入入度为零的数据域。
一方面,入度为零的顶点序号即为表头结点的序号,另一方面,借用入度为零的数据域存放带链栈的指针域(下一个入度的顶点号)。
C++
六、程序源代码
iostream>
cmath>
cstdio>
algorithm>
stack>
usingnamespacestd;
#defineMAX9999
stack<
int>
mystack;
intindegree[MAX];
structnode
intadjvex;
node*next;
}adj[MAX];
intCreate(nodeadj[],intn,intm)//邻接表建表函数,n代表定点数,m代表边数
inti;
node*p;
=n-1;
adj[i].adjvex=i;
adj[i].next=NULL;
=m-1;
cout<
<
请输入第"
条边:
;
intu,v;
cin>
>
u>
v;
p=newnode;
p->
adjvex=v;
next=adj[u].next;
adj[u].next=p;
return1;
voidprint(intn)//邻接表打印函数
p=&
adj[i];
while(p!
=NULL)
p->
adjvex<
'
'
p=p->
next;
endl;
voidtopsort(nodeadj[],intn)
memset(indegree,0,sizeof(indegree));
p=adj[i].next;
indegree[p->
adjvex]++;
if(indegree[i]==0)
mystack.push(i);
intcount=0;
while(mystack.size()!
=0)
i=mystack.top();
mystack.pop();
count++;
for(p=adj[i].next;
p!
=NULL;
p=p->
next)
intk=p->
adjvex;
indegree[k]--;
if(indegree[k]==0)
mystack.push(k);
if(count<
n)cout<
有回路"
intmain()
500元以上1224%{
intn;
(4)创新能力薄弱intm;
拓扑排序算法"
请输入顶点数及边数:
n>
m;
据了解,百分之八十的饰品店都推出“DIY饰品”来吸引顾客,一方面顺应了年轻一代喜欢与众不同、标新立异的心理;
另一方面,自制饰品价格相对较低,可以随时更新换代,也满足了年轻人“喜新厌旧”的需要,因而很受欢迎。
Create(adj,n,m);
输入的邻接表为:
我们认为:
创业是一个整合的过程,它需要合作、互助。
大学生创业“独木难支”。
在知识经济时代,事业的成功来自于合作,团队精神。
创业更能培养了我们的团队精神。
我们一个集体的智慧、力量一定能够展示我们当代大学生的耐心.勇气和坚强的毅力。
能够努力克服自身的弱点,取得创业的成功。
print(n);
精明的商家不失时机地打出“自己的饰品自己做”、“DIY(DoItYourself)饰品、真我个性”的广告,推出“自制饰品”服务,吸引了不少喜欢标新立异、走在潮流前端的年轻女孩,成为上海的时尚消费市场。
其市场现状特点具体表现为:
拓扑排序结果为:
topsort(adj,n);
四、影响的宏观环境分析system("
pause"
尽管售价不菲,但仍没挡住喜欢它的人来来往往。
这里有营业员们向顾客们示范着制作各种风格迥异的饰品,许多顾客也是学得不亦乐乎。
在现场,有上班族在里面精挑细选成品,有细心的小女孩在仔细盘算着用料和价钱,准备自己制作的原料。
可以想见,用本来稀奇的原料,加上别具匠心的制作,每一款成品都必是独一无二的。
而这也许正是自己制造所能带来最大的快乐吧。
3.www。
oh/ov。
com/teach/student/shougong/七、程序运行截图
300-400元1632%以下图为例:
、程序启动截图
在大学生对DIY手工艺品价位调查中,发现有46%的女生认为在十元以下的价位是可以接受;
48%的认为在10-15元;
6%的则认为50-100元能接受。
如图1-2所示
、程序输入截图
、程序运行结果截图
通过本次实验掌握拓扑排序的算法,了解拓扑排序的有向图的数据结构。
参考文献
1.《离散数学》冯伟森、栾新成、石兵等编著机械工业出版社
2.《C语言程序设计》陈良银、游洪跃、李旭伟等编著清华大学出版社
3.《C++:
面向对象程序设计》李涛、游洪跃等编高等教育出版社