2
2
3
3
from functools import lru_cache
4
4
5
-
6
5
def tsp (distances : list [list [int ]]) -> int :
7
6
"""
8
- Solves the Travelling Salesman Problem (TSP) using dynamic programming and bitmasking.
9
-
7
+ Solves the Travelling Salesman Problem (TSP) using
8
+ dynamic programming and bitmasking.
10
9
Args:
11
- distances: A 2D list where distances[i][j] represents the distance between city i and city j.
12
-
10
+ distances: A 2D list where distances[i][j] represents the
11
+ distance between city i and city j.
13
12
Returns:
14
13
The minimum cost to complete the tour visiting all cities.
15
-
16
14
Raises:
17
15
ValueError: If any distance is negative.
18
16
19
17
>>> tsp([[0, 10, 15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]])
20
18
80
21
19
>>> tsp([[0, 29, 20, 21], [29, 0, 15, 17], [20, 15, 0, 28], [21, 17, 28, 0]])
22
20
69
23
- >>> tsp([[0, 10, -15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]]) # doctest: +ELLIPSIS
24
- Traceback (most recent call last):
25
- ...
21
+ >>> tsp([[0, 10, -15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]])
26
22
ValueError: Distance cannot be negative
27
23
"""
28
24
n = len (distances )
29
25
if any (distances [i ][j ] < 0 for i in range (n ) for j in range (n )):
30
26
raise ValueError ("Distance cannot be negative" )
31
-
32
27
visited_all = (1 << n ) - 1
33
28
34
29
@lru_cache (None )
@@ -45,11 +40,7 @@ def visit(city: int, mask: int) -> int:
45
40
)
46
41
min_cost = min (min_cost , new_cost )
47
42
return min_cost
48
-
49
43
return visit (0 , 1 ) # Start from city 0 with only city 0 visited
50
-
51
-
52
44
if __name__ == "__main__" :
53
45
import doctest
54
-
55
46
doctest .testmod ()
0 commit comments