Traveling salesman problem based on branch-bound method (TSP)

Source: Internet
Author: User

Traveling salesman Problem ( English:travelling salesman problem, TSP) is a question: given the distance between a series of cities and each pair of cities, Solve the shortest loop that accesses each city once and returns to the starting city. It is a NP-hard problem in combinatorial optimization, which is very important in operational research and theoretical computer science.

Branch-bound method in the previous blog I have a brief explanation, and give a branch-based method of Dijkstra, this article introduces the branch-limit method based on the TSP algorithm.

For TSP, we need to use the upper bound and the lower bound to prune BFS, by constantly updating the upper and lower bounds, as far as possible to exclude the child does not meet the needs to achieve pruning. Finally, when the upper limit and the lower limit are at the same time, we can obtain the best BFS solution to solve the TSP problem.

The code below, in the following code, I use the Greedy method (using DFS brute force search to a result) to get the initial upper bound, by summing up each line of travel quotient matrix of the minimum value to obtain a lower bound.

//Branch and gauge method#include <iostream>#include<algorithm>#include<cstdio>#include<queue>Const intINF =100000;Const intMax_n = A;using namespacestd;//a matrix of n*nintN;intCost[max_n][max_n];//minimum 3 points, up to max_n pointsstructnode{BOOLVisited[max_n];//mark which points are gone    intS//First Point    ints_p;//the adjacency point of the first point    intE//One last point    inte_p;//the adjacency point of the last point    intK//Number of points passed    intSUMV;//distance through the path    intlb//the value of the target function (target result)    BOOL operator< (ConstNode &p)Const    {        returnp.lb < lb;//first-out queue with low target function value}};p riority_queue<Node> PQ;//Create a queue of precedenceintLow, up;//Nether and Upper boundsBOOLDfs_visited[max_n];//Search in DFS process//To determine the upper bound, using DFS (which belongs to the greedy algorithm), the result of the greedy method is an estimation result greater than the actual value.intDfsintUintKintL//The current node, the target node, the path that has been consumed{    if(k = = N)returnL + cost[u][1];//if n nodes have been inspected, the consumption of path consumption + nth node regression starting point is returned directly    intMinlen =INF, p;  for(inti =1; I <= N; i++)    {        if(!dfs_visited[i] && minlen > Cost[u][i])//take the smallest edge in the connecting edge of all points{Minlen= Cost[u][i];//find out which node is closest to the node for each nodep =i; }} Dfs_visited[p]=true;//continue searching with p for the next node    returnDFS (p, k +1+ K +minlen);}voidget_up () {dfs_visited[1] =true;//take the first point as the starting pointUp = DFS (1,1,0);}//Use this simple brute method to get a value that must be less than the resultvoidGet_low () {//take the sum of the minimum values per row as the lower boundLow =0;  for(inti =1; I <= N; i++)    {        //creates a temporary array that is equivalent to map and can be memcpy        intTmpa[max_n];  for(intj =1; J <= N; J + +) {Tmpa[j]=Cost[i][j]; } sort (Tmpa+1, Tmpa +1+ N);//to sort a temporary arrayLow + = tmpa[1]; }}intget_lb (Node p) {intRET = P.SUMV *2;//twice times the distance of the points on the path    intMin1 = inf, min2 = INF;//the edge of the beginning and the end     for(inti =1; I <= N; i++)    {        //cout << p.visited[i] << Endl;        if(!p.visited[i] && min1 >COST[I][P.S]) {Min1=COST[I][P.S]; }        //cout << min1 << Endl;} ret+=min1;  for(inti =1; I <= N; i++)    {        if(!p.visited[i] && min2 >Cost[p.e][i]) {min2=Cost[p.e][i]; }        //cout << min2 << Endl;} ret+=min2;  for(inti =1; I <= N; i++)    {        if(!P.visited[i]) {Min1= Min2 =INF;  for(intj =1; J <= N; J + +)            {                if(Min1 >Cost[i][j]) min1=Cost[i][j]; }             for(intj =1; J <= N; J + +)            {                if(Min2 >Cost[j][i]) min2=Cost[j][i]; } ret+ = Min1 +min2; }    }    return(ret +1) /2;}intsolve () {//The greedy method determines the upper boundsget_up (); //take the minimum Benzi per row and as the lower bound//cout << up << Endl;//TestGet_low (); //cout << Low << Endl;//Test//set the initial point, starting from 1 by defaultNode Star; STAR.S=1;//start at 1STAR.E =1;//end point is 1STAR.K =1;//went through a point     for(inti =1; I <= N; i++) {Star.visited[i]=false; } star.visited[1] =true; STAR.SUMV=0;//path-distance initializationstar.lb = low;//let the target value be equal to the nether    intret = INF;//ret As the solution of the problemPq.push (Star);//Join the start queue     while(Pq.size ()) {Node tmp=pq.top ();p q.pop (); if(TMP.K = = N-1)//If you've been through a n-1 point        {            //find the last point not to go            intp;  for(inti =1; I <= N; i++)            {                if(!Tmp.visited[i]) {P= i;//Let's not go the point for the last point can go                     Break; }            }            intAns = tmp.sumv + COST[P][TMP.S] + cost[tmp.e][p];//Consumed + back to start consumption + go to P consumption//if the current path and the value of all target functions are small, jump out            if(Ans <=tmp.lb) {ret=min (ans, ret);  Break; }            //Otherwise, continue to ask for other possible paths and update the upper bound            Else{ up= min (up, ans);//the upper bound is updated to the ANS value closer to the targetRET =min (ret, ans); Continue; }        }        //the point at which the current point can be scaled down into the priority queueNode Next;  for(inti =1; I <= N; i++)        {            if(!Tmp.visited[i]) {                //cout << "test" << Endl;Next.s = TMP.S;//follow TMP to Next, the starting point is the sameNEXT.SUMV = TMP.SUMV + cost[tmp.e][i];//Update paths andNEXT.E = i;//Update last pointNEXT.K = TMP.K +1;//update the number of vertices traversed                 for(intj =1; J <= N; J + +) Next.visited[j] = Tmp.visited[j];//the point where TMP passes is also the point where next passes.Next.visited[i] =true;//Naturally, you also want to update the current point//cout << next.visited[i] << Endl;next.lb = get_lb (next);//finding the objective function//cout << next.lb << Endl;                if(Next.lb > Up)Continue;//if greater than upper bound does not join the queuePq.push (next);//otherwise join the queue//cout << "test" << Endl;            }        }        //cout << pq.size () << Endl; BUG: Test is 0    }    returnret;}intMain () {CIN>>N;  for(inti =1; I <= N; i++)    {         for(intj =1; J <= N; J + +) {cin>>Cost[i][j]; if(i = =j) {Cost[i][j]=INF; } }} cout<< Solve () <<Endl; return 0;}/*Test 5100000 5 61 34 1257 100000 43 20 739 42 100000 8 216 50 42 100000 841 26 10 35 10000036 Press any key to continue ...*/

Traveling salesman problem based on branch-bound method (TSP)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.