动态规划法回溯法分支限界法求解TSP问题实验报告.docx
- 文档编号:563316
- 上传时间:2022-10-11
- 格式:DOCX
- 页数:17
- 大小:112.33KB
动态规划法回溯法分支限界法求解TSP问题实验报告.docx
《动态规划法回溯法分支限界法求解TSP问题实验报告.docx》由会员分享,可在线阅读,更多相关《动态规划法回溯法分支限界法求解TSP问题实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
动态规划法回溯法分支限界法求解TSP问题实验报告
TSP问题算法实验报告
指导教师:
季晓慧
姓名:
辛瑞乾
学号:
1004131114
提交日期:
2015年11月
总述
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]}; 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(-1.0)) #defineeps(1e-8) #defineinf0x3f3f3f3f #definelllonglongint #definelsonl,m,rt<<1 #definersonm+1,r,rt<<1|1 usingnamespacestd; constintmod=1000000007; 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) 3.1、x[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、若数组x[n]构成哈密顿路径的部分解,则k=k+1,转步骤3; 3.5、否则,取消顶点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(-1.0)) #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]); } } ///puts("YES"); dfs (2); cout< } return0; } 输入输出截图 OJ提交截图 算法优化分析 在哈密顿回路的可能解中,考虑到约束条件xi! =xj(1<=I,j<=n,i! =j),则可能解应该是(1,2,…,n)的一个排列,对应的解空间树种至少有n! 个叶子结点,每个叶子结点代表一种可能解。 当找到可行的最优解时,算法停止。 分支限界法 算法问题分析 分支限界法解决TSP问题首先确定目标函数的界[down,up],可以采用贪心法确定TSP问题的一个上界。 如何求得TSP问题的一个合理的下界呢? 对于无向图的代价矩阵,吧矩阵中每一行最小的元素想家,可以得到一个简单的下界,但是还有一个信息量更大的下界: 考虑一个TSP问题的完整解,在每条路径上,每个城市都有两条邻接边,一条是进入这个城市的,另一条是离开这个城市的,那么,如果把矩阵中每一行最小的两个元素相加在除以2,假设图中所有的代价都是整数,再对这个结果向上取整,就得到一个合理的下界。 需要强调的是,这个解可能不是一个可行解(可能没有构成哈密顿回路),但给出了一个参考下界。 一般情况下,假设当前已确定的路径为U=(r1,r2,…,rk),即路径上已确定了k个顶点,此时,该部分解的目标函数值的计算方法(限界函数)如下: L
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态 规划 回溯 分支 限界 求解 TSP 问题 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)