11"""
2- title : Travelling Sales man Problem
2+ title : Travelling Sales man Problem
33references : https://en.wikipedia.org/wiki/Travelling_salesman_problem
44author : SunayBhoyar
55"""
6+
67import itertools
78import math
89
1314 "D" : [40 , 10 ],
1415 "E" : [25 , 5 ],
1516 "F" : [5 , 15 ],
16- "G" : [50 , 25 ]
17+ "G" : [50 , 25 ],
1718}
1819
19- # Euclidean distance - shortest distance between 2 points
20+
21+ # Euclidean distance - shortest distance between 2 points
2022def distance (point1 , point2 ):
2123 """
2224 Calculate the Euclidean distance between two points.
@@ -28,11 +30,14 @@ def distance(point1, point2):
2830 """
2931 return math .sqrt ((point2 [0 ] - point1 [0 ]) ** 2 + (point2 [1 ] - point1 [1 ]) ** 2 )
3032
33+
3134"""
32- Brute force
35+ Brute force
3336Time Complexity - O(n!×n)
3437Space Complexity - O(n)
3538"""
39+
40+
3641def travelling_sales_man_problem_brute_force (graph_points ):
3742 """
3843 Solve the Travelling Salesman Problem using brute force (permutations).
@@ -43,31 +48,34 @@ def travelling_sales_man_problem_brute_force(graph_points):
4348 (['A', 'B', 'C', 'A'], 3.414)
4449 """
4550 nodes = list (graph_points .keys ())
46-
51+
4752 min_path = None
48- min_distance = float (' inf' )
49-
50- # Considering the first Node as the start position
53+ min_distance = float (" inf" )
54+
55+ # Considering the first Node as the start position
5156 start_node = nodes [0 ]
5257 other_nodes = nodes [1 :]
53-
58+
5459 for perm in itertools .permutations (other_nodes ):
5560 path = [start_node ] + list (perm ) + [start_node ]
5661 total_distance = 0
5762 for i in range (len (path ) - 1 ):
58- total_distance += distance (graph_points [path [i ]], graph_points [path [i + 1 ]])
63+ total_distance += distance (graph_points [path [i ]], graph_points [path [i + 1 ]])
5964
6065 if total_distance < min_distance :
6166 min_distance = total_distance
6267 min_path = path
63-
68+
6469 return min_path , min_distance
6570
71+
6672"""
67- dynamic_programming
73+ dynamic_programming
6874Time Complexity - O(n^2×2^n)
6975Space Complexity - O(n×2^n)
7076"""
77+
78+
7179def travelling_sales_man_problem_dp (graph_points ):
7280 """
7381 Solve the Travelling Salesman Problem using dynamic programming.
@@ -79,57 +87,65 @@ def travelling_sales_man_problem_dp(graph_points):
7987 """
8088 n = len (graph_points )
8189 nodes = list (graph_points .keys ())
82-
90+
8391 # Precompute distances between every pair of nodes
8492 dist = [[0 ] * n for _ in range (n )]
8593 for i in range (n ):
8694 for j in range (n ):
8795 dist [i ][j ] = distance (graph_points [nodes [i ]], graph_points [nodes [j ]])
88-
96+
8997 # dp[mask][i] represents the minimum distance to visit all nodes in the 'mask' set, ending at node i
90- dp = [[float (' inf' )] * n for _ in range (1 << n )]
98+ dp = [[float (" inf" )] * n for _ in range (1 << n )]
9199 dp [1 ][0 ] = 0 # Start at node 0
92-
100+
93101 # Iterate over all subsets of nodes (represented by mask)
94102 for mask in range (1 << n ):
95103 for u in range (n ):
96- if mask & (1 << u ):
104+ if mask & (1 << u ):
97105 for v in range (n ):
98- if mask & (1 << v ) == 0 :
106+ if mask & (1 << v ) == 0 :
99107 next_mask = mask | (1 << v )
100- dp [next_mask ][v ] = min (dp [next_mask ][v ], dp [mask ][u ] + dist [u ][v ])
108+ dp [next_mask ][v ] = min (
109+ dp [next_mask ][v ], dp [mask ][u ] + dist [u ][v ]
110+ )
101111
102112 # Reconstruct the path and find the minimum distance to return to the start
103113 final_mask = (1 << n ) - 1
104- min_cost = float (' inf' )
114+ min_cost = float (" inf" )
105115 end_node = - 1
106116
107117 # Find the minimum distance from any node back to the starting node
108118 for u in range (1 , n ):
109119 if min_cost > dp [final_mask ][u ] + dist [u ][0 ]:
110120 min_cost = dp [final_mask ][u ] + dist [u ][0 ]
111121 end_node = u
112-
122+
113123 # Reconstruct the path using the dp table
114124 path = []
115125 mask = final_mask
116126 while end_node != 0 :
117127 path .append (nodes [end_node ])
118128 for u in range (n ):
119- if mask & (1 << u ) and dp [mask ][end_node ] == dp [mask ^ (1 << end_node )][u ] + dist [u ][end_node ]:
120- mask ^= (1 << end_node )
129+ if (
130+ mask & (1 << u )
131+ and dp [mask ][end_node ]
132+ == dp [mask ^ (1 << end_node )][u ] + dist [u ][end_node ]
133+ ):
134+ mask ^= 1 << end_node
121135 end_node = u
122136 break
123137
124- path .append (nodes [0 ])
138+ path .append (nodes [0 ])
125139 path .reverse ()
126140
127141 return path , min_cost
128142
129143
130144if __name__ == "__main__" :
131145 print (f"Travelling salesman problem solved using Brute Force:" )
132- path , distance_travelled = travelling_sales_man_problem_brute_force (demo_graph_points )
146+ path , distance_travelled = travelling_sales_man_problem_brute_force (
147+ demo_graph_points
148+ )
133149 print (f"Shortest path: { path } " )
134150 print (f"Total distance: { distance_travelled :.2f} " )
135151
0 commit comments