|
5 | 5 |
|
6 | 6 | def tsp(distances: list[list[int]]) -> int:
|
7 | 7 | """
|
8 |
| - Solves the Travelling Salesman Problem (TSP) using |
| 8 | + Solves the Travelling Salesman Problem (TSP) using |
9 | 9 | dynamic programming and bitmasking.
|
10 | 10 | Args:
|
11 |
| - distances: A 2D list where distances[i][j] represents the |
| 11 | + distances: 2D list where distances[i][j] is the |
12 | 12 | distance between city i and city j.
|
13 | 13 | Returns:
|
14 |
| - The minimum cost to complete the tour visiting all cities. |
| 14 | + Minimum cost to complete the |
| 15 | + tour visiting all cities. |
15 | 16 | Raises:
|
16 | 17 | ValueError: If any distance is negative.
|
17 | 18 |
|
18 | 19 | >>> tsp([[0, 10, 15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]])
|
19 | 20 | 80
|
20 | 21 | >>> tsp([[0, 29, 20, 21], [29, 0, 15, 17], [20, 15, 0, 28], [21, 17, 28, 0]])
|
21 | 22 | 69
|
22 |
| - >>> tsp([[0, 10, -15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]]) |
| 23 | + >>> tsp([[0, 10, -15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]]) |
23 | 24 | ValueError: Distance cannot be negative
|
24 | 25 | """
|
25 | 26 | n = len(distances)
|
26 | 27 | if any(distances[i][j] < 0 for i in range(n) for j in range(n)):
|
27 | 28 | raise ValueError("Distance cannot be negative")
|
| 29 | + |
28 | 30 | visited_all = (1 << n) - 1
|
29 | 31 |
|
30 | 32 | @lru_cache(None)
|
31 | 33 | def visit(city: int, mask: int) -> int:
|
32 |
| - """Recursively calculates the minimum cost of visiting all cities.""" |
| 34 | + """Recursively calculates the minimum cost to visit all cities.""" |
33 | 35 | if mask == visited_all:
|
34 | 36 | return distances[city][0] # Return to start
|
35 | 37 |
|
36 |
| - min_cost = float("inf") |
| 38 | + min_cost = float('inf') # Large value to compare against |
37 | 39 | for next_city in range(n):
|
38 |
| - if not mask & (1 << next_city): # If next_city is unvisited |
| 40 | + if not mask & (1 << next_city): # If unvisited |
39 | 41 | new_cost = distances[city][next_city] + visit(
|
40 | 42 | next_city, mask | (1 << next_city)
|
41 | 43 | )
|
42 | 44 | min_cost = min(min_cost, new_cost)
|
43 |
| - return min_cost |
| 45 | + return int(min_cost) # Ensure returning an integer |
44 | 46 |
|
45 |
| - return visit(0, 1) # Start from city 0 with only city 0 visited |
| 47 | + return visit(0, 1) # Start from city 0 with city 0 visited |
46 | 48 |
|
47 | 49 |
|
48 | 50 | if __name__ == "__main__":
|
49 | 51 | import doctest
|
50 |
| - |
51 | 52 | doctest.testmod()
|
0 commit comments