离散数学实验报告格式.docx
《离散数学实验报告格式.docx》由会员分享,可在线阅读,更多相关《离散数学实验报告格式.docx(16页珍藏版)》请在冰豆网上搜索。
离散数学实验报告格式
《离散数学》实验报告
专业
班级
姓名
学号
授课教师
二O一六年十二月
实验一联结词的运算
实验二根据矩阵的乘法求复合关系
实验三利用warshall算法求关系的传递闭包
实验四图的可达矩阵实现
实验一联结词的运算
一.实验目的
通过上机实验操作,将命题连接词运算融入到C语言的程序编写中,一方面加强对命题连接词运算的理解,另一方面通过编程实现命题连接词运算,帮助学生复习和锻炼C语言知识,将理论知识与实际操作结合,让学生更加容易理解和记忆命题连接词运算。
二.实验原理
(1)非运算,符号:
当P=T时,P为F,当P=F时,P为T。
(2)合取,符号:
∧,当且仅当P和Q的真值同为真,命题P∧Q的真值才为真;否则,P∧Q的真值为假。
(3)析取,符号:
∨,当且仅当P和Q的真值同为假,命题P∨Q的真值才为假;否则,P∨Q的真值为真。
(4)异或,符号:
▽,当且仅当P和Q的真值不同时,命题P▽Q的真值才为真;否则,P▽Q的真值为真。
(5)蕴涵,符号:
→,当且仅当P为T,Q为F时,命题P→Q的真值才为假;否则,P→Q的真值为真。
(6)等价,符号:
↔,当且仅当P,Q的真值不同时,命题P↔Q的真值才为假;否则,P→Q的真值为真。
三.实验内容
编写一个程序实现非运算、合取运算、析取运算、异或运算、蕴涵运算、等价运算。
四.算法程序
#include
intmain()
{
boolP=true,Q=false;
printf("请选择运算方式\n");
printf("1.析取\n");
printf("2.合取\n");
printf("3.非\n");
printf("4.蕴含\n");
printf("5.等价\n");
intm;
scanf("%d",&m);
while(m>=1&&m<=4)
{
printf("请输入PQ的值\n");
scanf("%d%d",&P,&Q);
intcount=1;
switch(m)
{
case1:
while((count>=1)&&(count<4))
{
if(Q==0&&P==0)
printf("P析取Q=0\n");
else
printf("P析取Q=1\n");
count++;
if(count==4)break;
printf("请输入PQ的值\n");
scanf("%d%d",&P,&Q);
}
break;
case2:
while((count>=0)&&(count<4))
{
if(Q==1&&P==1)
printf("P合取Q=1\n");
else
printf("P合取Q=0\n");
count++;
if(count==4)break;
printf("请输入PQ的值\n");
scanf("%d%d",&P,&Q);
}
break;
case3:
while((count>=0)&&(count<4))
{
if(Q==0)printf("非Q=1\n");
elseprintf("非Q=0\n");
if(P==0)printf("非P=1\n");
elseprintf("非P=0\n");
count++;
if(count==4)break;
printf("请输入PQ的值\n");
scanf("%d%d",&P,&Q);
}
break;
case4:
while((count>=0)&&(count<4))
{
if(Q==1||(Q==0&&P==0))
printf("P蕴含Q=1\n");
elseif(P==1&&Q==0)
printf("P蕴含Q=0\n");
count++;
if(count==4)break;
printf("请输入PQ的值\n");
scanf("%d%d",&P,&Q);
}
break;
case5:
while((count>=0)&&(count<4))
{
if(P==Q)
printf("P等价Q=1\n");
else
printf("P等价Q=0\n");
count++;
if(count==4)break;
printf("请输入PQ的值\n");
scanf("%d%d",&P,&Q);
}
break;
}
printf("请重新选择运算方式\n");
scanf("%d",&m);
}
return0;
}
五.实验结果
六.心得体会
通过将命题连接词运算融入到程序编写中,既加强我对命题连接词运算的理解,又通过编程实现命题连接词运算帮助我复习C语言知识,通过设计算法可以使得数学中逻辑算法用程序来实现,这样只要借助计算机的程序就可以很方便的将一些复杂的逻辑运算轻松地解决。
主函数中设计的代码虽然代码过长,但是结构明显,但是可以拆分为一个菜单函数,和一个指令输入函数,这样整体的机构更加简洁,方便代码的维护。
实验二根据矩阵的乘法求复合关系
一.实验目的
复合运算是一种重要的二元关系运算,可用于二元关系的合成,二元关系的性质判断,二元关系传递闭包的运算等方面,通过编程实现二元关系的复合运算,帮助同学们理解复合运算的过程,复合形成新的二元关系中的序偶是如何产生的。
二.实验原理
复合运算能由两个二元关系生成一个新的二元关系。
设X→Y(R关系),Y→Z(S关系),则称X→Z(R◦S关系)为R和S的复合关系,并规定为:
R◦S={|x∈X∧z∈Z∧∃y(y∈Y∧∈R∧∈S)}
关系可用矩阵表示,故复合运算也可用矩阵表示。
设有三个集合:
X={x1,x2…xm},Y={y1,y2…yn},Z={z1,z2…zp},
,|X|=m,|Y|=n,|Z|=p,MR=[aik]m×n,MS=[akj]n×p则复合关系R◦S的关系矩阵为:
MR◦S=MR◦MS=[cij]m×p
∨代表逻辑加,满足0∨0=0,0∨1=1,1∨0=1,1∨1=1
∧代表逻辑乘,满足0∧0=0,0∧1=0,1∧0=0,1∧1=1
三.实验内容
将二元关系用关系矩阵表示,通过两个关系矩阵对应行列元素先进行逻辑乘,后进行逻辑加生成新的关系矩阵中的每一个元素。
新的关系矩阵所对应的二元关系就是两个二元关系复合形成的,编程实现这一复合过程。
四.算法程序
#include
#defineN100
intmain()
{
intn,m,r;
printf("请输入n,m,r的值:
");
scanf("%d%d%d",&n,&m,&r);
inti,j,s;
intR[N][N],S[N][N];
printf("输入R的序偶:
\n");
for(i=0;ifor(j=0;j{
scanf("%d",&R[i][j]);
if(R[i][j]!
=0&&R[i][j]!
=1)
R[i][j]=0;
}
printf("输入S的序偶:
\n");
for(j=0;jfor(s=0;s{
scanf("%d",&S[j][s]);
if(S[j][s]!
=0&&S[j][s]!
=1)
S[j][s]=0;
}
intRS[N][N];
for(i=0;ifor(s=0;s{
intsum=0;
for(j=0;j{
sum+=R[i][j]*S[j][s];
if(sum!
=0)
RS[i][s]=1;
else
RS[i][s]=0;
}
}
printf("R的矩阵是:
\n");
for(i=0;i{
for(j=0;jprintf("%d",R[i][j]);
printf("\n");
}
printf("S的矩阵是:
\n");
for(i=0;i{
for(s=0;sprintf("%d",S[i][s]);
printf("\n");
}
printf("R复合S结果为:
\n");
for(i=0;i{
for(s=0;sprintf("%d",RS[i][s]);
printf("\n");
}
return0;
}五.实验结果
六.心得体会
利用算法的兼容性使算法优化实现计算多维矩阵的复合运算,避免键盘输入产生的其他数值,影响代码结果的正确性。
实验三利用warshall算法求关系的传递闭包
一.实验目的
对于一个二元关系R,它的传递闭包(t(R))就是包含R,并且具有传递性质的最小二元关系。
传递闭包在图论、数据库、编译原理、计算机形式语言中都有重要的应用。
warshall算法是计算传递闭包的一种有效算法,通过编程实现warshall算法,帮助同学们更好地理解传递闭包的生成过程。
二.实验原理
设X是含有n个元素的集合,R是X上的二元关系,则:
以上计算传递闭包时需要按照复合关系定义求
,这是比较麻烦的,特别当有限集合元素比较多时计算量很大。
1962年Warshall提出了一个求t(R)的有效计算方法:
设R是n个元素集合上的二元关系,
是R的关系矩阵:
第一步:
置新矩阵M,
;
第二步:
置i,
;
第三步:
对
,若M的第j行i列处为1,则对
作如下计算:
将M的第j行第k列元素与第i行第k列元素进行逻辑加,然后将结果送到第j行k列处,即
;
第四步:
;
第五步:
若
,转到第三步,否则停止。
三.实验内容
将二元关系用关系矩阵表示,编程实现Warshall算法,获得二元关系传递闭包的关系矩阵。
四.算法程序
#include
#defineN10
intlogical_add(intx,inty)
{
inta=1;
if(x==0&&y==0)
a=0;
returna;
}
intmain()
{
intMR[N][N];
intM[N][N];
inti,j,k,n;
printf("请输入关系矩阵的阶数:
\n");
scanf("%d",&n);
printf("请输入关系矩阵MR%d*%d:
\n",n,n);
for(i=0;ifor(j=0;j{
scanf("%d",&MR[i][j]);
if(MR[i][j]!
=0&&MR[i][j]!
=1)
MR[i][j]=0;
M[i][j]=MR[i][j];
}
i=0;
while(i{
for(j=0;jif(M[j][i]==1)
for(k=0;kM[j][k]=logical_add(M[j][k],M[i][k]);
i++;
}
printf("关系矩阵为:
\n");
for(i=0;i{
for(j=0;jprintf("%d",MR[i][j]);
printf("\n");
}
printf("结果为:
\n");
for(i=0;i{
for(j=0;jprintf("%d",M[i][j]);
printf("\n");
}
return0;
}
五.实验结果
六.心得体会
数组和循环嵌套可以使得数学中逻辑算法用程序来实现,通过编写矩阵的传递闭包算更加深刻的理解了warshall算法的计算原理。
对于输出的闭包关系中每对序偶输入时用空格隔开,行末用回车结束。
实验四图的可达矩阵实现
一.实验目的
可达矩阵表明了图中任何两个不同的结点之间是否存在至少一条道路,以及在任何结点处是否存在着回路。
可达性矩阵是判别一个有向图是否为强连通图或弱连通图的有效工具,通过编程实现图形的可达矩阵,帮助同学们掌握可达矩阵生成方法。
二.实验原理
定义设G=(V,E)是一个n阶的有向简单图,
。
定义矩阵
,其中
称P是图G的可达矩阵。
求可达矩阵可以先构造A,
,再构造
,最后利用关系
确定P的元素
从而构造出P。
显然,这种先求
再构造P的方法很费事。
如果我们把邻接矩阵A当作关系矩阵,那么求可达矩阵就相当于求A的传递闭包,因此可以仿照集合论中求关系的传递闭包的办法,求可达矩阵P。
三.实验内容
将图形中的边表达成二元关系,计算该二元关系的传递闭包,并将传递闭包表达成关系矩阵,该关系矩阵就是图形的可达矩阵,编程实现求可达矩阵的过程。
四.算法程序
内容格式:
新罗马,小五号,行间距固定值18磅
#include
#defineN20
intlogical_add(intx,inty)
{
inta=1;
if(x==0&&y==0)
a=0;
returna;
}
intmain()
{
intp[N][N],n,i,j,k;
printf("请输入点的个数n:
\n");
scanf("%d",&n);
printf("请输入n*n个数,分别表示两点之间的有向线段,0表示没有:
\n");
for(i=0;ifor(j=0;jscanf("%d",&p[i][j]);
printf("\n原来的邻接矩阵为:
\n");
for(i=0;i{
for(j=0;jprintf("%d",p[i][j]);
printf("\n");
}