版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28666193/article/details/53763657
【问题描述】
旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。
假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值
【基本算法思想】
动态规划:
【源代码】
#include<iostream>
#include<stdio.h>
#include<string.h>
#define inf 0x3f3f3f3f
using namespace std;
int d[20][40000];
int main()
{
int arc[20][20],n;
while(~scanf("%d",&n)) //while(scanf("%d",&n)!=EOF)
{
int ans=inf;
memset(arc,0,sizeof arc);
for(int i=0; i<n; i++) //输入代价矩阵
{
for(int j=0; j<n; j++)
{
if(i!=j)cin>>arc[i][j];
else arc[i][j]=inf;
}
}
int total=(1<<(n-1)); //总子集数为total-1
d[0][0]=0;
for(int i=1; i<n; i++) //初始化第一列
{
d[i][0]=arc[i][0];
}
d[0][total-1]=inf;
for(int j=1; j<(total-1); j++) //遍历每一个子集
{
for(int i=1; i<n; i++) //对每一个元素判断是否在当前子集中
{
if((j&(1<<(i-1)))==0) //若不存在当前子集中
{
int x,y=inf;
for(int k=1; k<n; k++)
{
if((j&(1<<(k-1)))>0)
{
x=d[k][(j-(1<<(k-1)))]+arc[i][k];
y=min(y,x);
}
}
d[i][j]=y;
}
}
}
d[0][total-1]=inf;
for(int i=1; i<n; i++)
d[0][total-1]=min(d[0][total-1],arc[0][i]+d[i][(total-1)-(1<<(i-1))]);
cout<<d[0][total-1]<<endl;
}
return 0;
}
//样例
//5
//3 1 5 8
//3 6 7 9
//1 6 4 2
//5 7 4 3
//8 9 2 3
//4
//3 6 7
//5 2 3
//6 4 2
//3 7 5