用动态规划方法旅行商问题(TSP问题)
2007-12-04 21:50
330 查看
某推销员要从城市v1 出发,访问其它城市v2,v3,…,v6 各一次且仅一次,最后返回v1。D
为各城市间的距离矩阵。
问:该推销员应如何选择路线,才能使总的行程最短?
以下是用动态规划方法,Linux下g++编译通过
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#include <iostream>
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#include <set>
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#include <vector>
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#define MAX 6
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
using namespace std;
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
int dis[MAX][MAX]=...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
0, 10, 20, 30, 40, 50,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
12, 0 ,18, 30, 25, 21,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
23, 19, 0, 5, 10, 15,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
34, 32, 4, 0, 8, 16,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
45, 27, 11,10, 0, 18,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
56, 22, 16,20, 12, 0
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
};
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef struct
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int curcity;//当前所在的城市
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int> unvisited;//当前未访问的城市
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
set<int> type;//由于set自动排序,相同状态的vector可能不同,但set必然相同
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int distance;//从当前城市到终点回到起点的距离
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}status;
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
/**//*测试用*/
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
void printVec( vector<status> vec)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator it;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter=vec.begin();iter!=vec.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<(*iter).curcity<<" <";
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(it=(*iter).unvisited.begin();it!=(*iter).unvisited.end();it++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<*it<<" ";
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<">"<<" distance:"<<(*iter).distance<<endl;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
//看看当前状态的城市中是否包括城市i
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
bool contain(int i, status &sta)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(i==sta.curcity)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return true;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
else
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter=sta.unvisited.begin();iter!=sta.unvisited.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(i==*iter)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return true;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return false;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
/**//*合并相同状态*/
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
vector<status> combine(vector<status> vec)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status> new_vec;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status temp;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
while(vec.size()>0)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter=vec.begin();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
temp=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vec.erase(iter);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(;iter!=vec.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if((temp.curcity==(*iter).curcity)&&(temp.type==(*iter).type))
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if((*iter).distance<temp.distance)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
temp=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter=vec.erase(iter);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter--;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_vec.push_back(temp);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return new_vec;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
int main()
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status> pre_vector;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status> cur_vector;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//从后往前推,初始化
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(int i=1;i<MAX;i++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status sta;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
sta.curcity=i;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
sta.distance=dis[i][0];
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector.push_back(sta);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//依次递推,递推MAX-2次
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
for(int j=0;j<MAX-2;j++)...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
pre_vector=cur_vector;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector.clear();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(int i=1;i<MAX;i++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter=pre_vector.begin();iter!=pre_vector.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status temp=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(contain(i,temp)==false)//为确保状态中没有重复路径
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status new_stat=temp;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator int_iter=new_stat.unvisited.begin();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.unvisited.insert(int_iter,new_stat.curcity);//加入vector
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.type.insert(new_stat.curcity);//加入set
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.distance+=dis[i][new_stat.curcity];//计算距离
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.curcity=i;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector.push_back(new_stat);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//记录相同状态最短路径,并合并相同状态
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector=combine(cur_vector);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}//end for
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//printVec(cur_vector);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//递推完毕后,最后一步,计算起点到每个状态的距离,找到最短路径
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter=cur_vector.begin();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status shortest=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int min_dis=shortest.distance+dis[0][shortest.curcity];
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter++;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(;iter!=cur_vector.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int temp_dis=dis[0][(*iter).curcity]+(*iter).distance;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(temp_dis<min_dis)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
min_dis=temp_dis;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
shortest=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//打印结果
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator iter_city;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<"minimum distance is "<<min_dis<<endl;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<"the shortest path is "<<"1 "<<shortest.curcity+1;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter_city=shortest.unvisited.begin();iter_city!=shortest.unvisited.end();iter_city++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<" "<<*iter_city+1;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<" 1"<<endl;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
运行结果如下
minimum distance is 80
the shortest path is 12 6 5 4 3 1
注意:动态规划方法并不是解决TSP问题的一个好方法,因其占用空间和时间复杂度均较大。
相关资料(从网上摘抄,注意所举例子的数据与程序不同):
设有n个城市, 其中每两个城市之间都有道路相连,城市i和城市j之间的距离为Cij。从某城市出发周游所有城市,经过每个城市一次且仅一次,最后回到出发地,求总行程最短的周游路线。对于一般的情况可以假设两城市之间往返距离不相等。在此例中,为了简化问题,设往返距离相等,即Cij=Cji。
这就是所谓的货郎担问题(Traveling Salesman Problem,简称TSP)。这个问题与最短路径问题不同,最短路径问题以当前所在的位置作为状态变量,而在货郎担问题中,状态变量除了要指明当前所在位置外,还要指明已经经过哪几个城市。
由于货郎担问题经过的路线是一条经过所有城市的闭合回路,因此从哪一点出发是无所谓的,因此不妨设从城市1出发。
问题的动态规划模型构造如下:
阶段k:已经历过的城市个数,包括当前所在的城市。k=1, 2, …, n , n+1,k=1表示出发时位于起点,k=n+1表示结束时回到终点。
状态变量:xk=(i, Sk),其中i表示当前所在的城市,Sk表示尚未访问过的城市的集合。很明显
S1={2,3,…,n},…,Sn=Sn+1=F
其中F表示空集。并且有
xn=(i, F) i=2,3,…,n, xn+1=(1, F)
决策变量:dk=( i , j ),其中i为当前所在的城市,j为下一站将要到达的城市。
状态转移方程:若当前的状态为
xk=( i ,Sk)
采取的决策为
dk=( i , j )
则下一步到达的状态为
xk+1=T(xk,dk)=( j ,Sk/ {j})
阶段指标:vk(xk,dk)=Cij
最优指标函数:fk(xk)=fk(i,Sk) 表示从城市i出发,经过Sk中每个城市一次且仅一次,最后返回城市1的最短距离。
终端条件:fn+1(xn+1)=fn+1(1, F)=0
对于如图3.7.1所示的一个五个城市的货郎担问题,求解步骤如下:
对于k=5,有
f5(i, F)=min{Cij+f6(1, F)}=Ci1 i=2,3,4,5
d5Î(i,1)
f5(I,F)的值列表如下:
i f5(i, F)
2 2
3 7
4 2
5 5
对于k=4,有
f4(i, S4)=min{Cij+f5(j,S5)}
jÎS4
f4(i,S4)的值列表如下:
(i,S4) j Cij S5 Cij+f5(j,S5) f4(i,S4) j*
(2,{3}) {3} 3 F 3+f5(3,F)=3+7=10 10 3
(2,{4}) {4} 5 F 5+f5(4,F)=5+2=7 7 4
(2,{5}) {5} 1 F 1+f5(5,F)=1+5=6 6 5
(3,{2}) {2} 3 F 3+f5(2,F)=3+2=5 5 2
(3,{4}) {4} 4 F 4+f5(4,F)=4+2=6 6 4
(3,{5}) {5} 6 F 6+f5(5,F)=6+5=11 11 5
(4,{2}) {2} 5 F 5+f5(2,F)=5+2=7 7 2
(4,{3}) {3} 4 F 4+f5(3,F)=4+7=11 11 3
(4,{5}) {5} 3 F 3+f5(5,F)=3+5=8 8 5
(5,{2}) {2} 1 F 1+f5(2,F)=1+2=3 3 2
(5,{3}) {3} 6 F 6+f5(3,F)=6+7=13 13 3
(5,{4}) {4} 3 F 3+f5(4,F)=3+2=5 5 4
对于k=3,有
f3(i,S3)=min{Cij+f4(j,S4)}
jÎS3
f3(i,S3)的值列表如下:
(i,S3) j Cij S4 Cij+f4(j,S4) f3(i,S3) j*
(2,{3,4}) {3}{4} 35 {4}{3} 3+f4(3,{4})=3+6=9*5+f4(4,{3})=5+11=16 9 3
(2,{3,5}) {3}{5} 31 {5}{3} 3+f4(3,{5})=3+11=14*1+f4(5,{3})=1+13=14* 14 3,5
(2,{4,5}) {4}{5} 51 {5}{4} 5+f4(4,{5})=5+8=131+f4(5,{4})=1+5=6* 6 5
(3,{2,4}) {2}{4} 34 {4}{2} 3+f4(2,{4})=3+7=10*4+f4(4,{2})=4+7=11 10 2
(3,{2,5}) {2}{5} 36 {5}{2} 3+f4(2,{5})=3+6=9*6+f4(5,{2})=6+3=9* 9 2,5
(3,{4,5}) {4}{5} 46 {5}{4} 4+f4(4,{5})=4+8=126+f4(5,{4})=6+5=11* 11 5
(4,{2,3}) {2}{3} 54 {3}{2} 5+f4(2,{3})=5+10=154+f4(3,{2})=4+5=9* 9 3
(4,{2,5}) {2}{5} 53 {5}{2} 5+f4(2,{5})=5+6=113+f4(5,{2})=3+3=6* 6 5
(4,{3,5}) {3}{5} 43 {5}{3} 4+f4(3,{5})=4+11=15*3+f4(5,{3})=3+13=16 15 3
(5,{2,3}) {2}{3} 16 {3}{2} 1+f4(2,{3})=1+10=11*6+f4(3,{2})=6+5=11* 11 2,3
(5,{2,4}) {2}{4} 13 {4}{2} 1+f4(2,{4})=1+7=8*3+f4(4,{2})=3+7=10 8 2
(5,{3,4}) {3}{4} 63 {4}{3} 6+f4(3,{4})=6+6=12*3+f4(4,{3})=3+11=14 12 3
对于k=2有
(i,S2) j Cij S3 Cij+f3(j,S3) f2(i,S2) j*
(2,{3,4,5}) {3}{4}{5} 351 {4,5}{3,5}{3,4} 3+f3(3,{4,5})=3+11=145+f3(4,{3,5})=5+15=201+f3(5,{3,4})=1+12=13* 13 5
(3,{2,4,5}) {2}{4}{5} 346 {4,5}{3,5}{2,4} 3+f3(2,{4,5})=3+6=9*4+f3(4,{2,5})=4+6=106+f3(5,{2,4})=6+8=14 9 2
(4,{2,3,5}) {2}{3}{5} 543 {3,5}{2,5}{2,3} 5+f3(2,{3,5})=5+14=194+f3(3,{2,5})=4+9=13*3+f3(5,{2,3})=3+11=14 13 3
(5,{2,3,4}) {2}{3}{4} 163 {3,4}{2,4}{2,3} 1+f3(2,{3,4})=1+9=10*6+f3(3,{2,4})=6+10=163+f3(4,{2,3})=3+9=12 10 2
对于k=1,有
f1(1,S1)=min{C1j+f2(j,S2)}
f1(1,S1)的值列表如下:
(1,S1) j Cij S2 Cij+f2(j,S2) f1(1,S1) j*
(1,{2,3,4,5}) {2}{3}{4}{5} 2725 {3,4,5}{2,4,5}{2,3,5}{2,3,4} 2+f2(2,{3,4,5})=2+13=15*7+f2(3,{2,4,5})=7+9=162+f2(4,{2,3,5})=2+13=15*5+f2(5,{2,3,4})=5+10=15* 15 2,4,5
由状态x1=(1,{2,3,4,5})开始回朔,得到
(1,{2,3,4,5})
j*=2 j*=5 j*=4
(2,{3,4,5}) (5,{2,3,4}) (4{2,3,5})
j*=5 j*=2 j*=3
(5,{3,4}) (2,{3,4}) (3,{2,5})
j*=3 j*=3 j*=2 j*=5
(3,{4}) (3,{4}) (2,{5}) (5,{2})
j*=4 j*=4 j*=4 j*=2
(4,Φ) (4, Φ) (5, Φ) (2, Φ)
即得到以下四条回路:
(1) ①à②à⑤à③à④à①
(2) ①à⑤à②à③à④à①
(3) ①à④à③à②à⑤à①
(4) ①à④à③à⑤à②à①
其中(1)和(4)是同一条回路,(2)和(3)是同一条回路,这两条回路的图示如下:
容易验证,两条回路的长度都是15。
为各城市间的距离矩阵。
问:该推销员应如何选择路线,才能使总的行程最短?
以下是用动态规划方法,Linux下g++编译通过
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#include <iostream>
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#include <set>
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#include <vector>
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
#define MAX 6
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
using namespace std;
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
int dis[MAX][MAX]=...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
0, 10, 20, 30, 40, 50,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
12, 0 ,18, 30, 25, 21,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
23, 19, 0, 5, 10, 15,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
34, 32, 4, 0, 8, 16,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
45, 27, 11,10, 0, 18,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
56, 22, 16,20, 12, 0
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
};
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef struct
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int curcity;//当前所在的城市
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int> unvisited;//当前未访问的城市
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
set<int> type;//由于set自动排序,相同状态的vector可能不同,但set必然相同
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int distance;//从当前城市到终点回到起点的距离
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}status;
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
/**//*测试用*/
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
void printVec( vector<status> vec)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator it;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter=vec.begin();iter!=vec.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<(*iter).curcity<<" <";
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(it=(*iter).unvisited.begin();it!=(*iter).unvisited.end();it++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<*it<<" ";
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<">"<<" distance:"<<(*iter).distance<<endl;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
//看看当前状态的城市中是否包括城市i
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
bool contain(int i, status &sta)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(i==sta.curcity)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return true;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
else
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter=sta.unvisited.begin();iter!=sta.unvisited.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(i==*iter)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return true;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return false;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
/**//*合并相同状态*/
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
vector<status> combine(vector<status> vec)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status> new_vec;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status temp;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
while(vec.size()>0)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter=vec.begin();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
temp=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vec.erase(iter);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(;iter!=vec.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if((temp.curcity==(*iter).curcity)&&(temp.type==(*iter).type))
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if((*iter).distance<temp.distance)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
temp=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter=vec.erase(iter);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter--;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_vec.push_back(temp);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return new_vec;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015/2015030196/6810355c2f78c12e91b7997a8e8c583a.gif)
int main()
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/1327ab569c1ae82736693a50b8e33378.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status> pre_vector;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status> cur_vector;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//从后往前推,初始化
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(int i=1;i<MAX;i++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status sta;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
sta.curcity=i;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
sta.distance=dis[i][0];
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector.push_back(sta);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//依次递推,递推MAX-2次
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
for(int j=0;j<MAX-2;j++)...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
pre_vector=cur_vector;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector.clear();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(int i=1;i<MAX;i++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter=pre_vector.begin();iter!=pre_vector.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status temp=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(contain(i,temp)==false)//为确保状态中没有重复路径
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status new_stat=temp;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator int_iter=new_stat.unvisited.begin();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.unvisited.insert(int_iter,new_stat.curcity);//加入vector
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.type.insert(new_stat.curcity);//加入set
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.distance+=dis[i][new_stat.curcity];//计算距离
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
new_stat.curcity=i;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector.push_back(new_stat);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//记录相同状态最短路径,并合并相同状态
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cur_vector=combine(cur_vector);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}//end for
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//printVec(cur_vector);
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//递推完毕后,最后一步,计算起点到每个状态的距离,找到最短路径
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<status>::iterator iter=cur_vector.begin();
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
status shortest=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int min_dis=shortest.distance+dis[0][shortest.curcity];
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
iter++;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(;iter!=cur_vector.end();iter++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
int temp_dis=dis[0][(*iter).curcity]+(*iter).distance;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(temp_dis<min_dis)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/7ff8d92cded7e0ce15e7ca1acc870052.gif)
...{
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
min_dis=temp_dis;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
shortest=*iter;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201104/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
//打印结果
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
vector<int>::iterator iter_city;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<"minimum distance is "<<min_dis<<endl;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<"the shortest path is "<<"1 "<<shortest.curcity+1;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(iter_city=shortest.unvisited.begin();iter_city!=shortest.unvisited.end();iter_city++)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<" "<<*iter_city+1;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<" 1"<<endl;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201109/0196c3df5ea9e936f21e9932cca91014.gif)
}
运行结果如下
minimum distance is 80
the shortest path is 12 6 5 4 3 1
注意:动态规划方法并不是解决TSP问题的一个好方法,因其占用空间和时间复杂度均较大。
相关资料(从网上摘抄,注意所举例子的数据与程序不同):
设有n个城市, 其中每两个城市之间都有道路相连,城市i和城市j之间的距离为Cij。从某城市出发周游所有城市,经过每个城市一次且仅一次,最后回到出发地,求总行程最短的周游路线。对于一般的情况可以假设两城市之间往返距离不相等。在此例中,为了简化问题,设往返距离相等,即Cij=Cji。
这就是所谓的货郎担问题(Traveling Salesman Problem,简称TSP)。这个问题与最短路径问题不同,最短路径问题以当前所在的位置作为状态变量,而在货郎担问题中,状态变量除了要指明当前所在位置外,还要指明已经经过哪几个城市。
由于货郎担问题经过的路线是一条经过所有城市的闭合回路,因此从哪一点出发是无所谓的,因此不妨设从城市1出发。
问题的动态规划模型构造如下:
阶段k:已经历过的城市个数,包括当前所在的城市。k=1, 2, …, n , n+1,k=1表示出发时位于起点,k=n+1表示结束时回到终点。
状态变量:xk=(i, Sk),其中i表示当前所在的城市,Sk表示尚未访问过的城市的集合。很明显
S1={2,3,…,n},…,Sn=Sn+1=F
其中F表示空集。并且有
xn=(i, F) i=2,3,…,n, xn+1=(1, F)
决策变量:dk=( i , j ),其中i为当前所在的城市,j为下一站将要到达的城市。
状态转移方程:若当前的状态为
xk=( i ,Sk)
采取的决策为
dk=( i , j )
则下一步到达的状态为
xk+1=T(xk,dk)=( j ,Sk/ {j})
阶段指标:vk(xk,dk)=Cij
最优指标函数:fk(xk)=fk(i,Sk) 表示从城市i出发,经过Sk中每个城市一次且仅一次,最后返回城市1的最短距离。
终端条件:fn+1(xn+1)=fn+1(1, F)=0
对于如图3.7.1所示的一个五个城市的货郎担问题,求解步骤如下:
对于k=5,有
f5(i, F)=min{Cij+f6(1, F)}=Ci1 i=2,3,4,5
d5Î(i,1)
f5(I,F)的值列表如下:
i f5(i, F)
2 2
3 7
4 2
5 5
对于k=4,有
f4(i, S4)=min{Cij+f5(j,S5)}
jÎS4
f4(i,S4)的值列表如下:
(i,S4) j Cij S5 Cij+f5(j,S5) f4(i,S4) j*
(2,{3}) {3} 3 F 3+f5(3,F)=3+7=10 10 3
(2,{4}) {4} 5 F 5+f5(4,F)=5+2=7 7 4
(2,{5}) {5} 1 F 1+f5(5,F)=1+5=6 6 5
(3,{2}) {2} 3 F 3+f5(2,F)=3+2=5 5 2
(3,{4}) {4} 4 F 4+f5(4,F)=4+2=6 6 4
(3,{5}) {5} 6 F 6+f5(5,F)=6+5=11 11 5
(4,{2}) {2} 5 F 5+f5(2,F)=5+2=7 7 2
(4,{3}) {3} 4 F 4+f5(3,F)=4+7=11 11 3
(4,{5}) {5} 3 F 3+f5(5,F)=3+5=8 8 5
(5,{2}) {2} 1 F 1+f5(2,F)=1+2=3 3 2
(5,{3}) {3} 6 F 6+f5(3,F)=6+7=13 13 3
(5,{4}) {4} 3 F 3+f5(4,F)=3+2=5 5 4
对于k=3,有
f3(i,S3)=min{Cij+f4(j,S4)}
jÎS3
f3(i,S3)的值列表如下:
(i,S3) j Cij S4 Cij+f4(j,S4) f3(i,S3) j*
(2,{3,4}) {3}{4} 35 {4}{3} 3+f4(3,{4})=3+6=9*5+f4(4,{3})=5+11=16 9 3
(2,{3,5}) {3}{5} 31 {5}{3} 3+f4(3,{5})=3+11=14*1+f4(5,{3})=1+13=14* 14 3,5
(2,{4,5}) {4}{5} 51 {5}{4} 5+f4(4,{5})=5+8=131+f4(5,{4})=1+5=6* 6 5
(3,{2,4}) {2}{4} 34 {4}{2} 3+f4(2,{4})=3+7=10*4+f4(4,{2})=4+7=11 10 2
(3,{2,5}) {2}{5} 36 {5}{2} 3+f4(2,{5})=3+6=9*6+f4(5,{2})=6+3=9* 9 2,5
(3,{4,5}) {4}{5} 46 {5}{4} 4+f4(4,{5})=4+8=126+f4(5,{4})=6+5=11* 11 5
(4,{2,3}) {2}{3} 54 {3}{2} 5+f4(2,{3})=5+10=154+f4(3,{2})=4+5=9* 9 3
(4,{2,5}) {2}{5} 53 {5}{2} 5+f4(2,{5})=5+6=113+f4(5,{2})=3+3=6* 6 5
(4,{3,5}) {3}{5} 43 {5}{3} 4+f4(3,{5})=4+11=15*3+f4(5,{3})=3+13=16 15 3
(5,{2,3}) {2}{3} 16 {3}{2} 1+f4(2,{3})=1+10=11*6+f4(3,{2})=6+5=11* 11 2,3
(5,{2,4}) {2}{4} 13 {4}{2} 1+f4(2,{4})=1+7=8*3+f4(4,{2})=3+7=10 8 2
(5,{3,4}) {3}{4} 63 {4}{3} 6+f4(3,{4})=6+6=12*3+f4(4,{3})=3+11=14 12 3
对于k=2有
(i,S2) j Cij S3 Cij+f3(j,S3) f2(i,S2) j*
(2,{3,4,5}) {3}{4}{5} 351 {4,5}{3,5}{3,4} 3+f3(3,{4,5})=3+11=145+f3(4,{3,5})=5+15=201+f3(5,{3,4})=1+12=13* 13 5
(3,{2,4,5}) {2}{4}{5} 346 {4,5}{3,5}{2,4} 3+f3(2,{4,5})=3+6=9*4+f3(4,{2,5})=4+6=106+f3(5,{2,4})=6+8=14 9 2
(4,{2,3,5}) {2}{3}{5} 543 {3,5}{2,5}{2,3} 5+f3(2,{3,5})=5+14=194+f3(3,{2,5})=4+9=13*3+f3(5,{2,3})=3+11=14 13 3
(5,{2,3,4}) {2}{3}{4} 163 {3,4}{2,4}{2,3} 1+f3(2,{3,4})=1+9=10*6+f3(3,{2,4})=6+10=163+f3(4,{2,3})=3+9=12 10 2
对于k=1,有
f1(1,S1)=min{C1j+f2(j,S2)}
f1(1,S1)的值列表如下:
(1,S1) j Cij S2 Cij+f2(j,S2) f1(1,S1) j*
(1,{2,3,4,5}) {2}{3}{4}{5} 2725 {3,4,5}{2,4,5}{2,3,5}{2,3,4} 2+f2(2,{3,4,5})=2+13=15*7+f2(3,{2,4,5})=7+9=162+f2(4,{2,3,5})=2+13=15*5+f2(5,{2,3,4})=5+10=15* 15 2,4,5
由状态x1=(1,{2,3,4,5})开始回朔,得到
(1,{2,3,4,5})
j*=2 j*=5 j*=4
(2,{3,4,5}) (5,{2,3,4}) (4{2,3,5})
j*=5 j*=2 j*=3
(5,{3,4}) (2,{3,4}) (3,{2,5})
j*=3 j*=3 j*=2 j*=5
(3,{4}) (3,{4}) (2,{5}) (5,{2})
j*=4 j*=4 j*=4 j*=2
(4,Φ) (4, Φ) (5, Φ) (2, Φ)
即得到以下四条回路:
(1) ①à②à⑤à③à④à①
(2) ①à⑤à②à③à④à①
(3) ①à④à③à②à⑤à①
(4) ①à④à③à⑤à②à①
其中(1)和(4)是同一条回路,(2)和(3)是同一条回路,这两条回路的图示如下:
容易验证,两条回路的长度都是15。
相关文章推荐
- 用动态规划方法旅行商问题(TSP问题)
- 动态规划法解旅行商问题(TSP)问题的java实现
- 基于分支限界法的旅行商问题(TSP)二
- poj 3311 Hie with the Pie (TSP问题)
- TSP问题求解方法
- 分支限界求解TSP问题
- TSP问题及蚁群算法理解与实现
- TSP_旅行商问题 - 遗传算法(四)
- TSP问题(贪心)
- hdu4284 Realtime Status 状压dp TSP问题 最短路
- 动态规划法解决TSP问题(C++)
- TSP_旅行商问题 - 蛮力法DFS(一)
- TSP_旅行商问题 - 蛮力法DFS(一)
- TSP(旅行者问题)——动态规划详解
- 网络分析优化旅行商问题TSP算法资源
- TSP问题
- 旅行商问题和背包问题
- 模拟退火算法解决TSP问题
- 禁忌搜索解TSP问题
- 回溯法求解TSP问题