禁忌搜索算法求解CVRP问题Python代码复现,每行代码标注中文注释和画图
时间: 2024-04-29 20:20:52 浏览: 117
以下是禁忌搜索算法求解CVRP问题Python代码的复现:
```python
import random
import copy
import matplotlib.pyplot as plt
# 定义车辆容量
capacity = 50
# 定义城市坐标
cities = {
0: (50, 50),
1: (30, 40),
2: (10, 30),
3: (40, 70),
4: (70, 30),
5: (20, 20),
6: (80, 60),
7: (30, 60),
8: (50, 10),
9: (90, 30)
}
# 定义初始解
init_solution = [[0], [1, 2, 3, 4, 5], [6, 7], [8, 9]]
# 计算两个城市之间的距离
def distance(city1, city2):
x1, y1 = cities[city1]
x2, y2 = cities[city2]
return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
# 计算解的总距离
def total_distance(solution):
total = 0
for route in solution:
for i in range(len(route) - 1):
total += distance(route[i], route[i+1])
return total
# 交换两个城市的位置
def swap(solution, i, j):
new_solution = copy.deepcopy(solution)
for route in new_solution:
if i in route and j in route:
index_i = route.index(i)
index_j = route.index(j)
route[index_i], route[index_j] = route[index_j], route[index_i]
break
return new_solution
# 随机选择两个城市进行交换
def random_swap(solution):
new_solution = copy.deepcopy(solution)
while True:
route1 = random.choice(new_solution)
route2 = random.choice(new_solution)
if len(route1) == 1 or len(route2) == 1:
continue
i = random.choice(route1[1:-1])
j = random.choice(route2[1:-1])
if sum([capacity - cities[i][1] for i in route1]) + cities[j][1] > capacity \
or sum([capacity - cities[i][1] for i in route2]) + cities[i][1] > capacity:
continue
return swap(new_solution, i, j)
# 计算移动的距离
def move_distance(solution, i, j):
new_solution = swap(solution, i, j)
return total_distance(new_solution) - total_distance(solution)
# 禁忌搜索算法
def tabu_search(init_solution, max_iter, tabu_tenure):
# 初始化当前解和最优解
current_solution = init_solution
best_solution = init_solution
# 初始化禁忌列表
tabu_list = []
# 迭代max_iter次
for i in range(max_iter):
# 选择邻域中移动距离最小的解
min_distance = float('inf')
for i in range(len(current_solution)):
for j in range(i+1, len(current_solution)):
if (i, j) in tabu_list:
continue
distance = move_distance(current_solution, i, j)
if distance < min_distance:
min_distance = distance
move_i, move_j = i, j
# 更新当前解和最优解
current_solution = swap(current_solution, move_i, move_j)
if total_distance(current_solution) < total_distance(best_solution):
best_solution = current_solution
# 更新禁忌列表
tabu_list.append((move_i, move_j))
if len(tabu_list) > tabu_tenure:
tabu_list.pop(0)
return best_solution
# 打印最优解和最优解的距离
best_solution = tabu_search(init_solution, 100, 10)
print('最优解:', best_solution)
print('最优解的距离:', total_distance(best_solution))
# 画出最优解的路径图
for route in best_solution:
x = []
y = []
for city in route:
x.append(cities[city][0])
y.append(cities[city][1])
plt.plot(x, y, 'o-')
plt.show()
```
代码中首先定义了车辆容量和城市坐标。然后定义了计算两个城市之间距离的函数、计算解的总距离的函数、交换两个城市位置的函数、随机选择两个城市进行交换的函数、计算移动的距离的函数以及禁忌搜索算法的函数。在主函数中,首先调用禁忌搜索算法函数求解最优解,并打印最优解和最优解的距离。最后,使用Matplotlib库画出最优解的路径图。
阅读全文