Traveling Salesman Problem using Branch And Bound | Python3 program to solve Traveling Salesman Problem using Branch and Bound . ; final_path [ ] stores the final solution i . e . the path of the salesman . ; visited [ ] keeps track of the already visited nodes in a particular path ; Stores the final minimum weight of shortest tour . ; Function to copy temporary solution to the final solution ; Function to find the minimum edge cost having an end at the vertex i ; function to find the second minimum edge cost having an end at the vertex i ; function that takes as arguments : curr_bound -> lower bound of the root node curr_weight -> stores the weight of the path so far level -> current level while moving in the search space tree curr_path [ ] -> where the solution is being stored which would later be copied to final_path [ ] ; base case is when we have reached level N which means we have covered all the nodes once ; check if there is an edge from last vertex in path back to the first vertex ; curr_res has the total weight of the solution we got ; Update final result and final path if current result is better . ; for any other level iterate for all vertices to build the search space tree recursively ; Consider next vertex if it is not same ( diagonal entry in adjacency matrix and not visited already ) ; different computation of curr_bound for level 2 from the other levels ; curr_bound + curr_weight is the actual lower bound for the node that we have arrived on . If current lower bound < final_res , we need to explore the node further ; call TSPRec for the next level ; Else we have to prune the node by resetting all changes to curr_weight and curr_bound ; Also reset the visited array ; This function sets up final_path ; Calculate initial lower bound for the root node using the formula 1 / 2 * ( sum of first min + second min ) for all edges . Also initialize the curr_path and visited array ; Compute initial bound ; Rounding off the lower bound to an integer ; We start at vertex 1 so the first vertex in curr_path [ ] is 0 ; Call to TSPRec for curr_weight equal to 0 and level 1 ; Adjacency matrix for the given graph
import math NEW_LINE maxsize = float ( ' inf ' ) NEW_LINE final_path = [ None ] * ( N + 1 ) NEW_LINE visited = [ False ] * N NEW_LINE final_res = maxsize NEW_LINE TSP ( adj ) NEW_LINE print ( " Minimum ▁ cost ▁ : " , final_res ) NEW_LINE print ( " Path ▁ Taken ▁ : ▁ " , end = ' ▁ ' ) NEW_LINE for i in range ( N + 1 ) : NEW_LINE INDENT print ( final_path [ i ] , end = ' ▁ ' ) NEW_LINE DEDENT def copyToFinal ( curr_path ) : NEW_LINE INDENT final_path [ : N + 1 ] = curr_path [ : ] NEW_LINE final_path [ N ] = curr_path [ 0 ] NEW_LINE DEDENT def firstMin ( adj , i ) : NEW_LINE INDENT min = maxsize NEW_LINE for k in range ( N ) : NEW_LINE INDENT if adj [ i ] [ k ] < min and i != k : NEW_LINE INDENT min = adj [ i ] [ k ] NEW_LINE DEDENT DEDENT return min NEW_LINE DEDENT def secondMin ( adj , i ) : NEW_LINE INDENT first , second = maxsize , maxsize NEW_LINE for j in range ( N ) : NEW_LINE INDENT if i == j : NEW_LINE INDENT continue NEW_LINE DEDENT if adj [ i ] [ j ] <= first : NEW_LINE INDENT second = first NEW_LINE first = adj [ i ] [ j ] NEW_LINE DEDENT elif ( adj [ i ] [ j ] <= second and adj [ i ] [ j ] != first ) : NEW_LINE INDENT second = adj [ i ] [ j ] NEW_LINE DEDENT DEDENT return second NEW_LINE DEDENT def TSPRec ( adj , curr_bound , curr_weight , level , curr_path , visited ) : NEW_LINE INDENT global final_res NEW_LINE if level == N : NEW_LINE INDENT if adj [ curr_path [ level - 1 ] ] [ curr_path [ 0 ] ] != 0 : NEW_LINE INDENT curr_res = curr_weight + adj [ curr_path [ level - 1 ] ] [ curr_path [ 0 ] ] NEW_LINE if curr_res < final_res : NEW_LINE INDENT copyToFinal ( curr_path ) NEW_LINE final_res = curr_res NEW_LINE DEDENT DEDENT return NEW_LINE DEDENT for i in range ( N ) : NEW_LINE INDENT if ( adj [ curr_path [ level - 1 ] ] [ i ] != 0 and visited [ i ] == False ) : NEW_LINE INDENT temp = curr_bound NEW_LINE curr_weight += adj [ curr_path [ level - 1 ] ] [ i ] NEW_LINE if level == 1 : NEW_LINE INDENT curr_bound -= ( ( firstMin ( adj , curr_path [ level - 1 ] ) + firstMin ( adj , i ) ) / 2 ) NEW_LINE DEDENT else : NEW_LINE INDENT curr_bound -= ( ( secondMin ( adj , curr_path [ level - 1 ] ) + firstMin ( adj , i ) ) / 2 ) NEW_LINE DEDENT if curr_bound + curr_weight < final_res : NEW_LINE INDENT curr_path [ level ] = i NEW_LINE visited [ i ] = True NEW_LINE TSPRec ( adj , curr_bound , curr_weight , level + 1 , curr_path , visited ) NEW_LINE DEDENT curr_weight -= adj [ curr_path [ level - 1 ] ] [ i ] NEW_LINE curr_bound = temp NEW_LINE visited = [ False ] * len ( visited ) NEW_LINE for j in range ( level ) : NEW_LINE INDENT if curr_path [ j ] != - 1 : NEW_LINE INDENT visited [ curr_path [ j ] ] = True NEW_LINE DEDENT DEDENT DEDENT DEDENT DEDENT def TSP ( adj ) : NEW_LINE INDENT curr_bound = 0 NEW_LINE curr_path = [ - 1 ] * ( N + 1 ) NEW_LINE visited = [ False ] * N NEW_LINE for i in range ( N ) : NEW_LINE INDENT curr_bound += ( firstMin ( adj , i ) + secondMin ( adj , i ) ) NEW_LINE DEDENT curr_bound = math . ceil ( curr_bound / 2 ) NEW_LINE visited [ 0 ] = True NEW_LINE curr_path [ 0 ] = 0 NEW_LINE TSPRec ( adj , curr_bound , 0 , 1 , curr_path , visited ) NEW_LINE DEDENT adj = [ [ 0 , 10 , 15 , 20 ] , [ 10 , 0 , 35 , 25 ] , [ 15 , 35 , 0 , 30 ] , [ 20 , 25 , 30 , 0 ] ] NEW_LINE N = 4 NEW_LINE