《旅行商问题资料.doc》由会员分享,可在线阅读,更多相关《旅行商问题资料.doc(15页珍藏版)》请在三一办公上搜索。
1、算法设计与分析实验报告实验三 旅行商问题院系: 班级: 计算机科学与技术学号: 姓名: 任课教师: 成绩:湘 潭 大 学2016年5月 实验三 旅行商问题一. 实验内容分别编程实现回溯法和分支限界法求TSP问题的最优解,分析比较两种算法的时间复杂度并验证分析结果。二实验目的1、掌握回溯法和分支限界法解决问题的一般步骤,学会使用回溯法和分支限界法解决实际问题;2、理解回溯法和分支限界法的异同及各自的适用范围。三. 算法描述旅行商问题的回溯法算法可描述如下:Template Class Travelingfriend Type TSP(int * , int,int ,Type);Private;
2、Void Backtrack(int i);Int n, /图G的顶点数*x; /当前解*bestx; /当前最优解Type *a, /图G的邻接矩阵cc, /当前费用bestc, /当前最优解NoEdge; /无边标记;Template Void Traveling : : backtrack(int i)if(i =n)if(axn-1xn!=NoEdge&axn1!=NoEdge& (cc+axn-1xn+axn1 +axn1bestc | bestc = NoEdge)for(int j = 1;j=n;j+) bestxj = xj;bestc = cc + axn-1xn+axn1
3、;elseFor (int j = i;j= n;j+)/是否可进入xj子树?If(axi-1xj != NoEdge &(cc+axi-1xj bestc | bestc = NoEdge)/搜素子树Swap(xi,xj);cc += axi-1xi;Backtrack(i + 1);cc -= axi-1xi;Swap(xi,xj);TemplateType TSP(Type*a, int v, int n, Type NoEdge)Traveling Y;/初始化YY.x = new int n+1;/置x为单位排列For(int i = 1;i = n;i+)Y.xi = i;Y.a
4、= a;Y.n = n;Y.bestc = NoEdge;Y.bestx = v;Y.cc = 0;Y.NoEdge = NoEdge;/搜索x2:n的全排列Y.Backtrack(2);DeleteY.x;Return Y.bestc;算法效率:如果不考虑更新bestx所需的计算时间,则Backtrack需要O(n-1)!)计算时间。由于算法Backtrack在最坏情款下可能需要更新当前最优解O(n-1)!)次,每次更新需O(n)计算时间,从而整个算法的计算时间复杂性为O(n!)。旅行商问题的分支界限法算法可描述如下:使用优先队列来存储活节点,优先队列中的每个活节点都存储从根到该活节点的相应
5、路径。具体算法可描述如下:TemplateClass MinHeapNodefirend Traveling;Public:Operator Type() const return lcost;Private:Type lcost, /子树费用的下界 cc, /当前费用rcost; /xs:n-1中定点最小出边费用和Int s, /根节点到当前节点的路径为x0:s*x; /需要进一步搜索的顶点是xs+1:n-1;四. 算法实现源程序代码 /*回溯法*/#include#include#define N 5double cc,/当前路径费用 bestc;/当前最优解费用double aN+1N+
6、1;/邻接矩阵,存放图的信息int bestxN+1;/当前最优解int xN+1;/当前解void inputAjac()int i,j;for(i=1;i=N;i+)for(j=i+1;j0.0&axNx10.0)if(bestccc+axN-1xN+axNx1)int j;for(j=1;j=N;j+)bestxj=xj;bestc=cc+axN-1xN+axNx1;elseint j;for(j=i;j0.0)if(bestccc+axi-1xj+axjx1)int temp;cc+=axi-1xj;temp=xi;xi=xj;xj=temp;backtrack(i+1);temp=x
7、i;xi=xj;xj=temp;cc-=axi-1xj;double tsp()int i;for(i=1;i=N;i+)xi=i;cc=0.0,bestc=-1.0;inputAjac();backtrack(2);return bestc;void output() int i;for(i=1;i=N;i+)printf(%4d,bestxi); / printf(n);void main()double start,finish; start=clock();/取开始时间 printf(城市个数:5n); printf(走%d个城市最少路费为:%lfn,N,tsp();printf(路径
8、:);output();printf( 1n); finish=clock();printf(所需时间 %f msn,(finish-start);/*分支界限法*/#include #include #includeusing namespace std;#define MAX_CITY_NUMBER 10 #define MAX_COST 10000000 int City_GraphMAX_CITY_NUMBERMAX_CITY_NUMBER;int City_Size; int Best_Cost; int Best_Cost_PathMAX_CITY_NUMBER;typedef s
9、truct Node int lcost; int cc; int rcost; int s; int xMAX_CITY_NUMBER; struct Node* pNext; Node;typedef struct MiniHeap Node* pHead; MiniHeap;void InitMiniHeap(MiniHeap* pMiniHeap) pMiniHeap-pHead = new Node;pMiniHeap-pHead-pNext = NULL;void put(MiniHeap* pMiniHeap,Node node) Node* next;Node* pre;Nod
10、e* pinnode = new Node; pinnode-cc = node.cc;pinnode-lcost = node.lcost;pinnode-pNext = node.pNext;pinnode-rcost = node.rcost;pinnode-s = node.s;pinnode-pNext = NULL;for(int k=0; kxk = node.xk;pre = pMiniHeap-pHead;next = pMiniHeap-pHead-pNext;if(next = NULL) pMiniHeap-pHead-pNext = pinnode; else whi
11、le(next != NULL) if(next-lcost) (pinnode-lcost) pinnode-pNext = pre-pNext;pre-pNext = pinnode;break; pre = next;next = next-pNext;pre-pNext = pinnode; Node* RemoveMiniHeap(MiniHeap* pMiniHeap) Node* pnode = NULL;if(pMiniHeap-pHead-pNext != NULL) pnode = pMiniHeap-pHead-pNext;pMiniHeap-pHead-pNext =
12、pMiniHeap-pHead-pNext-pNext;return pnode;void Traveler() int i,j;int temp_xMAX_CITY_NUMBER;Node* pNode = NULL;int miniSum; int miniOutMAX_CITY_NUMBER;MiniHeap* heap = new MiniHeap; InitMiniHeap(heap); miniSum = 0;for (i=0; iCity_Size; i+) miniOuti = MAX_COST; for(j=0; j0 & City_GraphijminiOuti) mini
13、Outi = City_Graphij;if (miniOuti = MAX_COST) Best_Cost = -1;return ;miniSum += miniOuti;for(i=0; ilcost = 0; pNode-cc = 0; pNode-rcost = miniSum; pNode-s = 0; pNode-pNext = NULL;for(int k=0; kxk = Best_Cost_Pathk; put(heap,*pNode); while(pNode != NULL & (pNode-s) City_Size-1) for(int k=0; kxk ; if (
14、pNode-s) = City_Size-2) int edge1 = City_Graph(pNode-x)City_Size-2(pNode-x)City_Size-1;int edge2 = City_Graph(pNode-x)City_Size-1(pNode-x)0;if(edge1 = 0 & edge2 = 0 & (pNode-cc+edge1+edge2) cc + edge1+edge2;pNode-cc = Best_Cost;pNode-lcost = Best_Cost; pNode-s+; else for (i=pNode-s; ixpNode-spNode-x
15、i = 0) int temp_cc = pNode-cc+City_GraphpNode-xpNode-spNode-xi;int temp_rcost = pNode-rcost-miniOutpNode-xpNode-s;if (temp_cc+temp_rcostBest_Cost) for (j=0; jxpNode-s+1 = Best_Cost_Pathi;temp_xi = Best_Cost_PathpNode-s+1; Node* pNextNode = new Node;pNextNode-cc = temp_cc;pNextNode-lcost = temp_cc+te
16、mp_rcost;pNextNode-rcost = temp_rcost;pNextNode-s = pNode-s+1;pNextNode-pNext = NULL;for(int k=0; kxk = temp_xk;put(heap,*pNextNode);delete pNextNode;pNode = RemoveMiniHeap(heap);int main() double start,finish; start=clock(); int i,j;printf(城市个数:);scanf(%d,&City_Size);for(i=0; iCity_Size; i+) printf
17、(请分别输入每个城市与其它城市的路程花费:);for(j=0; jCity_Size; j+) scanf(%d,&City_Graphij);Traveler();printf(最少路费:%dn,Best_Cost);finish=clock();printf(所需时间: %f msn,(finish-start);return 1;五 程序运行结果回溯法结果截图:分支界限法结果截图:六 实验结果分析回溯法算法的时间复杂度为O(n!),分支界限发算法的时间复杂度为O(2n);从实验结果也可看出分支界限法所需时间少很多。七 结论 分支限界法类似于回溯法,也是一种在问题的解空间树T上搜索问题解的
18、算法。但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。由于求解目标不同,导致分支限界法与回溯法在解空间树T上的搜索方式也不相同。回溯法以深度优先的方式搜索解空间树T,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树T。分支限界法的搜索策略是:在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一个扩展对点。为了有效地选择下一扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值(限界),并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。