使用遗传算法解决CVRP问题用deap库写出程序
以下是使用遗传算法解决CVRP问题的程序,使用deap库:
import random
import numpy as np
from deap import base, creator, tools, algorithms
# 定义染色体的长度、种群大小、迭代次数、交叉概率、变异概率
n_nodes = 20 # 节点数
n_customers = n_nodes - 1 # 客户数
pop_size = 100 # 种群大小
n_generations = 100 # 迭代次数
cx_prob = 0.8 # 交叉概率
mut_prob = 0.2 # 变异概率
# 读取数据
with open("cvrp_data.txt", "r") as f:
data = f.readlines()
# 保存节点的坐标和需求量
nodes = np.zeros((n_nodes, 3))
for i in range(n_nodes):
nodes[i] = np.array(data[i].split(), dtype=float)
# 计算距离矩阵
distances = np.zeros((n_nodes, n_nodes))
for i in range(n_nodes):
for j in range(n_nodes):
distances[i][j] = np.sqrt(np.sum((nodes[i][:2] - nodes[j][:2])**2))
# 定义适应度函数
def fitness(individual):
# 计算每个车辆的路径长度
routes = [[] for _ in range(n_customers)]
for i in range(n_customers):
j = individual[i]
routes[j].append(i)
total_distance = 0
for route in routes:
if len(route) == 0:
continue
route_distance = distances[0][route[0]+1] + distances[route[-1]+1][0]
for i in range(len(route)-1):
route_distance += distances[route[i]+1][route[i+1]+1]
total_distance += route_distance
# 计算每个车辆的容量
capacities = [nodes[0][2]] * n_customers
for i in range(n_customers):
j = individual[i]
capacities[j] -= nodes[i+1][2]
for capacity in capacities:
if capacity < 0:
total_distance += 1000000 # 惩罚函数,超出容量的车辆需要额外加费用
return 1 / total_distance,
# 创建遗传算法的对象
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin)
toolbox = base.Toolbox()
toolbox.register("indices", random.sample, range(n_customers), n_customers)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.indices)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("mate", tools.cxOrdered)
toolbox.register("mutate", tools.mutShuffleIndexes, indpb=0.05)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", fitness)
# 运行遗传算法
pop = toolbox.population(n=pop_size)
best_ind = None
best_fitness = float("inf")
for gen in range(n_generations):
offspring = algorithms.varAnd(pop, toolbox, cxpb=cx_prob, mutpb=mut_prob)
fits = toolbox.map(toolbox.evaluate, offspring)
for fit, ind in zip(fits, offspring):
ind.fitness.values = fit
if fit[0] < best_fitness:
best_ind = ind
best_fitness = fit[0]
pop = toolbox.select(offspring, k=len(pop))
# 输出结果
print("Best individual: ", best_ind)
print("Best fitness: ", best_fitness)
其中,我们使用了cvrp_data.txt文件中的数据,文件内容如下:
0 40.0 50.0
1 22.0 22.0 18.0
2 36.0 26.0 26.0
3 21.0 45.0 11.0
4 45.0 35.0 30.0
5 55.0 20.0 21.0
6 33.0 34.0 19.0
7 50.0 50.0 16.0
8 55.0 45.0 29.0
9 26.0 59.0 26.0
10 40.0 66.0 37.0
11 55.0 65.0 16.0
12 35.0 51.0 12.0
13 62.0 35.0 31.0
14 62.0 57.0 8.0
15 62.0 24.0 19.0
16 21.0 36.0 23.0
17 33.0 44.0 20.0
18 9.0 56.0 13.0
19 62.0 48.0 15.0
其中,每行的第一个数字表示节点编号,第二个数字表示该节点的x坐标,第三个数字表示该节点的y坐标,第四个数字表示该节点的需求量。
运行结果会输出最优个体和适应度值。
原文地址: https://www.cveoy.top/t/topic/bSFB 著作权归作者所有。请勿转载和采集!