Skip to content

Commit 613f482

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 76db9e0 commit 613f482

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

sorts/topological_sort.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
vertices: list[str] = ["a", "b", "c", "d", "e"]
1818

19+
1920
# Perform topological sort on a DAG starting from the specified node
2021
def topological_sort(start: str, visited: list[str], sort: list[str]) -> list[str]:
2122
current = start
@@ -42,10 +43,11 @@ def topological_sort(start: str, visited: list[str], sort: list[str]) -> list[st
4243
# Return sorted list
4344
return sort
4445

46+
4547
if __name__ == "__main__":
4648
# Topological Sorting from node "a" (Returns the order in bottom up approach)
4749
sort = topological_sort("a", [], [])
4850

4951
# Reversing the list to get the correct topological order (Top down approach)
50-
sort.reverse()
52+
sort.reverse()
5153
print(sort)

travelling_salesman_problem.py

+28-15
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
""" Travelling Salesman Problem (TSP) """
1+
"""Travelling Salesman Problem (TSP)"""
22

33
import itertools
44
import math
55

6+
67
class InvalidGraphError(ValueError):
78
"""Custom error for invalid graph inputs."""
89

10+
911
def euclidean_distance(point1: list[float], point2: list[float]) -> float:
1012
"""
1113
Calculate the Euclidean distance between two points in 2D space.
@@ -28,6 +30,7 @@ def euclidean_distance(point1: list[float], point2: list[float]) -> float:
2830
except TypeError:
2931
raise ValueError("Invalid input: Points must be numerical coordinates")
3032

33+
3134
def validate_graph(graph_points: dict[str, list[float]]) -> None:
3235
"""
3336
Validate the input graph to ensure it has valid nodes and coordinates.
@@ -41,12 +44,12 @@ def validate_graph(graph_points: dict[str, list[float]]) -> None:
4144
Traceback (most recent call last):
4245
...
4346
InvalidGraphError: Each node must have a valid 2D coordinate [x, y]
44-
47+
4548
>>> validate_graph([10, 20]) # Invalid input type
4649
Traceback (most recent call last):
4750
...
4851
InvalidGraphError: Graph must be a dictionary with node names and coordinates
49-
52+
5053
>>> validate_graph({"A": [10, 20], "B": [30, 21], "C": [15]}) # Missing coordinate
5154
Traceback (most recent call last):
5255
...
@@ -66,6 +69,7 @@ def validate_graph(graph_points: dict[str, list[float]]) -> None:
6669
):
6770
raise InvalidGraphError("Each node must have a valid 2D coordinate [x, y]")
6871

72+
6973
# TSP in Brute Force Approach
7074
def travelling_salesman_brute_force(
7175
graph_points: dict[str, list[float]],
@@ -89,7 +93,7 @@ def travelling_salesman_brute_force(
8993
raise InvalidGraphError("Graph must have at least two nodes")
9094

9195
min_path = [] # List that stores shortest path
92-
min_distance = float("inf") # Initialize minimum distance to infinity
96+
min_distance = float("inf") # Initialize minimum distance to infinity
9397

9498
start_node = nodes[0]
9599
other_nodes = nodes[1:]
@@ -111,6 +115,7 @@ def travelling_salesman_brute_force(
111115

112116
return min_path, min_distance
113117

118+
114119
# TSP in Dynamic Programming approach
115120
def travelling_salesman_dynamic_programming(
116121
graph_points: dict[str, list[float]],
@@ -127,20 +132,26 @@ def travelling_salesman_dynamic_programming(
127132
"""
128133
validate_graph(graph_points)
129134

130-
n = len(graph_points) # Extracting the node names (keys)
135+
n = len(graph_points) # Extracting the node names (keys)
131136

132137
# There shoukd be atleast 2 nodes for a valid TSP
133138
if n < 2:
134139
raise InvalidGraphError("Graph must have at least two nodes")
135140

136-
nodes = list(graph_points.keys()) # Extracting the node names (keys)
141+
nodes = list(graph_points.keys()) # Extracting the node names (keys)
137142

138143
# Initialize distance matrix with float values
139-
dist = [[euclidean_distance(graph_points[nodes[i]], graph_points[nodes[j]]) for j in range(n)] for i in range(n)]
140-
141-
# Initialize a dynamic programming table with infinity
144+
dist = [
145+
[
146+
euclidean_distance(graph_points[nodes[i]], graph_points[nodes[j]])
147+
for j in range(n)
148+
]
149+
for i in range(n)
150+
]
151+
152+
# Initialize a dynamic programming table with infinity
142153
dp = [[float("inf")] * n for _ in range(1 << n)]
143-
dp[1][0] = 0 # Only visited node is the starting point at node 0
154+
dp[1][0] = 0 # Only visited node is the starting point at node 0
144155

145156
# Iterate through all masks of visited nodes
146157
for mask in range(1 << n):
@@ -149,14 +160,16 @@ def travelling_salesman_dynamic_programming(
149160
if mask & (1 << u):
150161
# Traverse nodes 'v' such that u->v
151162
for v in range(n):
152-
if mask & (1 << v) == 0: # If v is not visited
153-
next_mask = mask | (1 << v) # Upodate mask to include 'v'
163+
if mask & (1 << v) == 0: # If v is not visited
164+
next_mask = mask | (1 << v) # Upodate mask to include 'v'
154165
# Update dynamic programming table with minimum distance
155-
dp[next_mask][v] = min(dp[next_mask][v], dp[mask][u] + dist[u][v])
166+
dp[next_mask][v] = min(
167+
dp[next_mask][v], dp[mask][u] + dist[u][v]
168+
)
156169

157170
final_mask = (1 << n) - 1
158171
min_cost = float("inf")
159-
end_node = -1 # Track the last node in the optimal path
172+
end_node = -1 # Track the last node in the optimal path
160173

161174
for u in range(1, n):
162175
if min_cost > dp[final_mask][u] + dist[u][0]:
@@ -175,7 +188,7 @@ def travelling_salesman_dynamic_programming(
175188
== dp[mask ^ (1 << end_node)][u] + dist[u][end_node]
176189
):
177190
mask ^= 1 << end_node # Update mask to remove end node
178-
end_node = u # Set the previous node as end node
191+
end_node = u # Set the previous node as end node
179192
break
180193

181194
path.append(nodes[0]) # Bottom-up Order

0 commit comments

Comments
 (0)