Skip to content

Commit d6b11f7

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 81ef261 commit d6b11f7

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

graphs/travlelling_salesman_problem.py

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""
2-
title : Travelling Sales man Problem
2+
title : Travelling Sales man Problem
33
references : https://en.wikipedia.org/wiki/Travelling_salesman_problem
44
author : SunayBhoyar
55
"""
6+
67
import itertools
78
import math
89

@@ -13,10 +14,11 @@
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
2022
def 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
3336
Time Complexity - O(n!×n)
3437
Space Complexity - O(n)
3538
"""
39+
40+
3641
def 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
6874
Time Complexity - O(n^2×2^n)
6975
Space Complexity - O(n×2^n)
7076
"""
77+
78+
7179
def 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

130144
if __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

Comments
 (0)