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