遗传算法(GA)用于解决双目标带时间窗的路径规划问题

% 双目标路径规划问题
% 目标1:企业综合成本
% 目标2:客户服务满意度
% 使用遗传算法优化

clear; clc; close all;

%% 参数设置
num_customers = 10; % 客户数量
num_vehicles = 3; % 车辆数量
depot = [0, 0]; % 出发点 (仓库)
time_windows = [0, 100; 10, 50; 20, 60; 30, 70; 40, 80; 50, 90; 60, 100; 70, 110; 80, 120; 90, 130]; % 客户时间窗
service_times = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]; % 服务时间
distances = pdist2(rand(num_customers, 2) * 100, rand(num_customers, 2) * 100); % 随机生成距离矩阵

% 添加仓库到每个客户的距离
distances = [zeros(1, num_customers); distances];
distances = [zeros(num_customers+1, 1), distances];

%% 遗传算法参数设置
population_size = 50; % 种群大小
max_generations = 100; % 最大迭代次数
mutation_rate = 0.1; % 变异率
crossover_rate = 0.8; % 交叉率
elite_rate = 0.1; % 精英选择比例

%% 初始化种群
population = randi([1, num_customers], population_size, num_customers);

% 添加起点和终点
population = [zeros(population_size, 1), population, zeros(population_size, 1)];

%% 目标函数:企业综合成本与客户服务满意度
objective_function = @(route) calculate_objectives(route, distances, service_times, time_windows);

% 计算目标值
fitness_values = zeros(population_size, 2); % 每个个体的目标值
for i = 1:population_size
    fitness_values(i, :) = objective_function(population(i, :));
end

%% 主循环:遗传算法优化
for generation = 1:max_generations
    % 选择父代
    [selected_parents, selected_indices] = select_parents(population, fitness_values, elite_rate);

    % 交叉与变异
    offspring = crossover_and_mutate(selected_parents, crossover_rate, mutation_rate, num_customers);

    % 计算后代的适应度
    new_fitness_values = zeros(size(offspring, 1), 2);
    for i = 1:size(offspring, 1)
        new_fitness_values(i, :) = objective_function(offspring(i, :));
    end

    % 更新种群与适应度
    [population, fitness_values] = update_population(population, fitness_values, offspring, new_fitness_values, elite_rate);

    % 输出当前最优解
    [min_fitness, best_idx] = min(fitness_values(:, 1));
    fprintf('Generation %d: Best Cost = %.2f, Best Satisfaction = %.2f\n', generation, min_fitness, fitness_values(best_idx, 2));

    % 可视化进化过程
    figure(1);
    subplot(1, 2, 1);
    scatter(population(best_idx, 2:end-1), fitness_values(best_idx, 1));
    title('Cost vs. Satisfaction');
    xlabel('Customer Index');
    ylabel('Cost');
    grid on;

    subplot(1, 2, 2);
    plot(1:generation, min_fitness, 'r-', 'LineWidth', 2);
    title('Minimum Cost Over Generations');
    xlabel('Generation');
    ylabel('Cost');
    grid on;

    pause(0.1); % 动态显示
end

%% 结果显示
best_route = population(best_idx, :);
fprintf('Optimal Route: ');
disp(best_route);

% 绘制最优路径
figure;
plot_route(best_route, depot, distances);

%% 目标函数计算
function objectives = calculate_objectives(route, distances, service_times, time_windows)
    % 计算企业综合成本(距离和服务时间)与客户服务满意度(时间窗约束)
    total_distance = 0;
    satisfaction = 0;
    
    for i = 2:(length(route) - 1) % 跳过第一个和最后一个仓库点
        customer_idx = route(i); % 客户索引
        previous_idx = route(i - 1); % 前一个点的索引(可能是仓库或其他客户)
        
        % 计算从前一个点到当前客户的距离
        total_distance = total_distance + distances(previous_idx + 1, customer_idx + 1); 
        
        % 计算到达当前客户的时间
        arrival_time = sum(service_times(1:(i-1))) + total_distance; 
        
        % 检查是否满足时间窗
        if arrival_time >= time_windows(customer_idx, 1) && arrival_time <= time_windows(customer_idx, 2)
            satisfaction = satisfaction + 1; % 满足时间窗要求
        end
    end
    
    % 计算总成本
    total_cost = total_distance + sum(service_times); % 综合成本
    objectives = [total_cost, satisfaction];
end

%% 父代选择
function [selected_parents, selected_indices] = select_parents(population, fitness_values, elite_rate)
    % 选择父代,基于精英选择与轮盘赌
    num_elites = round(elite_rate * size(population, 1));
    [~, sorted_indices] = sort(fitness_values(:, 1));
    elites = population(sorted_indices(1:num_elites), :);

    % 轮盘赌选择
    fitness_sum = sum(fitness_values(:, 1));
    selection_probs = fitness_values(:, 1) / fitness_sum;
    selected_indices = randsample(1:size(population, 1), size(population, 1) - num_elites, true, 1 - selection_probs);
    selected_parents = [elites; population(selected_indices, :)];
end

%% 交叉与变异
function offspring = crossover_and_mutate(parents, crossover_rate, mutation_rate, num_customers)
    % 对父代进行交叉和变异操作
    offspring = parents;
    for i = 1:2:size(parents, 1) - 1
        if rand < crossover_rate
            cross_point = randi([2, num_customers]);
            offspring(i, cross_point:end) = parents(i+1, cross_point:end);
            offspring(i+1, cross_point:end) = parents(i, cross_point:end);
        end

        % 变异
        if rand < mutation_rate
            mutate_point = randi([2, num_customers]);
            offspring(i, mutate_point) = randi([1, num_customers]);
        end
    end
end

%% 更新种群
function [new_population, new_fitness_values] = update_population(population, fitness_values, offspring, new_fitness_values, elite_rate)
    % 更新种群,保留精英个体
    num_elites = round(elite_rate * size(population, 1));
    [~, sorted_indices] = sort(fitness_values(:, 1));
    elites = population(sorted_indices(1:num_elites), :);
    elites_fitness = fitness_values(sorted_indices(1:num_elites), :);

    % 合并后代与精英
    new_population = [elites; offspring];
    new_fitness_values = [elites_fitness; new_fitness_values];
end

%% 绘制路径
function plot_route(route, depot, ~)
    % 绘制最优路径
    figure;
    hold on;
    plot(depot(1), depot(2), 'ro', 'MarkerSize', 10, 'LineWidth', 2);
    for i = 1:(length(route) - 1)
        plot([route(i), route(i+1)], [route(i), route(i+1)], 'bo-', 'LineWidth', 2);
        text(route(i), route(i), num2str(route(i)), 'FontSize', 10, 'HorizontalAlignment', 'right');
    end
    plot(depot(1), depot(2), 'ro', 'MarkerSize', 10, 'LineWidth', 2);
    title('Optimal Route');
    xlabel('X Coordinate');
    ylabel('Y Coordinate');
    grid on;
    hold off;
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值