% 双目标路径规划问题
% 目标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
遗传算法(GA)用于解决双目标带时间窗的路径规划问题
最新推荐文章于 2024-10-27 12:10:10 发布