旅行售货员问题-回溯法

排列树问题

《旅行售货员问题-回溯法》

问题描述:

 某售货员要到若干城市去推销商品,已知各城市之间的路程(旅费),他要选定一条从驻地出发,经过每个城市一遍,最后回到驻地的路线,使总的路程(总旅费)最小。

输出结果:

《旅行售货员问题-回溯法》



    // 旅行员售货问题 回溯法求解

    #include <iostream>

    using namespace std;


    const int N = 4;//图的顶点数


    class Traveling
    {


       friend    int TSP(int **a, int n);

       private:
        void Backtrack(int i);
        int n,           // 图G的顶点数
                *x,          // 当前解
                *bestx,     // 当前最优解
                  **a,    // 图G的领接矩阵
                cc,          // 当前费用
                bestc;       // 当前最优值
                int NoEdge;  // 无边标记


     };


              void Swap(int &a, int &b);

              int TSP(int **a, int n);

    int main()
    {
        cout<<"图的顶点个数 n="<<N<<endl;

        int **a=new int*[N+1];
        for(int i=0;i<=N;i++)
        {
            a[i]=new int[N+1];
        }

        cout<<"图的邻接矩阵为:"<<endl;

        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=N;j++)
            {
                cin>>a[i][j];

            }
            cout<<endl;
        }
        cout<<"最短回路的长为:"<<TSP(a,N)<<endl;

        for(int i=0;i<=N;i++)
        {
            delete []a[i];
        }
        delete []a;

        a=0;
        return 0;
    }


    void Traveling::Backtrack(int i)
    {
        if (i == n)
        {
            if (a[x[n-1]][x[n]] != 0 && a[x[n]][1] != 0 &&
                (cc + a[x[n-1]][x[n]] + a[x[n]][1] < bestc || bestc == 0))
            {
                for (int j = 1; j <= n; j++) bestx[j] = x[j];
                bestc = cc + a[x[n-1]][x[n]] + a[x[n]][1];
            }
        }
        else
        {
            for (int j = i; j <= n; j++)
            {
                 // 是否可进入x[j]子树?
                 if (a[x[i-1]][x[j]] != 0 && (cc + a[x[i-1]][x[i]] < bestc || bestc == 0))
                 {
                    // 搜索子树
                    Swap(x[i], x[j]);
                    cc += a[x[i-1]][x[i]];  //当前费用累加
                    Backtrack(i+1);         //排列向右扩展,排列树向下一层扩展
                    cc -= a[x[i-1]][x[i]];
                    Swap(x[i], x[j]);
                 }
            }
        }
    }


    int TSP(int  **a, int n)
    {

        Traveling Y;
        Y.n=n;
        Y.x=new int[n+1];
        Y.bestx=new int[n+1];

        for(int i=1;i<=n;i++)
        {
            Y.x[i]=i;
        }

        Y.a=a;
        Y.cc=0;
        Y.bestc=0;

        Y.NoEdge=0;
        Y.Backtrack(2);

        cout<<"最短回路为:"<<endl;
        for(int i=1;i<=n;i++)
        {
            cout<<Y.bestx[i]<<" --> ";
        }
        cout<<Y.bestx[1]<<endl;

        delete [] Y.x;
        Y.x=0;
        delete [] Y.bestx;

        Y.bestx=0;
        return Y.bestc;
    }

     void Swap(int &a, int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/heated_youth/article/details/53340477
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞