离散数学实验指导.docx
《离散数学实验指导.docx》由会员分享,可在线阅读,更多相关《离散数学实验指导.docx(14页珍藏版)》请在冰豆网上搜索。
![离散数学实验指导.docx](https://file1.bdocx.com/fileroot1/2022-11/22/55fe38ce-a079-4ff1-b0f0-0e854c1c73ac/55fe38ce-a079-4ff1-b0f0-0e854c1c73ac1.gif)
离散数学实验指导
实验1关系的闭包运算
1、实验类型:
设计性
2、实验目的
通过算法设计并编程实现求给定关系的各种闭包运算,加深学生对闭包运算的概念的理解。
3、实验内容
给定关系R,求R的自反闭包、对称闭包及R的传递闭包。
4、实验原理
若关系R的关系矩阵为M,而自反闭包为A(即r(R)=A),对称闭包为B(即S(R)=B),则A=M∨IB=M∨MT其中,I为恒等矩阵,MT为M的转置矩阵。
5、实验仪器设备或软件环境及工具
运行Windows或Linux操作系统的PC机,具有gcc(Linux)、Turboc、Vc(Windows)等C语言的编译环境。
6、实验要求
复习关系闭包的定义,实验由一人一组完成。
所编程序能够通过编译,并能够实现求出给定关系的闭包的运算。
7、实验报告要求
(1)写出实验过程中遇到的问题及其解决过程。
(2)写出类c的算法并编写一个程序求出给定关系的闭包。
(3)写出实验结束时的程序清单及运行结果及实验总结。
实验2最小生成树的Kruskal算法
1、实验类型:
设计性
2、实验目的
通过算法设计并编程实现求出给定无向连通加权图的一棵最小生成树,加深学生对求最小生成树的Kruskal算法的理解。
3、实验内容
给定无向连通加权图,编程设计求出其一棵最小生成树。
4、实验原理
设所给定无向连通加权图具有n个结点,m条边,首先,将各条边的权按从小到大的顺序排序。
然后依次将这些边按所给图的结构放到生成树中去。
如果在放置某一条边时,使得生成树形成回路,则删除这条边。
这样,直至生成树具有n-1条边时,我们所得到的就是一棵最小生成树。
5、实验仪器设备或软件环境及工具
运行Windows或Linux操作系统的PC机,具有gcc(Linux)、Turboc、Vc、CFree(Windows)等C语言的编译环境。
6、实验要求
复习树及最小生成树的定义,实验由一人一组完成。
所设计程序能够通过编译,并能够求出给定无向连通加权图的一棵最小生成树。
7、实验步骤及注意事项
(1)边依小到大顺序得l1,l2,…,lm。
(2)置初值:
S,0
i,1
j。
(3)若i=n-1,则转(6)。
(4)若生成树边集S并入一条新的边lj之后产生的回路,则j+1
j,并转(4)。
(5)否则,i+1
i;lj
S(i);j+1
j,转(3)。
(6)输出最小生成树S。
(7)结束。
8、实验报告要求
(1)写出实验过程中遇到的问题及其解决过程。
(2)写出类c的算法,并写一个程序求出给定无向连通加权图的一棵最小生成树。
(3)写出实验结束时的程序清单及运行结果及实验总结。
参考例子:
1闭包:
#include
intmain()
{
inti,j,k,n;
staticintstr[122],zifan[122],chuandi[122],duich[122];
printf("Pleaseinputthejie:
\n");
scanf("%d",&n);
printf("A=%d\n",n);
for(i=0;i{
scanf("%d",&str[i]);
}
printf("Theshuzuis:
\n");
for(j=0;j{
printf("%4d",str[j]);
if((j+1)%n==0)
printf("\n");
}
for(j=0;j{
zifan[j]=str[j];
chuandi[j]=str[j];
duich[j]=str[j];
}
printf("Thezifanbibaois:
\n");
for(i=0;i{
if(i%(n+1)==0)
zifan[i]=zifan[i]||1;
printf("%4d",zifan[i]);
if((i+1)%n==0)
printf("\n");
}
printf("Theduichbibaois:
\n");
for(i=0,j=0;i{
if(i>j*(n+1)&&i<(j+1)*n)
{duich[i]=duich[(i-j*(n+1))*(n-1)+i]||duich[i];
duich[(i-j*(n+1))*(n-1)+i]=duich[(i-j*(n+1))*(n-1)+i]||duich[i];
}
elseif(i>=(j+1)*n)
j++;
}
for(i=0;i{
printf("%4d",duich[i]);
if((i+1)%n==0)
printf("\n");
}
printf("Thechuandibibaois:
\n");
for(i=0;ifor(j=0;jif(chuandi[j*n+i])
{for(k=0;kchuandi[j*n+k]=chuandi[j*n+k]||chuandi[i*n+k];
}
for(i=0;i{
printf("%4d",chuandi[i]);
if((i+1)%n==0)
printf("\n");
}
return0;
}
2、warshall算法:
#include
#include
#include
#defineN3
#defineTRUE0
intget_matrix(inta[N][N])
{
inti=0,j=0;
for(i=0;ifor(j=0;jscanf("%d",&a[i][j]);
if(a[i][j]!
=0&&a[i][j]!
=1){
printf("0or1inmatrix\n");
exit
(2);
}
}
}
returnTRUE;
}
intoutput_matrix(inta[N][N])
{
inti=0,j=0;
for(i=0;ifor(j=0;jprintf("%d",a[i][j]);
}
putchar('\n');
}
returnTRUE;
}
intwarshall(inta[N][N])
{
intcol=0;
intline=0;
inttemp=0;
for(col=0;colfor(line=0;lineif(a[line][col]!
=0){
for(temp=0;tempa[line][temp]=a[line][temp]|a[col][temp];
}
}
}
}
returnTRUE;
}
intmain(void)
{
inta[N][N]={0};
printf("pleaseinputamatrixwith%d*%d:
\n",N,N);
if(get_matrix(a)){
printf("getmatrixerror!
\n");
exit
(1);
}
warshall(a);
output_matrix(a);
return0;
}
3、Kruskal算法1:
#defineMAXE11
#defineMAXV10
#include"stdio.h"
typedefstruct
{
intvex1;//边的起始顶点
intvex2;//边的终止顶点
intweight;//边的权值
}Edge;
voidkruskal(EdgeE[],intn,inte)
{
inti,j,m1,m2,sn1,sn2,k;
intvset[MAXV];
for(i=1;i<=n;i++)//初始化辅助数组
vset[i]=i;
k=1;//表示当前构造最小生成树的第k条边,初值为1
j=0;//E中边的下标,初值为0
while(k{
m1=E[j].vex1;
m2=E[j].vex2;//取一条边的两个邻接点
sn1=vset[m1];
sn2=vset[m2];
//分别得到两个顶点所属的集合编号
if(sn1!
=sn2)
//两顶点分属于不同的集合,该边是最小生成树的一条边
{
printf("(v%d,v%d):
%d\n",m1,m2,E[j].weight);
k++;//生成边数增l
if(k>=6)break;
for(i=1;i<=n;i++)//两个集合统一编号
if(vset[i]==sn2)//集合编号为sn2的改为sn1
vset[i]=sn1;
}//if
j++;//扫描下一条边
}//while
}//kruskal
intmain()
{
EdgeE[MAXE];
intnume,numn;
/*
printf("输入边数和顶数:
\n");
scanf("%d%d",&nume,&numn);*/
nume=10;
numn=6;
//printf("请输入各边及对应的的权值(起始顶点终止顶点权值)\n");
/*
for(inti=0;iscanf("%d%d%d",&E[i].vex1,&E[i].vex2,&E[i].weight);*/
//在这里对输入的数据进行排序,达到假设的要求,即:
假设数组E存放图G中的
//所有边,且边已按权值从小到大的顺序排列
E[9].vex1=1;
E[9].vex2=2;
E[9].weight=6;
E[0].vex1=1;
E[0].vex2=3;
E[0].weight=1;
E[4].vex1=1;
E[4].vex2=4;
E[4].weight=5;
E[6].vex1=2;
E[6].vex2=3;
E[6].weight=5;
E[2].vex1=2;
E[2].vex2=5;
E[2].weight=3;
E[8].vex1=1;
E[8].vex2=2;
E[8].weight=6;
E[5].vex1=3;
E[5].vex2=4;
E[5].weight=5;
E[7].vex1=3;
E[7].vex2=5;
E[7].weight=6;
E[3].vex1=3;
E[3].vex2=6;
E[3].weight=4;
E[1].vex1=4;
E[1].vex2=6;
E[1].weight=2;
kruskal(E,numn,nume);
}
4、Kruskal算法2:
#include"stdio.h"
#definemaxver10
#definemaxright100
intG[maxver][maxver],record=0,touched[maxver][maxver];
intcircle=0;
intFindCircle(int,int,int,int);
intmain()
{
intpath[maxver][2],used[maxver][maxver];
inti,j,k,t,min=maxright,exsit=0;
intv1,v2,num,temp,status=0;
restart:
printf("Pleaseenterthenumberofvertex(s)inthegraph:
\n");
scanf("%d",&num);
if(num>maxver||num<0)
{
printf("Error!
Pleasereinput!
\n");
gotorestart;
}
for(j=0;jfor(k=0;k{
if(j==k)
{
G[j][k]=maxright;
used[j][k]=1;
touched[j][k]=0;
}
elseif(j{
re:
printf("Pleaseinputtherightbetweenvertex%dandvertex%d,ifnoedgeexistspleaseinput-1:
\n",j+1,k+1);
scanf("%d",&temp);
if(temp>=maxright||temp<-1)
{
printf("Invalidinput!
\n");
gotore;
}
if(temp==-1)
temp=maxright;
G[j][k]=G[k][j]=temp;
used[j][k]=used[k][j]=0;
touched[j][k]=touched[k][j]=0;
}
}
for(j=0;j{
path[j][0]=0;
path[j][1]=0;
}
for(j=0;j{
status=0;
for(k=0;kif(G[j][k]{
status=1;
break;
}
if(status==0)
break;
}
for(i=0;i{
for(j=0;jfor(k=0;kif(G[j][k]used[j][k])
{
v1=j;
v2=k;
min=G[j][k];
}
if(!
used[v1][v2])
{
used[v1][v2]=1;
used[v2][v1]=1;
touched[v1][v2]=1;
touched[v2][v1]=1;
path[i][0]=v1;
path[i][1]=v2;
for(t=0;tFindCircle(path[t][0],path[t][0],num,path[t][0]);
if(circle)
{
/*ifacircleexsits,rollback*/
circle=0;
i--;
exsit=0;
touched[v1][v2]=0;
touched[v2][v1]=0;
min=maxright;
}
else
{
record++;
min=maxright;
}
}
}
if(!
status)
printf("Wecannotdealwithitbecausethegraphisnotconnected!
\n");
else
{
for(i=0;iprintf("Path%d:
vertex%dtovertex%d\n",i+1,path[i][0]+1,path[i][1]+1);
}
return1;
}
intFindCircle(intstart,intbegin,inttimes,intpre)
{
/*tojudgewhetheracircleisproduced*/
inti;
for(i=0;iif(touched[begin][i]==1)
{
if(i==start&&pre!
=start)
{
circle=1;
return1;
break;
}
elseif(pre!
=i)
FindCircle(start,i,times,begin);
else
continue;
}
return1;
}