动态规划法回溯法分支限界法求解TSP问题实验报告.docx
- 文档编号:10670557
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:30
- 大小:18.83KB
动态规划法回溯法分支限界法求解TSP问题实验报告.docx
《动态规划法回溯法分支限界法求解TSP问题实验报告.docx》由会员分享,可在线阅读,更多相关《动态规划法回溯法分支限界法求解TSP问题实验报告.docx(30页珍藏版)》请在冰豆网上搜索。
动态规划法回溯法分支限界法求解TSP问题实验报告
TSP问题算法实验报告
指导教师:
季晓慧
姓名:
辛瑞乾
学号:
提交日期:
2015年11月
总述......................................................................
动向规划法................................................................
算法问题剖析............................................................
算法设计................................................................
实现代码................................................................
输入输出截图............................................................
OJ提交截图..............................................................
算法优化剖析............................................................
回溯法....................................................................
算法问题剖析............................................................
算法设计................................................................
实现代码................................................................
输入输出截图............................................................
OJ提交截图..............................................................
算法优化剖析............................................................
分支限界法................................................................
算法问题剖析............................................................
算法设计................................................................
实现代码................................................................
输入输出截图............................................................
OJ提交截图..............................................................
算法优化剖析............................................................
总结......................................................................
总述
TSP问题又称为旅游商问题,是指一个旅游商要历经全部城市一次最后又
回到本来的城市,求最短行程或最小花销,解决TSP能够用好多算法,比方
蛮力法,动向规划法⋯详细的时间复杂的也各有差别,本次实验报告包括动
态规划法,回溯法以及分支限界法。
动向规划法
算法问题剖析
假定n个极点分别用0~n-1的数字编号,极点之间的代价寄存在数组
mp[n][n]中,下边考虑从极点0出发求解TSP问题的填表形式。
第一,按个
数为1、2、⋯、n-1的次序生成1~n-1个元素的子集寄存在数组x[2^n-1]
中,例如当n=4时,
x[1]={1},x[2]={2},x[3]={3},x[4]={1,2},x[5]={1,3},x[6]={2,3},x[7]=
{1,2,3}
。
设数组
dp[n][2^n-1]
寄存迭代结果,此中
dp[i][j]
表示从极点
i
经过子集
x[j]
中的极点一次且一次,最后回到出发点
0的最短路径长度,动
态规划法求解
TSP问题的算法以下。
算法设计
输入:
图的代价矩阵mp[n][n]
输出:
从极点0出发经过全部极点一次且仅一次再回到极点0的最短路径长
度
1.初始化第0列(动向规划的界限问题)for(i=1;i dp[i][0]=mp[i][0] 2.挨次办理每个子集数组x[2^n-1] for(i=1;i if(子集x[j]中不包括i) 对x[j]中的每个元素k,计算d[i][j]=min{mp[i][k]+dp[k][j-1]}; 2.输出最短路径长度。 实现代码 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #definedebug"outputfordebug\n" #definepi(acos) #defineeps(1e-8) #defineinf0x3f3f3f3f #definelllonglongint #definelsonl,m,rt<<1 #definersonm+1,r,rt<<1|1 usingnamespacestd; constintMax=100005; intn,mp[20][20],dp[20][40000]; intmain() { while(~scanf("%d",&n)) { intans=inf; memset(mp,0,sizeofmp); for(inti=0;i { for(intj=0;j { if(i==j) { mp[i][j]=inf; continue; } inttmp; scanf("%d",&tmp); mp[i][j]=tmp; } } intmx=(1<<(n-1)); dp[0][0]=0; for(inti=1;i { dp[i][0]=mp[i][0]; } dp[0][mx-1]=inf; for(intj=1;j<(mx-1);j++) { for(inti=1;i { if((j&(1<<(i-1)))==0) { intx,y=inf; for(intk=1;k { if((j&(1<<(k-1)))>0){ x=dp[k][(j-(1<<(k-1)))]+mp[i][k]; y=min(y,x); } } dp[i][j]=y; } } } dp[0][mx-1]=inf; for(inti=1;i dp[0][mx-1]=min(dp[0][mx-1],mp[0][i]+dp[i][(mx-1)-(1<<(i-1))]);printf("%d\n",dp[0][mx-1]); } return0; } 输入输出截图 OJ提交截图 算法优化剖析 该算法需要对极点会合{1,2,⋯,n-1}的每一个子集进行操作,所以时 间复杂度为O(2^n)。 和蛮力法对比,动向规划法求解TSP问题,把本来的时 间复杂度是O(n! )的摆列问题,转变为组合问题,进而降低了算法的时间复 杂度,但仍需要指数时间。 回溯法 算法问题剖析 回溯法求解TSP问题,第一把全部的极点的接见标记初始化为0,而后在解空间树中从根节点出发开始搜寻,假如从根节点到目前结点对应一个部分解,即知足上述拘束条件,则在目前结点处选择第一棵子树持续搜寻,不然,对目前子树的兄弟结点进行搜寻,假如目前结点的全部子树都已试试过而且发生矛盾,则回溯到目前结点的父节点。 采纳毗邻矩阵mp[n][n]储存极点之 间边的状况,为防止在函数间传达参数,将数组mp设置为全局变量,设数组x[n]表示哈密顿回路经过的极点。 算法设计 输入: 无向图G=(V,E) 输出: 哈密顿回路 1、将极点数组x[n]初始化为0,标记数组vis[n]初始化为0; 2、从极点0出发结构哈密顿回路: vis[0]=1;x[0]=1;k=1; 3、While(k>=1) 、x[k]=x[k]+1,搜寻下一个极点。 、若n个极点没有被穷举完,则履行以下操作 ∈E,转步骤; 、若数组x[n]已经形成哈密顿路径,则输出数组x[n],算法结束;、若数组x[n]组成哈密顿路径的部分解,则k=k+1,转步骤3; 、不然,撤消极点x[k]的接见标记,重置x[k],k=k-1,转步骤3。 实现代码 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #definedebug"outputfordebug\n" #definepi(acos) #defineeps(1e-8) #defineinf0x3f3f3f3f #definelllonglongint #definelsonl,m,rt<<1 #definersonm+1,r,rt<<1|1 usingnamespacestd; intmp[20][20]; intx[30],vis[30]; intn,k,cur,ans; voidinit() { for(inti=0;i for(intj=0;j mp[i][j]=-1; ans=-1;cur=0; for(inti=1;i<=n;i++)x[i]=i; } voiddfs(intt) { if(t==n) { if(mp[x[n-1]][x[n]]! =-1&&(mp[x[n]][1]! =-1)&&(cur+mp[x[n-1]][x[n]]+mp[x[n]][1] { for(inti=1;i<=n;i++) vis[i]=x[i]; ans=cur+mp[x[n-1]][x[n]]+mp[x[n]][1]; } } else { for(inti=t;i<=n;i++) { if(mp[x[t-1]][x[i]]! =-1&&(cur+mp[x[t-1]][x[i]] { swap(x[t],x[i]); cur+=mp[x[t-1]][x[t]]; dfs(t+1); cur-=mp[x[t-1]][x[t]]; swap(x[t],x[i]); } } } } intmain() { while(~scanf("%d",&n)) { init(); for(inti=1;i<=n;i++) { for(intj=1;j<=n;j++) { if(i==j) continue; scanf("%d",&mp[i][j]); } } egin(); sum+=*it; it++; sum+=*it; } returnsum/2; } intgao(nodes) { intres=*2; intt1=inf,t2=inf; for(inti=1;i<=n;i++) { if(! [i]) { t1=min(t1,mp[i][]); t2=min(t2,mp[][i]); } } res+=t1; res+=t2; inttmp; for(inti=1;i<=n;i++) { tmp=inf; if(! [i]) { it=Mp[i].begin(); res+=*it; for(intj=1;j<=n;j++) tmp=min(tmp,mp[j][i]); res+=tmp; } } return! (res%2)? (res/2): (res/2+1); } voidbfs(nodes) { (s); while(! ()) { nodehead=(); (); if==n-1) { intp; for(inti=1;i<=n;i++) { if(! [i]) { p=i; break; } } intcnt=+mp[p][]+mp[][p]; nodetmp=(); if(cnt<= { ans=min(ans,cnt); return; } else { up=min(up,cnt); ans=min(ans,cnt); continue; } } nodetmp; for(inti=1;i<=n;i++) { if(! [i]) { =; =+mp[][i]; =i; =+1; for(intj=1;j<=n;j++)[j]=[j]; [i]=1; =gao(tmp); if<=up) (tmp); } } } } intmain() { while(~scanf("%d",&n)) { for(inti=0;i<=n;i++) Mp[i].clear(); for(inti=1;i<=n;i++) { for(intj=1;j<=n;j++) { if(i! =j) { scanf("%d",&mp[i][j]); Mp[i].push_back(mp[i][j]); } else mp[i][j]=inf; } sort(Mp[i].begin(),Mp[i].end()); } memset(vis,0,sizeofvis); vis[1]=1; up=0; up+=getup(1,1,up); low=getlow(); nodefir; =1; =1; =1; for(inti=1;i<=n;i++)[i]=0; [1]=1; =0; =low; ans=inf; bfs(fir); printf("%d\n",ans); } return0; } 输入输出截图 OJ提交截图 算法优化剖析 分支限界法的复杂度是依据数据的不一样而不一样,搜寻的节点越少,复杂 度越低,跟目标函数的选择有很大关系。 目标函数值的计算也会需要一准时 间,比方此文章中的目标函数值求解的复杂度是O(n^2)。 自然此算法仍旧 有能够优化的地方,比方在记录该路径每个叶子结点的孩子结点时能够采纳 二进制的思想,进而使算法的时间复杂度在降落到目前T/n的数目级,解决 COJ1814问题应当不可问题。 总结 TSP问题在好多地方都能够运用到,而且好多问题都是由TSP问题延长和 发展的,也能够称之为TSP问题,可是其思路大概相像,于是我们能够运用 已学过的算法对其进行解决。 我在学习算法课从前的TSP问题多数用动向规 划以及回溯法,究其时间复杂度以及代码的复杂度比较低,思路比较清楚, 在解决此类延长问题时简单调试和改正。 学完算法后最有感想的一点就是, 算法的精华其实不在于其方式方法,而在于其思想思路。 有了算法的思想,那 么耳濡目染中问题就能够获得解决。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态 规划 回溯 分支 限界 求解 TSP 问题 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)