import numpy as np
import matplotlib.pyplot as plt
# 定义问题参数
num_locations = 50 # 地点数量
num_vehicles = 3 # 车辆数量
num_genes = num_locations * num_vehicles # 基因数量
# 生成城市坐标和货物量
np.random.seed(42)
city_coordinates = np.random.rand(num_locations, 2) * 10 # 生成在[0, 10)范围内的城市坐标
goods_quantity = np.random.randint(1, 10, size=num_locations) # 每个地点需要输送的货物量
# 生成初始种群
def generate_population(pop_size):
return np.random.randint(0, num_vehicles, size=(pop_size, num_genes))
# 计算适应度函数(这里简化为总距离最小化)
def fitness(individual):
routes = individual.reshape((num_vehicles, num_locations))
total_distance = 0
for vehicle_index in range(num_vehicles):
route = routes[vehicle_index]
vehicle_path = city_coordinates[route]
total_distance += np.sum(np.linalg.norm(np.diff(np.vstack((vehicle_path, vehicle_path[0])), axis=0), axis=1))
return -total_distance # 负值,因为遗传算法通常是最大化适应度
def normalize_fitness(original_fitness):
# 线性归一化,将适应度值映射到[0, 1]范围
min_fitness = np.min(original_fitness)
max_fitness = np.max(original_fitness)
normalized_fitness = (original_fitness - min_fitness) / (max_fitness - min_fitness)
return normalized_fitness
# 竞标赛选择算子
def tournament_selection(population, tournament_size):
selected_indices = []
pop_size = len(population)
for _ in range(pop_size):
tournament_indices = np.random.choice(pop_size, size=tournament_size, replace=False)
tournament_individuals = population[tournament_indices]
tournament_fitness = [fitness(ind) for ind in tournament_individuals]
winner_index = tournament_indices[np.argmax(tournament_fitness)]
selected_indices.append(winner_index)
return population[selected_indices]
# 交叉操作:单点交叉
def crossover(parent1, parent2):
crossover_point = np.random.randint(1, len(parent1) - 1)
child1 = np.concatenate((parent1[:crossover_point], parent2[crossover_point:]))
child2 = np.concatenate((parent2[:crossover_point], parent1[crossover_point:]))
return child1, child2
# 变异操作:随机选择一个基因进行变异
def mutation(individual, mutation_rate):
if np.random.rand() < mutation_rate:
gene_to_mutate = np.random.randint(len(individual))
individual[gene_to_mutate] = np.random.randint(num_vehicles)
return individual
# 遗传算法主函数
def genetic_algorithm(pop_size, generations, mutation_rate, tournament_size):
population = generate_population(pop_size)
best_fitness_history = []
for generation in range(generations):
selected_population = tournament_selection(population, tournament_size)
new_population = []
for i in range(0, pop_size, 2):
parent1, parent2 = selected_population[i], selected_population[i + 1]
child1, child2 = crossover(parent1, parent2)
child1 = mutation(child1, mutation_rate)
child2 = mutation(child2, mutation_rate)
new_population.extend([child1, child2])
population = np.array(new_population)
best_fitness = np.max([fitness(ind) for ind in population])
best_fitness_history.append(best_fitness)
best_individual = population[np.argmax([fitness(ind) for ind in population])]
best_routes = best_individual.reshape((num_vehicles, num_locations))
return best_routes, best_fitness_history
# 绘制城市坐标
def plot_city_coordinates(coordinates):
plt.scatter(coordinates[:, 0], coordinates[:, 1], c='red', marker='o')
plt.title('City Coordinates')
plt.xlabel('X-coordinate')
plt.ylabel('Y-coordinate')
plt.show()
# 绘制适应度变化图像
def plot_fitness_history(fitness_history):
plt.plot(fitness_history)
plt.title('Fitness History')
plt.xlabel('Generation')
plt.ylabel('Fitness')
plt.show()
# 调用遗传算法主函数
best_solution, fitness_history = genetic_algorithm(pop_size=100, generations=1000, mutation_rate=0.1, tournament_size=5)
print("最优解(每辆车的路线):")
print(best_solution)
# 绘制城市坐标
plot_city_coordinates(city_coordinates)
# 绘制适应度变化图像
fitness_history_update = normalize_fitness(fitness_history)
plot_fitness_history(fitness_history_update)
遗传算法之物流运输求解,草稿式,结果进行归一化处理
最新推荐文章于 2024-07-27 12:20:46 发布