首先简略介绍一下旅行商问题:有n个城市,相互之间有一条路径,但距离大小不同,求从某个城市 c 出发访问所有城市一次后回到 c 的最短距离。
博主另一篇文章毕业旅行省钱问题其实也是这个问题的一个解法,那边的编程思想是图的深度遍历。今天给大家介绍一种动态规划解法,本文的程序编写是受到这位大神的文章启发,有兴趣的同学也可以去看看。
回到旅行商的一个具体问题,假如有城市 、、、,要从 开始访问所有城市一遍后回到 ,求这个路径最短的回路长度。
动态规划解法思路:要去的城市集合用 表示,,问题用 表示,可理解为从 出发访问 中所有的城市后回到 的最短路径,它的解是 、、 中最小的一个,其中表示 城市与 城市之间的距离,可以列出状态转移方程:
根据这个思路进行编程,代码如下:
class Solution2{
public:
int SearchLowestPricePath(int amount, int startCity=0){
if(amount>32)
return -1;
int s=(1<<(amount-1))-1;
/*生成城市之间的路径图,对称矩阵*/
v=new int* [amount];
for(int i=0; i<amount; i++)
v[i]=new int [amount];
int n=amount;
for(int i=0;i<amount; i++){
for(int j=i; j<amount; j++){
v[i][j]=v[j][i]=(j==i) ? 0:(rand()%10+1);
}
}
/*调用旅行商算法*/
TSP(startCity, s);
}
int TSP(int curCity, int S){//S存储要去的城市,这里用到了二进制的技巧,假如有3个城市C1、C2、C3要去,111表示都要去;101表示c1、c3要去,c2不用去
if(S==0) return v[curCity][0];
int optVal=INT_MAX;
int t=S;
while(t){
int b=log(~(t-1)&t)/log(2), nextCity=b+1, S1=S-(1<<b);
optVal=min(optVal, TSP(nextCity,S1)+v[curCity][nextCity]);
t=(t-1)&t;
}
return optVal;
}
private:
int** v;
};
int main()
{
Solution2 c;
c.SearchLowestPricePath(5);//方法调用,5个城市
system("pause");
return 0;
}
核心函数TSP是不是不到10行就实现了呢~欢迎大家发表评论