⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mazh.cpp

📁 旅行商问题的算法
💻 CPP
字号:
// mazh.cpp : 定义控制台应用程序的入口点。
//


#include <tchar.h>
#include"queue"
#include"vector"
#include"iostream"

template<class T>
class AdjacencyWDigraph
{
    #define NoEdge 99999999     //定义最大数
	public:
    int BBTSP(int v[]);
	int n;
    T **a;
 AdjacencyWDigraph(T*b,int num);
~AdjacencyWDigraph()
{
	for(int i=0;i<n+1;i++)
		delete a[i];
	delete []a;
}

private:
        class MinHeapNode
		{
		public:
			int *x;
			int s;
			T cc;
			T lcost;
			T rcost;
		};
		class CompareMin
		{
		public :
			bool operator()(const MinHeapNode& x,const MinHeapNode &y)const
			{
				return (x.lcost>y.lcost);
			}
		};
};
template<class T>
AdjacencyWDigraph<T>::AdjacencyWDigraph(T*b,int num)
	{
	n=num;
	
		a=new T*[n+1];
		for(int i=0;i<n+1;i++)
			a[i]=new T[n+1];
		
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				a[i][j]=b[(i-1)*n+j-1];
			}
		}
	}
template<class T>
int AdjacencyWDigraph<T>::BBTSP(int v[])//结果放在v[1]--------v[n]
{// 旅行商问题的最小耗费分枝定界算法
   using namespace std;

	std::priority_queue <MinHeapNode,std::vector<MinHeapNode>,CompareMin> H;
	T *	MinOut = new T [n+1];

// 计算MinOut[i] = 离开顶点i的最小耗费边的耗费
T MinSum = 0; // 离开顶点i的最小耗费边的数目
for (int i = 1; i <= n; i++)
{
     T Min = NoEdge;
for (int j = 1; j <= n; j++)
if (a[i][j] != NoEdge &&(a[i][j] < Min || Min == NoEdge))
               Min = a[i][j];
if (Min == NoEdge) return NoEdge; // 此路不通
MinOut[i] = Min;
MinSum += Min;
}
// 把E-节点初始化为树根
MinHeapNode E;
E.x = new int [n];
for (i = 0; i < n; i++)
E.x[i] = i + 1;
E.s = 0; // 局部旅行路径为x [ 1 : 0 ]
E.cc = 0; // 其耗费为0
E.rcost = MinSum;
T bestc = NoEdge; // 目前没有找到旅行路径
// 搜索排列树
while (E.s < n - 1) 
{       // 不是叶子
    if (E.s == n - 2) 
   {  // 叶子的父节点
     // 通过添加两条边来完成旅行
     // 检查新的旅行路径是不是更好
         if (a[E.x[n-2]][E.x[n-1]] != NoEdge && a[E.x[n-1]][1] != NoEdge && (E.cc +
             a[E.x[n-2]][E.x[n-1]] + a[E.x[n-1]][1] < bestc || bestc == NoEdge)) 
	     {
               // 找到更优的旅行路径
           bestc = E.cc + a[E.x[n-2]][E.x[n-1]] + a[E.x[n-1]][1];
              E.cc = bestc;
            E.lcost = bestc;
            E.s++ ;
           H.push(E);
         }
          else 
		  {
              delete [] E.x; 
		  }
    }
    else 
	{           // 产生孩子
           for (int i = E.s + 1; i < n; i++)
          if (a[E.x[E.s]][E.x[i]] != NoEdge)
		  {
              // 可行的孩子, 限定了路径的耗费
               T cc = E.cc + a[E.x[E.s]][E.x[i]];
               T rcost = E.rcost - MinOut[E.x[E.s]];
               T b = cc + rcost; //下限
               if (b < bestc || bestc == NoEdge) 
			   {
                   // 子树可能有更好的叶子
                   // 把根保存到最xiao堆中
                     MinHeapNode N;
                     N.x = new int [n];
                   for (int j = 0; j < n; j++)
                        N.x[j] = E.x[j];
                   N.x[E.s+1] = E.x[i];
                   N.x[i] = E.x[E.s+1];
                     N.cc = cc;
                     N.s = E.s + 1;
                   N.lcost = b;
                   N.rcost = rcost;
                     H.push(N) ;
               }

          } // 结束可行的孩子

             delete [] E.x;
      } // 对本节点的处理结束

        if(!H.empty())
         {
             E=H.top();
             H.pop();
         }
          else 
                break;
}
      if (bestc == NoEdge) return NoEdge; // 没有旅行路径
          // 将最优路径复制到v[1:n] 中
            for (i = 0; i < n; i++)
                v[i+1] = E.x[i];
           while (true) 
          {
	            // 释放最小堆中的所有节点
               delete [] E.x;
               if(!H.empty())
              { 
                       E=H.top();
                       H.pop();
               }
                   else
                    break;
           }
         delete []MinOut;
           return bestc;
}

int _tmain(int argc, _TCHAR* argv[])
{
int b[8][8]=
		{
	0,  8	,5	,9	,12,	13	,12,17	,
	8,	0	,8	,15	,17	,7	,11	,14	,
	5,	8	,0,	7,	9	,10	,7	,12	,
	9	,15,	7	,0,	3,	17,	11	,16	,
	12,	17	,9,	3,	0,	18	,11,	15	,
	13	,7	,10	,17	,18	,0	,8,	8	,
	12,	11,	7,	11	,11,	8,	0,	5	,
	17,	14	,12	,16	,15	,8	,5,	0	
		};
      AdjacencyWDigraph <int>t(&b[0][0],8);
        int v[10];
		std::cout<<t.BBTSP(v)<<std::endl;
		for(int i=1;i<8+1;i++)
			std::cout<<v[i]<<" ";
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -