算法之旅行售货员问题

问题描述:售货员要到n个城市去推销商品,已知各城市之间的路程(代价)a[][],试选择一条路,从第一个城市出发经过每个城市一遍,最后回到出发城市所耗费的代价最小。例:

问题分析:分析可知解空间是一棵排列树,每一条从根节点到达叶子结点的路径代表了n个顶点的一种排列。定义x[N]记录可行解。剪枝函数:两个城市之间是否连通,到达当前为止的代价是否已经超过了最优代价,当前城市是否已经走过

#include <iostream>
using namespace std;
#define NoEdge -1   //两点之间无法到达


int n=4;    //顶点(城市)数量
int cost=0; //从出发城市到当前位置的代价
int bestc=NoEdge; //最优代价
int bestx[4];     //最优解
int x[4];         //x[i]记录第i个城市的索引
int a[4][4]=     //记录城市之间代价,如果两座城市之间不连通则为NoEdge
{
    -1,30,6,4,
    30,-1,5,10,
    6,5,-1,20,
    4,10,20,-1
};

bool isHave(int i,int t)
{
    for(int j=0; j<t; j++)
        if(x[j]==i)return true;
    return false;
}

void Backtrack(int t)
{
    if(t==n)
    {
        //最后一个城市和出发城市是否可到达,该条通路的代价是不是最优
        if(a[x[n-1]][0]!=NoEdge
                &&((cost+a[x[n-1]][0])<bestc||bestc==NoEdge))
        {
            for(int i=0; i<n; i++)
            {
                bestx[i]=x[i];
                bestc=cost+a[x[n-1]][0];
            }
        }
    }
    else
    {
        for(int i=0; i<n; i++)
        {
            //当前城市是否已经走过,当前城市与上一座城市之间是否连通
            if(!isHave(i,t)&&a[x[t-1]][i]!=NoEdge&&((cost+a[x[t-1]][i])<bestc||bestc==NoEdge))
            {
                cost+=a[x[t-1]][i];
                //cout<<t<<endl;
                x[t]=i;
                Backtrack(t+1);
                cost-=a[x[t-1]][i];
            }
        }
    }
}
int main()
{
    x[0]=0; //出发城市固定为第一座城市
    Backtrack(1);
    for(int i=0; i<n; i++)
        cout<<bestx[i]+1<<" ";
    cout<<endl;
    cout<<bestc<<endl;
}

时间复杂度:O(n^3)

猜你喜欢

转载自blog.csdn.net/qq_35503380/article/details/80451684