TSP旅行商问题的C++解决方案
2010-12-26 20:50
676 查看
首先解释下什么是TSP问题。
TSP问题是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。各个城市间的距离可以用代价矩阵来表示。
![](http://hi.csdn.net/attachment/201012/26/0_1293367820Slbp.gif)
假设从顶点i出发,令d(i, V')表示从顶点i出发经过V'中各个顶点一次且仅一次,最后回到出发点i的最短路径长度,开始时,V'=V-{i},于是,TSP问题的动态规划函数为:
d(i,V')=min{cik+d(k,V-{k})}(k∈V') d(k,{})=cki(k≠i)
城市0出发经城市1、2、3然后回到城市0的最短路径长度是:
d(0,{1, 2, 3})=min{c01+d(1, { 2, 3}), c02+d(2, {1, 3}), c03+d(3, {1, 2})}
这是最后一个阶段的决策,而:
d(1, {2, 3})=min{c12+d(2, {3}), c13+ d(3, {2})}
d(2, {1, 3})=min{c21+d(1, {3}), c23+ d(3, {1})}
d(3, {1, 2})=min{c31+d(1, {2}), c32+ d(2, {1})}
这一阶段的决策又依赖于下面的计算结果:
d(1, {2})= c12+d(2, {}) d(2, {3})=c23+d(3, {})
d(3, {2})= c32+d(2, {}) d(1, {3})= c13+d(3, {})
d(2, {1})=c21+d(1, {}) d(3, {1})=c31+d(1, {})
最后填表如下图即程序中数组d
![](http://hi.csdn.net/attachment/201012/26/0_1293367821mHH2.gif)
TSP问题是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。各个城市间的距离可以用代价矩阵来表示。
![](http://hi.csdn.net/attachment/201012/26/0_1293367820Slbp.gif)
假设从顶点i出发,令d(i, V')表示从顶点i出发经过V'中各个顶点一次且仅一次,最后回到出发点i的最短路径长度,开始时,V'=V-{i},于是,TSP问题的动态规划函数为:
d(i,V')=min{cik+d(k,V-{k})}(k∈V') d(k,{})=cki(k≠i)
城市0出发经城市1、2、3然后回到城市0的最短路径长度是:
d(0,{1, 2, 3})=min{c01+d(1, { 2, 3}), c02+d(2, {1, 3}), c03+d(3, {1, 2})}
这是最后一个阶段的决策,而:
d(1, {2, 3})=min{c12+d(2, {3}), c13+ d(3, {2})}
d(2, {1, 3})=min{c21+d(1, {3}), c23+ d(3, {1})}
d(3, {1, 2})=min{c31+d(1, {2}), c32+ d(2, {1})}
这一阶段的决策又依赖于下面的计算结果:
d(1, {2})= c12+d(2, {}) d(2, {3})=c23+d(3, {})
d(3, {2})= c32+d(2, {}) d(1, {3})= c13+d(3, {})
d(2, {1})=c21+d(1, {}) d(3, {1})=c31+d(1, {})
最后填表如下图即程序中数组d
![](http://hi.csdn.net/attachment/201012/26/0_1293367821mHH2.gif)
/*author caoxulei 2010.12.26 20:38 email caoxulei921@gmail.com*/ #include <iostream> #include <cmath> using namespace std; #define N 4 #define M 8 #define MAX 1000 int V_rmv(int k,int arr[N-1],int V[M][N-1])//返回{{V}-k}其d数组的列号 { int i; int temp_arry[N-1]; for(i=0;i<N-1;i++) if(arr[i]==k) temp_arry[i]=0; else temp_arry[i]=arr[i]; for(i=0;i<M;i++) if(V[i][0]==temp_arry[0]&&V[i][1]==temp_arry[1]&&V[i][2]==temp_arry[2]) break; return i; } void TSP_Rsult(int c ,int d [8],int V[M][N-1])//打印最小路径,填写d数组最后一列 { for(int k=0;k<3;k++){ if((c[0][V[M-1][k]] + d[V[M-1][k]][V_rmv(V[M-1][k],V[M-1],V)])< d[0][M-1]){ d[0][M-1] = c[0][V[M-1][k]] + d[V[M-1][k]][V_rmv(V[M-1][k],V[M-1],V)]; } } cout<<"The least road is "<<d[0][M-1]<<endl; } void TSP(int c ,int d [8],int V[M][N-1])//计算d数组中各列需要填写的值 { for(int j=1;j<M-1;j++) for(int i=1;i<N;i++) if(i!=V[j][0]&&i!=V[j][1]&&i!=V[j][2]){ for(int k=0;k<3;k++){ if((V[j][k]!= 0)&&((c[i][V[j][k]] + d[V[j][k]][V_rmv(V[j][k],V[j],V)])< d[i][j])) d[i][j] = c[i][V[j][k]] + d[V[j][k]][V_rmv(V[j][k],V[j],V)]; } } TSP_Rsult(c,d,V); } int main(){ int c ={{MAX,3,6,7},{5,MAX,2,3},{6,4,MAX,2},{3,7,5,MAX}}; int d [M]={0}; for(int i=0; i<N; i++) for(int j=0; j<M; j++) d[i][j]=MAX; //假设1000为无穷大 int V[8][3]={ 0,0,0, 1,0,0, 0,2,0, 0,0,3, 1,2,0, 1,0,3, 0,2,3, 1,2,3, }; for(int i=1;i<N;i++) d[i][0]=c[i][0]; TSP(c,d,V); return 0; }
相关文章推荐
- (C语言)分支界限法求解旅行商(TSP)问题
- C++中动态内存分配引发问题的解决方案(二)
- 【ACMclub周赛5】Problem E——TSP旅行商问题
- C/C++字符串,字符数组,字符指针及其相互静态拷贝与追加的安全问题解决方案(2)
- C++数据精度问题的解决方案(对浮点数保存指定位小数)
- 清华OJ TSP旅行商问题
- 欧几里得旅行商问题 java与c++实现
- (C语言)分支界限法求解旅行商(TSP)问题
- c++智能指针循环引用带来的问题及解决方案
- ACO蚁群算法解决TSP旅行商问题
- TSP(旅行商问题)-状压dp
- AYITACM2016省赛第三周 G - Unidirectional TSP(DP单向旅行商问题)
- 模拟退火算法解旅行商(TSP)问题
- 总结sublime c++编译环境搭建 | 中文乱码问题解决方案 |sidebar配置 |sublime最佳插件列表|最佳主题方案
- C++中动态内存分配引发问题的解决方案
- 基于分支限界法的旅行商问题(TSP)二
- C++头文件重复包含问题分析及解决方案
- TSP 旅行商问题(状态压缩dp)
- C++内存泄漏——C++中动态内存分配引发问题的解决方案(1)
- 遗传算法 求解旅行商 TSP 问题,matlab代码