算法分析课程设计.docx
《算法分析课程设计.docx》由会员分享,可在线阅读,更多相关《算法分析课程设计.docx(29页珍藏版)》请在冰豆网上搜索。
![算法分析课程设计.docx](https://file1.bdocx.com/fileroot1/2022-12/13/5a265820-ce67-4e94-b4bd-a755bb271b14/5a265820-ce67-4e94-b4bd-a755bb271b141.gif)
算法分析课程设计
算法分析与设计实验报告书评分:
____________
题目:
(例如)基于矩阵变换算法的图同构识别
设计人:
李文森
班级:
网络工程2班学号:
1214080613213
一、实验环境:
1、硬件环境:
个人机,CPU主频:
2.3GHZ内存:
4GB
2、软件环境:
操作系统:
windows
编程语言:
C++
二、实验任务解决方案:
实验思路:
设两个无向图G=(V,E),G’=(V’,E’),G,G’同构当且仅当两图的邻接矩阵、行间同或矩阵、行间异或矩阵具有相同的行行置换。
1.矩阵算法步骤
a.根据定义,求出同型矩阵AAG、AAG’.
b.计算出行间同或矩阵RAG、RAG’,行间异或矩阵RXG、RXG’.
c.以图G=(V,E)的行间异或矩阵为参照,对RXG的每一行,从RXG’搜索所有行,找到一个匹配。
若不存在相应匹配,则两图不同构;若匹配,转步骤(4).
d.判断邻接矩阵AG、AG’,行间同或矩阵中是否存在同样的匹配,若匹配存在,调整邻接矩阵AG’、行间异或矩阵RXG’、行间同或矩阵RAG’对应的行和列;若不匹配,则不同构.
2、基于矩阵变换算法的流程图。
3、基于矩阵变换算法实现的关键代码。
//*********************************冒泡排序
voidwensen_mp(intmp[],intn)
{
intt;
for(inti=0;i{
for(intj=0;j{
if(mp[j]>mp[j+1])
{
t=mp[j];
mp[j]=mp[j+1];
mp[j+1]=t;
}
}
}
}
/////////////////////////核心代码
//异或矩阵行转换
voidwensen_hx(int**p1,int**p13,int**p14,int**p2,int**p23,int**p24,intn)
{
int*p77=newint[n];//用于替换的临时一维数组,存放p13
int*p88=newint[n];//用于替换的临时一维数组,存放p23
int*p33=newint[n];//用于替换的临时一维数组,存放p1
int*p44=newint[n];//用于替换的临时一维数组,存放p14
int*p55=newint[n];//用于替换的临时一维数组,存放p2
int*p66=newint[n];//用于替换的临时一维数组,存放p24
int*p99=newint[n];//用于行行替换的临时数组
intt;
inttt;//进行跳转判断
intttt=0;//进行跳转判断
//行行替换
for(inti=0;i{
//首先进行行赋值给另外一个数组p13
for(inti77=0;i77{
p77[i77]=p13[i][i77];
}
//首先进行行赋值给另外一个数组p1
for(inti33=0;i33{
p33[i33]=p1[i][i33];
}
//首先进行行赋值给另外一个数组
for(inti44=0;i44{
p44[i44]=p14[i][i44];
}
//p77,p33,p44冒泡排序
wensen_mp(p77,n);
wensen_mp(p33,n);
wensen_mp(p44,n);
//开始进行比较,p12的每一行与p23的每一行进行比较
for(inty=i;y{
tt=0;
//首先进行行赋值给另外一个数组
for(inti88=0;i88{
p88[i88]=p23[y][i88];
}
//首先进行行赋值给另外一个数组
for(inti55=0;i55{
p55[i55]=p2[y][i55];
}
//首先进行行赋值给另外一个数组
for(inti66=0;i66{
p66[i66]=p24[y][i66];
}
//p88,p55,p66冒泡排序
wensen_mp(p88,n);
wensen_mp(p55,n);
wensen_mp(p66,n);
//开始比较
for(inta=0;a{
if(p77[a]==p88[a])
{
tt=a;
if(a==n-1)//也就是各个都相等,找到匹配
{
//开始进行邻接矩阵对应位置比较
for(intb=0;b{
if(p33[b]==p55[b])
{
continue;
}
elseif(b{
cout<<"不同构\n";
return;
}
}
//开始进行同或矩阵
for(intc=0;c{
if(p44[c]==p66[c])
{
continue;
}
elseif(c{
cout<<"不同构\n";
return;
}
}
ttt++;//表示成功匹配一行
//进行行行转换p2
for(intu1=0;u1{
t=p2[i][u1];
p2[i][u1]=p2[y][u1];
p2[y][u1]=t;
}
for(intu11=0;u11{
t=p2[u11][i];
p2[u11][i]=p2[u11][y];
p2[u11][y]=t;
}
//进行行行转换p23
for(intu2=0;u2{
t=p23[i][u2];
p23[i][u2]=p23[y][u2];
p23[y][u2]=t;
}
for(intu22=0;u22{
t=p23[u22][i];
p23[u22][i]=p23[u22][y];
p23[u22][y]=t;
}
//进行行行转换p24
for(intu3=0;u3{
t=p24[i][u3];
p24[i][u3]=p24[y][u3];
p24[y][u3]=t;
}
for(intu33=0;u33{
t=p24[u33][i];
p24[u33][i]=p24[u33][y];
p24[u33][y]=t;
}
break;
}
else
{
continue;
}
}
elseif(y==n-1)//一直循环到最后都未找到匹配
{
cout<<"不同构\n";
return;
}
else
{
break;
}
}
//上面的匹配没有问题,则进行行替换
if(tt==n-1)
{
if(ttt==n)
{
cout<<"同构\n";
return;
}
else
{
break;//成功跳出循环判断下一行
}
}
}
}
}
三、基于矩阵变换算法的计算复杂度分析(最好、最差、平均情况复杂度):
1.同构最好情况是:
每一行都互相对应,所以复杂度为:
3n^2+3n^3+8n^2
时间复杂度为O(n^3)。
2.同构最坏情况是:
每一行都与最后一行对应,所以复杂度为:
3n^2+3n^3+8n*n!
时间复杂度为O(n*n!
)
3.所以平均时间复杂度为O(n*n!
)
四、总结综合实验心得体会:
1.实例演示
邻接矩阵:
2.实验体会
本课程设计是为了判断无向图是否同构,采用了较为容易实现的邻接矩阵,同时用到了同型矩阵、行间异或矩阵、行间同或矩阵等知识。
知道了同构当且仅当两图的邻接矩阵、行间同或矩阵、行间异或矩阵具有相同的行行置换。
通过他们之间对应的关系,我写出了这个算法,并已经初步测试过,能正确判断图是否同构。
通过本次的课程设计,让我更好的了解了算法的重要性,一个优异的算法能极大的减少运行时间。
在本课程设计上,在异或矩阵的比对上,为了更好的实现元素比对,我采用了了冒泡排序法,可以让它实现有序的比对,这样就减少了比对的次数,减少运算时间。
本算法还有挺多改进的地方,例如,算法复杂度太大,所以算法还有待进一步改善,以达到更优。
//完全代码
#include
usingnamespacestd;
//定义函数
//22222222222222222222222同型矩阵
voidwensen_tx(int**p1,int**p2,intn)
{
for(inti=0;i{
for(intj=0;j{
if(p1[i][j]>0)
{
p2[i][j]=1;
}
else
{
p2[i][j]=0;
}
}
}
}
//3333333333333333333333异或矩阵
voidwensen_yh(int**p1,int**p2,int**p3,intn)
{
for(inti=0;i{
for(intj=0;j{
if(i==j)
{
p3[i][j]=p1[i][i];
}
else
{
intsum1,sum12;
sum1=0;
for(intk=0;k{
if(p2[i][k]==p2[j][k])
{
sum12=0;
}
else
{
sum12=1;
}
sum1=sum1+(p1[i][k]+p1[j][k])*sum12;
}
p3[i][j]=sum1;
}
}
}
}
////44444444444444444同或矩阵
voidwensen_th(int**p1,int**p2,int**p4,intn)
{
for(inti=0;i{
for(intj=0;j{
if(i==j)
{
p4[i][j]=p1[i][i];
}
else
{
intsum1,sum12;
sum1=0;
for(intk=0;k{
if(p2[i][k]==p2[j][k])
{
sum12=1;
}
else
{
sum12=0;
}
sum1=sum1+(p1[i][k]+p1[j][k])*sum12;
}
p4[i][j]=sum1;
}
}
}
}
//////////////////////////输出函数
voidwensen_out(int**p,char*s,intn)
{
cout<
cout<<"\n";
for(inti=0;i{
for(intj=0;j{
cout<
cout<<"\t";
}
cout<<"\n";
}
}
//*********************************冒泡排序
voidwensen_mp(intmp[],intn)
{
intt;
for(inti=0;i{
for(intj=0;j{
if(mp[j]>mp[j+1])
{
t=mp[j];
mp[j]=mp[j+1];
mp[j+1]=t;
}
}
}
}
/////////////////////////核心代码
//异或矩阵行转换
voidwensen_hx(int**p1,int**p13,int**p14,int**p2,int**p23,int**p24,intn)
{
int*p77=newint[n];//用于替换的临时一维数组,存放p13
int*p88=newint[n];//用于替换的临时一维数组,存放p23
int*p33=newint[n];//用于替换的临时一维数组,存放p1
int*p44=newint[n];//用于替换的临时一维数组,存放p14
int*p55=newint[n];//用于替换的临时一维数组,存放p2
int*p66=newint[n];//用于替换的临时一维数组,存放p24
int*p99=newint[n];//用于行行替换的临时数组
intt;
inttt;//进行跳转判断
intttt=0;//进行跳转判断
//行行替换
for(inti=0;i{
//首先进行行赋值给另外一个数组p13
for(inti77=0;i77{
p77[i77]=p13[i][i77];
}
//首先进行行赋值给另外一个数组p1
for(inti33=0;i33{
p33[i33]=p1[i][i33];
}
//首先进行行赋值给另外一个数组
for(inti44=0;i44{
p44[i44]=p14[i][i44];
}
//p77,p33,p44冒泡排序
wensen_mp(p77,n);
wensen_mp(p33,n);
wensen_mp(p44,n);
//开始进行比较,p12的每一行与p23的每一行进行比较
for(inty=i;y{
tt=0;
//首先进行行赋值给另外一个数组
for(inti88=0;i88{
p88[i88]=p23[y][i88];
}
//首先进行行赋值给另外一个数组
for(inti55=0;i55{
p55[i55]=p2[y][i55];
}
//首先进行行赋值给另外一个数组
for(inti66=0;i66{
p66[i66]=p24[y][i66];
}
//p88,p55,p66冒泡排序
wensen_mp(p88,n);
wensen_mp(p55,n);
wensen_mp(p66,n);
//开始比较
for(inta=0;a{
if(p77[a]==p88[a])
{
tt=a;
if(a==n-1)//也就是各个都相等,找到匹配
{
//开始进行邻接矩阵对应位置比较
for(intb=0;b{
if(p33[b]==p55[b])
{
continue;
}
elseif(b{
cout<<"不同构\n";
return;
}
}
//开始进行同或矩阵
for(intc=0;c{
if(p44[c]==p66[c])
{
continue;
}
elseif(c{
cout<<"不同构\n";
return;
}
}
ttt++;//表示成功匹配一行
//进行行行转换p2
for(intu1=0;u1{
t=p2[i][u1];
p2[i][u1]=p2[y][u1];
p2[y][u1]=t;
}
for(intu11=0;u11{
t=p2[u11][i];
p2[u11][i]=p2[u11][y];
p2[u11][y]=t;
}
//进行行行转换p23
for(intu2=0;u2{
t=p23[i][u2];
p23[i][u2]=p23[y][u2];
p23[y][u2]=t;
}
for(intu22=0;u22{
t=p23[u22][i];
p23[u22][i]=p23[u22][y];
p23[u22][y]=t;
}
//进行行行转换p24
for(intu3=0;u3{
t=p24[i][u3];
p24[i][u3]=p24[y][u3];
p24[y][u3]=t;
}
for(intu33=0;u33{
t=p24[u33][i];
p24[u33][i]=p24[u33][y];
p24[u33][y]=t;
}
break;
}
else
{
continue;
}
}
elseif(y==n-1)//一直循环到最后都未找到匹配
{
cout<<"不同构\n";
return;
}
else
{
break;
}
}
//上面的匹配没有问题,则进行行替换
if(tt==n-1)
{
if(ttt==n)
{
cout<<"同构\n";
return;
}
else
{
break;//成功跳出循环判断下一行
}
}
}
}
}
///////////////////////////////////////主程序
intmain()
{
intn;//图的顶点数
char*s;//字符串提示
charss='y';
cout<<"\n";
cout<<"**********************欢迎进入李文森图同构判断*******************\n\n\n";
while(ss=='y')
{
cout<<"请输入图的顶点个数\n";
cin>>n;//接收第一个图的顶点个数
if(cin.fail())
{
cout<<"**********输入错误,请重新输入***