旅行商问题(TSP)示例与分支定界法实现---deepseek作答
·
旅行商问题(TSP)示例与分支定界法实现
下面我将提供一个旅行商问题(TSP)的示例,以及使用分支定界法解决该问题的Python代码实现。
问题示例
让我们考虑一个简单的4城市TSP实例,距离矩阵如下:
| A | B | C | D | |
|---|---|---|---|---|
| A | 0 | 10 | 15 | 20 |
| B | 10 | 0 | 35 | 25 |
| C | 15 | 35 | 0 | 30 |
| D | 20 | 25 | 30 | 0 |
这个矩阵表示:
- A到B的距离是10
- A到C的距离是15
- A到D的距离是20
- B到C的距离是35
- B到D的距离是25
- C到D的距离是30
分支定界法Python实现
import numpy as np
from copy import deepcopy
import heapq
class TSPSolver:
def __init__(self, distance_matrix):
self.n = len(distance_matrix)
self.dist_mat = distance_matrix
self.best_path = None
self.best_cost = float('inf')
def solve(self):
# 初始化优先队列(最小堆),用于存储待处理的节点
# 每个节点包含(下界, 路径, 成本, 减少矩阵)
pq = []
# 计算初始下界(通过减少矩阵)
reduced_matrix, lower_bound = self.reduce_matrix(deepcopy(self.dist_mat))
# 创建初始节点(从城市0开始)
initial_path = [0]
heapq.heappush(pq, (lower_bound, initial_path, 0, reduced_matrix))
while pq:
# 获取下界最小的节点
lower_bound, path, cost, reduced_mat = heapq.heappop(pq)
# 如果当前下界已经大于已知最优解,剪枝
if lower_bound >= self.best_cost:
continue
# 如果已经访问了所有城市
if len(path) == self.n:
# 添加返回起点的成本
final_cost = cost + self.dist_mat[path[-1]][path[0]]
if final_cost < self.best_cost:
self.best_cost = final_cost
self.best_path = path + [path[0]]
continue
# 对当前节点的子节点进行分支
current_city = path[-1]
for next_city in range(self.n):
if next_city in path:
continue
# 创建子节点
new_path = path + [next_city]
new_cost = cost + self.dist_mat[current_city][next_city]
# 创建新的减少矩阵
new_reduced_mat = deepcopy(reduced_mat)
# 将当前行和列设为无穷大(避免重复访问)
for i in range(self.n):
new_reduced_mat[current_city][i] = float('inf')
new_reduced_mat[i][next_city] = float('inf')
# 避免形成小循环(对于非对称TSP很重要)
new_reduced_mat[next_city][path[0]] = float('inf')
# 计算新节点的下界
child_reduced_mat, reduction_cost = self.reduce_matrix(new_reduced_mat)
child_lower_bound = new_cost + reduction_cost
# 如果下界小于当前最优解,将子节点加入优先队列
if child_lower_bound < self.best_cost:
heapq.heappush(pq, (child_lower_bound, new_path, new_cost, child_reduced_mat))
return self.best_path, self.best_cost
def reduce_matrix(self, matrix):
"""
减少矩阵并返回减少后的矩阵和减少成本
"""
reduction_cost = 0
n = len(matrix)
# 行减少
for i in range(n):
min_val = min(matrix[i])
if min_val != float('inf') and min_val > 0:
reduction_cost += min_val
for j in range(n):
if matrix[i][j] != float('inf'):
matrix[i][j] -= min_val
# 列减少
for j in range(n):
min_val = min(matrix[i][j] for i in range(n))
if min_val != float('inf') and min_val > 0:
reduction_cost += min_val
for i in range(n):
if matrix[i][j] != float('inf'):
matrix[i][j] -= min_val
return matrix, reduction_cost
# 示例使用
if __name__ == "__main__":
# 定义距离矩阵
dist_mat = [
[0, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 30, 0]
]
# 创建求解器并解决问题
solver = TSPSolver(dist_mat)
best_path, best_cost = solver.solve()
# 打印结果
print("最优路径:", [chr(65 + city) for city in best_path]) # 将数字转换为字母(A, B, C, D)
print("最短距离:", best_cost)
代码解释
1. 初始化
TSPSolver类初始化时接收距离矩阵- 设置最佳路径和最佳成本的初始值
2. 解决函数
- 使用优先队列(最小堆)存储待处理的节点
- 每个节点包含下界、路径、成本和减少矩阵
- 从初始节点(从城市0开始)开始处理
3. 减少矩阵函数
- 行减少:每行减去该行的最小值
- 列减少:每列减去该列的最小值
- 返回减少后的矩阵和减少成本(下界)
4. 分支过程
- 对于每个节点,生成所有可能的下一城市
- 创建子节点并计算其下界
- 如果下界小于当前最优解,将子节点加入优先队列
5. 终止条件
- 当路径包含所有城市时,计算返回起点的成本
- 如果该成本小于当前最优解,更新最优解
执行结果
对于我们的4城市示例,代码将输出:
最优路径: ['A', 'B', 'D', 'C', 'A']
最短距离: 80
这意味着最优路径是 A → B → D → C → A,总距离为 80(10 + 25 + 30 + 15)。
算法分析
- 分支策略:算法通过优先处理下界最小的节点,增加了找到最优解的可能性。
- 定界策略:通过矩阵减少计算下界,有效地剪枝了大量不可能产生最优解的分支。
- 复杂度:最坏情况下仍是指数级,但对于中小规模的TSP实例非常有效。
扩展和改进
- 启发式初始解:可以使用最近邻法等启发式算法先找到一个较好的解作为初始上界,从而更早地进行剪枝。
- 更好的下界计算:可以使用最小生成树或其他方法计算更紧凑的下界。
- 并行计算:可以将分支过程并行化,加速求解。
- 内存管理:对于大规模问题,可以实现迭代加深或其他策略来管理内存使用。
这个实现提供了分支定界法解决TSP的基本框架,可以根据具体需求进行扩展和优化。
更多推荐




所有评论(0)