9回溯法求解哈密尔顿回路.docx
- 文档编号:10853269
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:20
- 大小:296.65KB
9回溯法求解哈密尔顿回路.docx
《9回溯法求解哈密尔顿回路.docx》由会员分享,可在线阅读,更多相关《9回溯法求解哈密尔顿回路.docx(20页珍藏版)》请在冰豆网上搜索。
9回溯法求解哈密尔顿回路
数学与计算机学院
课程设计说明书
课程名称:
算法设计与分析-课程设计
课程代码:
7106620
题目:
回溯法求解一般哈密尔顿回路
年级/专业/班:
学生姓名:
学 号:
开始时间:
2010年12月27日
完成时间:
2011年01月07日
课程设计成绩:
学习态度及平时成绩(30)
技术水平与实际能力(20)
创新(5)
说明书撰写质量(45)
总分(100)
指导教师签名:
年月日
摘要
本次我的课程设计题目是“用回溯法求解一般哈密尔顿回路问题”,主要内容是给出用回溯法求解一般哈密尔顿回路问题的算法并编程实现。
所涉及到的知识是《算法设计与分析》中的回溯法,以及《图论》中的哈密顿尔回路。
回溯法:
从根结点出发,按照深度优先策略遍历解空间树,搜索满足约束条件的解。
哈密顿回路:
从某顶点开始,经过图G全部顶点一次回到起点的回路。
关键词:
回溯法哈密顿尔回路算法编程实现
1引言
1.1问题的提出
我所做的课程设计就是用回溯法求解一般哈密尔顿回路问题,即从某顶点开始,经过图G全部顶点一次回到起点的回路。
1.2任务与分析
本课程设计主要的目的是:
通过回溯的方法找出图的一般哈密顿尔回路,并且能够输出。
题目分析:
回溯法是一个既带有系统性又带有跳跃性的的搜索算法。
它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。
算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。
如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。
否则,进入该子树,继续按深度优先的策略进行搜索。
回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。
而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。
这种以深度优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题。
哈密顿回路:
从某顶点开始,经过图G全部顶点一次回到起点的回路。
2算法
2.1递归回溯法求解哈密顿尔回路算法
2.1.1递归求图的所有哈密顿尔回路算法
1)解向量用数组X[1...n]表示;X[k]=0无合法顶点;X数组初始化为0;
2)若k=n时,需检查x[k]是否有边与x[1]相连(回到起点,构成回路)
3)用k=1启动(指定哈密顿回路的起点)
由此可得以下算法:
statushamilton(intk)
{
if(k>n-1&&c[x[k-1]][0]==1)
{
output(x);
flag=1;
}
else
for(inti=k;i { swap(x[k],x[i]); if(c[x[k-1]][x[k]]==1) hamilton(k+1); swap(x[i],x[k]); } } 2.2非递归回溯法求解哈密顿尔回路算法 2.2.1非递归回溯法求图的所有哈密顿尔回路算法 假定图G=(V,E)的顶点集为V={1,2,…,n},则哈密顿回路的可能解表示为n元组X=(x1,x2,…,xn),其中,xi∈{1,2,…,n},并有如下约束条件: 由此可得以下算法: 1.将顶点数组x[n]初始化为0,标志数组visited[n]初始化为0; 2.k=1;visited[1]=1;x[1]=1;从顶点1出发构造哈密顿回路; 3.while(k>=1) 3.1x[k]=x[k]+1,搜索下一个顶点; 3.2若(n个顶点没有被穷举)执行下列操作 3.2.1若(顶点x[k]不在哈密顿回路上&&(x[k-1],x[k])∈E), 转步骤3.3; 3.2.2否则,x[k]=x[k]+1,搜索下一个顶点; 3.3若数组x[n]已形成哈密顿路径,则输出数组x[n],算法结束; 3.4否则, 3.4.1若数组x[n]构成哈密顿路径的部分解, 则k=k+1,转步骤3; 3.4.2否则,重置x[k],k=k-1,取消顶点x[k]的访问标志, 转步骤3; 3设计方案 3.1整体设计方案 这两个算法是通过C++语言编程实现的,在主菜单栏可以分成三块: 1、递归求图的所有哈密顿回路2、非递归求图的所有哈密顿回路0、退出程序。 3.2程序递归算法的主要代码 voidhamilton(intk) {//递归算法 if(k>n-1&&c[x[k-1]][0]==1) { output(x); flag=1; } else for(inti=k;i { swap(x[k],x[i]); if(c[x[k-1]][x[k]]==1) hamilton(k+1); swap(x[i],x[k]); } } 3.3程序非递归算法的主要代码 voidhamilton(intn,intx[N],boolc[N][N]) {//非递归算法 inti,k; bool*visited=newbool[n]; for(i=0;i { x[i]=0; visited[i]=false; } visited[0]=1; x[0]=0;//默认以第一个城市开始 k=1;//搜索解空间树(子集树形式)直接从第二层开始 while(k>=1) { x[k]++; while(x[k] if(visited[x[k]]==0&&c[x[k-1]][x[k]]==1) break; else x[k]++; if(x[k] { for(k=0;k { cout< flag=1; } cout< k--; } elseif(x[k] =n-1) { visited[x[k]]=1; k++; } else { x[k]=0; k--; visited[x[k]]=0; } } } 3.4程序的其他函数 3.4.1输出函数主要代码 voidoutput(intx[]) {//输出函数 for(inti=0;i cout< cout< } 3.4.2建立邻接矩阵函数 voidCreat_M() {//建立邻接矩阵 memset(c,0,sizeof(c)); inti=0; cout<<"请输入图的结点数: "; cin>>n; cout<<"请输入"< "< for(i=0;i { for(intj=0;j { cin>>c[i][j]; } } } 4系统测试 首先进入VC++6.0,打开源程序文件“哈密顿回路(递归与非递归).cpp”,然后进入源程序,接着选择Build下的Executeperson.exe即可,也可以不打开工程,直接双击“哈密顿回路(递归与非递归).exe”也可以直接运行程序。 第一组: 0111 1011 1101 1110 第二组: 011 101 110 4.1测试数据 第一组数据位4阶完全图,第二组数据为3阶完全图。 4.2程序的录入、编译和连接 如图4.1所示。 图4.1源程序的录入、编译和连接 4.3运行程序 如图4.2所示。 图4.2运行程序 从图中可见程序能够成功的运行。 4.4进入主界面 如图4.3所示。 图4.3菜单界面 4.4测试递归回溯法求解图的所有哈密顿尔回路 首先输入操作1,显示如图4.4界面。 图4.4递归界面 输入第一组数据信息,为4阶矩阵。 如图4.5所示 图4.5递归回溯法求解哈密顿尔回路 从上图可见能够回溯法递归输出图的哈密顿尔回路功能。 4.5测试非递归回溯法求解图的所有哈密顿尔回路 在主界面下输入2号功能键,将显示读者所有已借图书信息。 如图4.6所示。 图4.6非递归回溯法求解哈密顿尔回路 程序与递归的结果一样,正确显示出4阶完全图的哈密顿尔回路,模块测试完成。 4.6测试第二组数据 按照测试第一组数据的步骤,测试第二组3阶完全图邻接矩阵。 测试结果分别如图4.7和4.8所示。 图4.7递归测试第二组数据结果 图4.8非递归测试第二组数据结果 如图可以说明,成功地输出了3阶完全图的哈密顿尔回路。 4.7测试退出模块 在主界面下输入0号功能键,观察结果。 图4.9所示。 图4.9程序退出 结论 本次课程设计的题目是用回溯法求解一般哈密顿尔回路问题,旨在了解回溯法以及用这种方法求解图中的哈密顿尔回路回路,方便我们寻找某些复杂的图形的哈密顿尔回路。 通过这次课程设计,使我了解了算法的设计与分析的重要性,使我明白了算法的设计和分析与当今社会的发展息息相关,并且提高了自身运用知识和变通知识的能力。 在这个课程设计中,我我首先通过课堂所学习的回溯法找出了简单的解哈密顿尔回路的方法,然后通过课后的资料使解法更加深入化,最后通过反复推敲得到了比较精确的解题算。 由此,我写了递归版和非递归版两个算法,这两个算法各有各的特点,但是其宗旨是不变的,就是运用回溯法解题,只是通过不同的数据结构表达出来。 最后,结合所学过的C++语言知识,编出来相对应的递归和非递归回溯法解哈密顿尔回路的程序,经测试我的算法和程序是正确的。 但是这个程序尚且不够完善,由于本人的水平有限,暂时无法使用MFC来实现可视化的界面,程序中也存在着很多可以延伸的问题有待解决。 总之,通过这次课程设计,不仅提高了自己的算法设计与分析能力,而且提高了对c++编程语言的操作水平。 虽然程序尚不完美,但是能将自己的知识运用到实际已经是很大的成功。 致谢 感谢谢春芝老师本学期对我课程设计的教导,感谢黄襄念老师辛勤栽培,他们给予了我莫大的支柱。 感谢我身边的同学们,感谢所有帮助过我的人。 如果没有你们的帮助,这次课程设计很难一个人完成,在此我致以衷心的谢意。 参考文献 [1]严蔚敏吴伟民著.《数据结构》(C语言版)(第三版).北京: 清华大学出版社2007.4 [2]谭浩强著.《C程序设计》(第三版).北京: 清华大学出版社;2006.9 [3]AnanyLevitin著.潘彦译《算法设计与分析基础》(第二版).北京: 清华大学出版社;2010.1 [4][美]S巴斯著.计算机算法: 设计和分析引论.朱洪等译上海: 复旦大学出版社;1985.1 附录 #include #include usingnamespacestd; #defineN20 boolc[N][N]; intx[N]; intn; boolflag=0; voidoutput(intx[]) {//输出函数 for(inti=0;i cout< cout< } voidhamilton(intk) {//递归算法 if(k>n-1&&c[x[k-1]][0]==1) { output(x); flag=1; } else for(inti=k;i { swap(x[k],x[i]); if(c[x[k-1]][x[k]]==1) hamilton(k+1); swap(x[i],x[k]); } } voidhamilton(intn,intx[N],boolc[N][N]) {//非递归算法 inti,k; bool*visited=newbool[n]; for(i=0;i { x[i]=0; visited[i]=false; } visited[0]=1; x[0]=0;//默认以第一个城市开始 k=1;//搜索解空间树(子集树形式)直接从第二层开始 while(k>=1) { x[k]++; while(x[k] if(visited[x[k]]==0&&c[x[k-1]][x[k]]==1) break; else x[k]++; if(x[k] { for(k=0;k { cout< flag=1; } cout< k--; } elseif(x[k] =n-1) { visited[x[k]]=1; k++; } else { x[k]=0; k--; visited[x[k]]=0; } } } voidCreat_M() {//建立邻接矩阵 memset(c,0,sizeof(c)); inti=0; cout<<"请输入图的阶数: "; cin>>n; cout<<"请输入"< "< for(i=0;i { for(intj=0;j { cin>>c[i][j]; } } } voidmenu() { intorder,i; cout<<"................................................................."< cout<<".......................菜单..............................."< cout<<"................................................................."< cout<<"....1回溯法求图的所有哈密顿回路(递归)...."< cout<<"....2回溯法求图的所有哈密顿回路(非递归)...."< cout<<"....0退出程序...."< cout<<"................................................................."< cout<<"................................................................."< cout<<"请输入您的操作: "; cin>>order; switch(order) { case1: system("cls"); cout<<"\t"<<"..........................创建邻接矩阵............................."< Creat_M(); cout<<"\t"<<"...............回溯法求图的所有哈密顿回路(递归).................."< for(i=0;i { x[i]=i; } hamilton (1); if(! flag) cout<<"无哈密顿回路! "< system("pause"); system("cls"); menu(); break; case2: system("cls"); cout<<"\t"<<"..........................创建邻接矩阵............................."< Creat_M(); cout<<"\t"<<"................回溯法求图的所有哈密顿回路(非递归)..............."< hamilton(n,x,c); if(! flag) cout<<"无哈密顿回路! "< system("pause"); system("cls"); menu(); break; case0: system("cls"); cout<<"\t"<<"..........................谢谢使用............................."< default: cout<<"输入命令有误,请重新输入;"< system("pause"); system("cls"); menu(); } } voidmain() { cout<<"\t"<<"....................欢迎进入哈密顿回路系统...................."< cout<<"\t"<<"........................."; system("pause"); system("cls"); menu(); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 回溯 求解 哈密尔顿 回路