分支限界求解货郎担/旅行商问题

分支限界求解货郎担/旅行商问题
http://blog.csdn.net/ly33854983/archive/2007/07/24/1705142.aspx

/* 文件名:BoundleSalesMan.h 限界函数法 */ #pragma once #include "salesman.h" #include #include "Node.h" class BoundSalesMan : public SalesMan { protected: int SetIMatrix(int i,int k,vector > & im);//生成第i点的规约矩阵,并返回约数,k点为其父结点 int Cost(vector A); //获取A中保存的路径的路径长度 int SimMatrix(vector< vector > & m); //将m规约 public: void Travel(); }; /* 文件名:BoundleSalesMan.cpp 限界函数法 */ #include "StdAfx.h" #include "BoundSalesMan.h" #include "Node.h" #include #include int BoundSalesMan::SimMatrix(vector > & m) //将m规约 { int result=0; int col=(int)m.size()-1; bool boolMax,boolZone; //对行进行规约 for (int i=0;i<=col;i++) { boolMax=true, boolZone=false; for (int j=0;j<=col;j++) { boolMax=boolMax && (m[i][j]==MAXNUM); //所有都是无穷大 boolZone=boolZone || (m[i][j]==0) ; //是否有一个是0 } if ((boolMax) || (boolZone)) //如果本行所有数据元素都是无穷大,或者有一个是0,本行已经规约 continue;//继续下一行 else //否则 { //从本行中找到最小的一个值,减去他,约数加上这个值 int min=m[i][0]; for (int k=1;k<=col;k++) { if (min>m[i][k]) min=m[i][k]; } for (int k=0;k<=col;k++) { if (m[i][k]!=MAXNUM) //如果是无穷值,则不变 m[i][k]-=min; } result+=min; } } //对列进行规约 for (int i=0;i<=col;i++) { boolMax=true, boolZone=false; for (int j=0;j<=col;j++) { boolMax=boolMax && (m[j][i]==MAXNUM); //所有都是无穷大 boolZone=boolZone || (m[j][i]==0) ; //是否有一个是0 } if ((boolMax) || (boolZone)) //如果本列所有数据元素都是无穷大,或者有一个是0,本列已经规约 continue;//继续下一列 else //否则 { //从本列中找到最小的一个值,减去他,约数加上这个值 int min=m[0][i]; for (int k=1;k<=col;k++) { if (min>m[k][i]) min=m[k][i]; } for (int k=0;k<=col;k++) { if (m[k][i]!=MAXNUM) //如果是无穷值,则不变 m[k][i]-=min; } result+=min; } } return result; } int BoundSalesMan::SetIMatrix(int i,int k,vector > & im) //生成第i点的规约矩阵 { int cols=im.size()-1; //先将k行和i列置为无穷/ for (int j=0;j<=cols;j++) { im[k][j]=MAXNUM; im[j][i]=MAXNUM; } //再将i行0列置为无穷 im[i][0]=MAXNUM; //再进行规约,记录规约值 return SimMatrix(im); } int BoundSalesMan::Cost(vector A) //获取A中保存的路径的路径长度 { int i=A.size(); int sum=matrix[0][A[0]];//先求从0到第一个点的距离 for (unsigned int i=1;i > simpleM=matrix; //0点的规约矩阵 int n0=SimMatrix(simpleM); int cols=matrix.size()-1; priority_queue p; Node firstNode(n0,0,0,path,simpleM); p.push(firstNode); //0结点入队列 Node node; while (! p.empty() && p.top().level tmpPath=node.states; tmpPath.push_back(i); Node newNode(tmp,node.level+1,i,tmpPath,simpleM); p.push(newNode); } } path=p.top().states; cout<<"Bound MinValue:"< PrintPath(); } /* 文件名:SalesMan。H 货郎担基类头文件 */ #pragma once #include #include using namespace std; class SalesMan { protected: enum{MAXNUM=999}; //最大值设为无穷大 vector > matrix; //对应的邻接矩阵 vector path; //记录走过的最小成本路径 int minValue;//最小路径长度 public: SalesMan(); virtual ~SalesMan(){matrix.clear();path.clear();} void PrintMatrix(); //打印矩阵值 void PrintPath(); //打印路径 virtual void Travel(){}; //主要寻找路径的函数,将在子类里面实现 }; /* 文件名:SalesMan。Cpp 货郎担基类源文件 */ #include "StdAfx.h" #include "SalesMan.h" SalesMan::SalesMan() //构造函数,从文件中读取数值,生成图的邻接矩阵, {//认为矩阵结点从0开始 fstream fin("in.txt"); if (!fin) { cerr<<"file open failed!"<>n; path.resize(n-1); //路径记录中间的那些结点 //从文件里取值 for (int i=0;i col; for (int j=0;j>num; col.push_back(num); } matrix.push_back(col); } fin.close(); } void SalesMan::PrintPath() { cout<<0<<"/t"; for (unsigned int i=0;i cout< cout<<"0"<< cout< using namespace std; struct Node { public: int num;//约数 int level; //层级 int position; //当前结点 vector > m; //当前结点的矩阵 vector states; //当前路径状态集 Node(){}; Node(int n,int l,int position,vector path,vector > mValue); bool operator< (const Node & B)const { return num>B.num; } }; /* 文件名:Node.cpp 为BoundSalesMan所调用,结点数据结构的实现 */ #include "StdAfx.h" #include "Node.h" Node::Node(int n,int l,int pos,vector path,vector > mValue) { num=n; level=l; position=pos; states=path; m=mValue; }

你可能感兴趣的:(C++,算法)