|
| 1 | +from itertools import combinations |
| 2 | + |
| 3 | +def tsp_dynamic_programming(dist_matrix): |
| 4 | + n = len(dist_matrix) # number of cities |
| 5 | + |
| 6 | + # Initialize a dictionary to store the costs of visiting a subset of cities ending at city i |
| 7 | + # dp[subset][i] will store the minimum cost to visit all cities in 'subset' and end at city i |
| 8 | + dp = {} |
| 9 | + |
| 10 | + # Base case: Starting from the first city, i.e., only city 0 is visited |
| 11 | + for i in range(1, n): |
| 12 | + dp[(1 << i, i)] = dist_matrix[0][i] # Subset contains city 0 and city i |
| 13 | + |
| 14 | + # Iterate through subsets of cities (of increasing size) |
| 15 | + for subset_size in range(2, n): |
| 16 | + for subset in combinations(range(1, n), subset_size): |
| 17 | + # Create the subset bitmask |
| 18 | + subset_mask = 0 |
| 19 | + for city in subset: |
| 20 | + subset_mask |= 1 << city |
| 21 | + |
| 22 | + # Try ending at each city 'j' in the subset |
| 23 | + for j in subset: |
| 24 | + prev_mask = subset_mask & ~(1 << j) # Remove city j from the subset |
| 25 | + dp[(subset_mask, j)] = min( |
| 26 | + dp[(prev_mask, k)] + dist_matrix[k][j] for k in subset if k != j |
| 27 | + ) |
| 28 | + |
| 29 | + # Final step: Consider returning to the start (city 0) from each possible city |
| 30 | + final_mask = (1 << n) - 2 # All cities visited except city 0 |
| 31 | + return min(dp[(final_mask, i)] + dist_matrix[i][0] for i in range(1, n)) |
| 32 | + |
| 33 | +# Example usage |
| 34 | +if __name__ == "__main__": |
| 35 | + # Example distance matrix (symmetric matrix where dist_matrix[i][j] is the distance between city i and city j) |
| 36 | + dist_matrix = [ |
| 37 | + [0, 10, 15, 20], |
| 38 | + [10, 0, 35, 25], |
| 39 | + [15, 35, 0, 30], |
| 40 | + [20, 25, 30, 0] |
| 41 | + ] |
| 42 | + |
| 43 | + result = tsp_dynamic_programming(dist_matrix) |
| 44 | + print(f"The minimum travel cost is: {result}") |
0 commit comments