回溯法-使用排列树解TSP问题
旅行售货员问题:某售货员要到若干城市去推销产品,已知各城市之间的旅费(或路程)。他需要选择一条从驻地出发经过每一个城市最后回到驻地的最优路径(使费用最少或使路径最短)。
这是一个NP完全问题,这个问题虽然叙述起来简单,但是其时间复杂度却是问题的输入规模的指数函数。
直接上代码
#include<iostream>
using namespace std;
int g[100][100],x[100],bestx[100];//bestx:依次存储最优路线
int cl=0,bestl=1000,n;//变量 cl:在t层中,cl表示到t-1层的总花费; bestl:最终最少花费;
void Traveling(int t)
{
int j;
if(t>n)//到达叶子结点
{
if(g[x[n]][1]!=-1 && (cl+g[x[n]][1]<bestl))//推销员到的最后一个城市与出发的城市之间有路径,且当前总费用比当前最优值小
{
for(j=1; j<=n; j++) //把本次得到的路径顺序,和花费保存下来,不然返回时将被重置
bestx[j]=x[j];
bestl=cl+g[x[n]][1];
}
}
else //没有到达叶子结点
{
for(j=t; j<=n; j++)//搜索所有与当前所在城市临近的城市
{
if(g[x[t-1]][x[j]]!=-1 && (cl+g[x[t-1]][x[j]]<bestl))//若第t-1个城市与第t个城市之间有路径且可以得到更便宜的路线
{
swap(x[t],x[j]); //保存要去的第t个城市到x[t]中
cl+=g[x[t-1]][x[t]]; //费用增加
Traveling(t+1); //搜索下一个城市
cl-=g[x[t-1]][x[t]]; //还原现场,以便下一次循环
swap(x[t],x[j]);
}
}
}
}
int main()
{
int i,j;
cout<<"请输入一共有几个城市:"<<endl;
cin>>n;
cout<<"请输入城市之间的路费(注:无路径或到自己本身就输入-1)"<<endl;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
cin>>g[i][j]; //i为起点城市,j为终点城市
for(i=1; i<=n; i++) //初始化
{
x[i]=i;
bestx[i]=0;
}
Traveling(2);
cout<<"城市路线:"<<endl;
for(i=1; i<=n; i++)
cout<<bestx[i]<<' ';
cout<<bestx[1];
cout<<endl;
cout<<"最小费用周游路线:"<<endl;
cout<<bestl<<endl;
return 0;
}
关注更方便查看更多实用精彩内容哟!!