遗传算法之物流运输求解,草稿式,结果进行归一化处理

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)

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不食人间烟火sweet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值