一、双层规划问题与遗传算法原理
1.1 双层规划数学模型
上层规划(领导者):
min F(x, y)
s.t. G(x, y) ≤ 0
x ∈ X
下层规划(跟随者):
min f(x, y)
s.t. g(x, y) ≤ 0
y ∈ Y
其中:y 是 x 的函数,y = S(x) 是下层问题的最优解
1.2 遗传算法在双层规划中的挑战
| 挑战 | 描述 | 解决方案 |
|---|---|---|
| 嵌套优化 | 每评估一个上层解都需要解下层问题 | 下层问题近似/并行计算 |
| 计算复杂度 | 双层遗传算法嵌套 | 代理模型/响应面方法 |
| 收敛性 | 可能收敛到局部最优 | 多种群/自适应策略 |
| 约束处理 | 双层约束需同时满足 | 可行解保持/修复策略 |
二、完整MATLAB实现
2.1 主程序(main_ga_bilevel.m)
matlab
%% 遗传算法求解双层规划模型
clc; clear; close all;
warning('off', 'all');
%% 1. 双层规划问题定义
% 上层问题(领导者):最小化投资成本 + 运营成本
% 下层问题(跟随者):最小化运输成本
fprintf('双层规划问题:投资-运输优化\n');
% 问题规模
n_facilities = 3; % 设施数量
n_customers = 5; % 客户数量
n_products = 2; % 产品类型
%% 2. 参数设置
% 遗传算法参数
ga_params.upper_pop_size = 50; % 上层种群大小
ga_params.lower_pop_size = 30; % 下层种群大小
ga_params.max_generations = 100; % 最大代数
ga_params.crossover_rate = 0.8; % 交叉概率
ga_params.mutation_rate = 0.1; % 变异概率
ga_params.elite_count = 2; % 精英保留数量
ga_params.tournament_size = 3; % 锦标赛选择大小
% 双层规划参数
bilevel_params.fixed_cost = [100, 150, 120]; % 固定投资成本
bilevel_params.capacity = [200, 250, 300]; % 设施容量
bilevel_params.demand = [50, 60, 40, 70, 55; 30, 40, 25, 50, 35]; % 需求矩阵
bilevel_params.production_cost = [8, 10, 7; 12, 15, 11]; % 生产成本
bilevel_params.transport_cost = zeros(n_facilities, n_customers, n_products);
% 生成运输成本
for f = 1:n_facilities
for c = 1:n_customers
for p = 1:n_products
bilevel_params.transport_cost(f,c,p) = 2 + 0.5*rand();
end
end
end
%% 3. 遗传算法主循环
fprintf('开始双层遗传算法...\n');
% 初始化上层种群
upper_pop = initialize_upper_population(ga_params.upper_pop_size, n_facilities);
% 存储最优解
best_upper_solution = [];
best_lower_solution = [];
best_fitness = inf;
fitness_history = zeros(ga_params.max_generations, 1);
convergence_history = zeros(ga_params.max_generations, 2);
% 进度条
progress_bar = waitbar(0, '优化进行中...');
for gen = 1:ga_params.max_generations
% 显示进度
if mod(gen, 10) == 0
waitbar(gen/ga_params.max_generations, progress_bar, ...
sprintf('第%d代/共%d代', gen, ga_params.max_generations));
end
%% 步骤1: 对每个上层个体求解下层问题
lower_solutions = cell(ga_params.upper_pop_size, 1);
upper_fitness = zeros(ga_params.upper_pop_size, 1);
lower_fitness = zeros(ga_params.upper_pop_size, 1);
for i = 1:ga_params.upper_pop_size
% 提取上层决策变量
upper_solution = upper_pop(i, :);
% 求解下层问题
[lower_solution, lower_obj] = solve_lower_problem(...
upper_solution, ga_params, bilevel_params);
% 计算上层目标函数
upper_obj = evaluate_upper_objective(...
upper_solution, lower_solution, bilevel_params);
% 存储结果
lower_solutions{i} = lower_solution;
upper_fitness(i) = upper_obj;
lower_fitness(i) = lower_obj;
end
%% 步骤2: 记录最优解
[min_fitness, min_idx] = min(upper_fitness);
if min_fitness < best_fitness
best_fitness = min_fitness;
best_upper_solution = upper_pop(min_idx, :);
best_lower_solution = lower_solutions{min_idx};
end
fitness_history(gen) = best_fitness;
convergence_history(gen, :) = [mean(upper_fitness), std(upper_fitness)];
%% 步骤3: 上层种群进化
if gen < ga_params.max_generations
% 选择
selected_indices = tournament_selection(upper_fitness, ...
ga_params.tournament_size, ga_params.upper_pop_size);
% 交叉
offspring = crossover(upper_pop(selected_indices, :), ...
ga_params.crossover_rate);
% 变异
offspring = mutation(offspring, ga_params.mutation_rate);
% 精英保留
[~, elite_indices] = sort(upper_fitness);
offspring(1:ga_params.elite_count, :) = ...
upper_pop(elite_indices(1:ga_params.elite_count), :);
% 更新种群
upper_pop = offspring;
end
% 显示当前最优
if mod(gen, 20) == 0
fprintf('第%d代: 最优适应度 = %.4f\n', gen, best_fitness);
end
end
close(progress_bar);
%% 4. 结果显示
fprintf('\n优化完成!\n');
fprintf('最终适应度: %.4f\n', best_fitness);
fprintf('总迭代次数: %d\n', ga_params.max_generations);
% 显示最优解
display_optimal_solution(best_upper_solution, best_lower_solution, ...
bilevel_params, best_fitness);
% 绘制收敛曲线
plot_convergence_curves(fitness_history, convergence_history);
% 绘制最优解可视化
plot_solution_visualization(best_upper_solution, best_lower_solution, ...
bilevel_params);
%% 5. 灵敏度分析
perform_sensitivity_analysis(best_upper_solution, best_lower_solution, ...
ga_params, bilevel_params);
2.2 上层种群初始化(initialize_upper_population.m)
matlab
function pop = initialize_upper_population(pop_size, n_facilities)
% 初始化上层种群
% 上层决策变量:设施建设规模 [0-1] 之间的连续变量
% 输入: pop_size - 种群大小
% n_facilities - 设施数量
% 输出: pop - 初始化种群
pop = rand(pop_size, n_facilities);
% 确保多样性
for i = 1:pop_size
% 添加一些特殊初始化策略
if i == 1
% 全建设
pop(i, :) = ones(1, n_facilities);
elseif i == 2
% 不建设
pop(i, :) = zeros(1, n_facilities);
elseif i == 3
% 50%建设
pop(i, :) = 0.5 * ones(1, n_facilities);
end
end
end
2.3 下层问题求解(solve_lower_problem.m)
matlab
function [lower_solution, lower_obj] = solve_lower_problem(...
upper_solution, ga_params, params)
% 求解下层规划问题
% 下层问题:最小化运输成本
% 输入: upper_solution - 上层决策变量
% ga_params - 遗传算法参数
% params - 问题参数
% 输出: lower_solution - 下层最优解
% lower_obj - 下层目标函数值
% 提取问题参数
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
% 初始化下层种群
pop_size = ga_params.lower_pop_size;
pop = initialize_lower_population(pop_size, upper_solution, params);
% 下层遗传算法
max_iter = 30; % 下层优化迭代次数
best_solution = [];
best_fitness = inf;
for iter = 1:max_iter
% 评估适应度
fitness = zeros(pop_size, 1);
for i = 1:pop_size
fitness(i) = evaluate_lower_objective(...
pop(i, :), upper_solution, params);
end
% 记录最优
[min_fit, min_idx] = min(fitness);
if min_fit < best_fitness
best_fitness = min_fit;
best_solution = pop(min_idx, :);
end
% 进化操作
if iter < max_iter
% 选择
selected_indices = tournament_selection(fitness, 2, pop_size);
% 交叉
offspring = crossover(pop(selected_indices, :), ga_params.crossover_rate);
% 变异
offspring = mutation(offspring, ga_params.mutation_rate);
% 精英保留
[~, elite_indices] = sort(fitness);
offspring(1:2, :) = pop(elite_indices(1:2), :);
pop = offspring;
end
end
% 返回结果
lower_solution = best_solution;
lower_obj = best_fitness;
end
function pop = initialize_lower_population(pop_size, upper_solution, params)
% 初始化下层种群
% 下层决策变量:运输量
% 输入: pop_size - 种群大小
% upper_solution - 上层决策变量
% params - 问题参数
% 输出: pop - 初始化种群
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
n_vars = n_facilities * n_customers * n_products;
pop = zeros(pop_size, n_vars);
% 根据上层决策生成可行解
for i = 1:pop_size
idx = 1;
for f = 1:n_facilities
for c = 1:n_customers
for p = 1:n_products
% 设施建设水平
facility_level = upper_solution(f);
% 可运输的最大量
max_transport = facility_level * params.capacity(f) * ...
params.demand(p, c) / sum(params.demand(p, :));
% 随机生成运输量
pop(i, idx) = rand() * max_transport;
idx = idx + 1;
end
end
end
% 修复约束
pop(i, :) = repair_lower_solution(pop(i, :), upper_solution, params);
end
end
2.4 目标函数评估
matlab
function fitness = evaluate_upper_objective(upper_solution, lower_solution, params)
% 评估上层目标函数
% 上层目标:最小化总成本 = 投资成本 + 运输成本
% 输入: upper_solution - 上层决策变量
% lower_solution - 下层决策变量
% params - 问题参数
% 输出: fitness - 适应度值
% 投资成本
investment_cost = sum(params.fixed_cost .* upper_solution);
% 从下层解中提取运输成本
transport_cost = 0;
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
idx = 1;
for f = 1:n_facilities
for c = 1:n_customers
for p = 1:n_products
qty = lower_solution(idx);
unit_cost = params.transport_cost(f, c, p) + params.production_cost(p, f);
transport_cost = transport_cost + qty * unit_cost;
idx = idx + 1;
end
end
end
% 惩罚项:容量约束违反
penalty = calculate_upper_penalty(upper_solution, lower_solution, params);
% 总适应度
fitness = investment_cost + transport_cost + penalty;
end
function fitness = evaluate_lower_objective(lower_solution, upper_solution, params)
% 评估下层目标函数
% 下层目标:最小化运输成本
% 输入: lower_solution - 下层决策变量
% upper_solution - 上层决策变量
% params - 问题参数
% 输出: fitness - 适应度值
% 运输成本
transport_cost = 0;
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
idx = 1;
for f = 1:n_facilities
for c = 1:n_customers
for p = 1:n_products
qty = lower_solution(idx);
unit_cost = params.transport_cost(f, c, p);
transport_cost = transport_cost + qty * unit_cost;
idx = idx + 1;
end
end
end
% 惩罚项:需求满足约束违反
penalty = calculate_lower_penalty(lower_solution, upper_solution, params);
% 总适应度
fitness = transport_cost + penalty;
end
2.5 约束处理与惩罚函数
matlab
function penalty = calculate_upper_penalty(upper_solution, lower_solution, params)
% 计算上层约束违反惩罚
% 输入: upper_solution - 上层决策变量
% lower_solution - 下层决策变量
% params - 问题参数
% 输出: penalty - 惩罚值
penalty = 0;
alpha = 1000; % 惩罚系数
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
% 约束1:设施容量约束
idx = 1;
for f = 1:n_facilities
total_throughput = 0;
for c = 1:n_customers
for p = 1:n_products
total_throughput = total_throughput + lower_solution(idx);
idx = idx + 1;
end
end
capacity = upper_solution(f) * params.capacity(f);
if total_throughput > capacity
penalty = penalty + alpha * (total_throughput - capacity)^2;
end
end
% 约束2:投资预算约束(示例)
max_investment = 500;
investment = sum(params.fixed_cost .* upper_solution);
if investment > max_investment
penalty = penalty + alpha * (investment - max_investment)^2;
end
end
function penalty = calculate_lower_penalty(lower_solution, upper_solution, params)
% 计算下层约束违反惩罚
% 输入: lower_solution - 下层决策变量
% upper_solution - 上层决策变量
% params - 问题参数
% 输出: penalty - 惩罚值
penalty = 0;
alpha = 1000; % 惩罚系数
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
% 约束1:需求满足约束
for c = 1:n_customers
for p = 1:n_products
total_supply = 0;
idx = (c-1)*n_products*n_facilities + (p-1)*n_facilities + 1;
for f = 1:n_facilities
total_supply = total_supply + lower_solution(idx);
idx = idx + 1;
end
demand = params.demand(p, c);
if total_supply < demand
penalty = penalty + alpha * (demand - total_supply)^2;
end
end
end
% 约束2:非负约束
penalty = penalty + alpha * sum(min(0, lower_solution).^2);
end
function repaired_solution = repair_lower_solution(solution, upper_solution, params)
% 修复下层解以满足约束
% 输入: solution - 待修复的解
% upper_solution - 上层决策变量
% params - 问题参数
% 输出: repaired_solution - 修复后的解
repaired_solution = solution;
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
% 修复1:确保非负
repaired_solution = max(0, repaired_solution);
% 修复2:满足容量约束
idx = 1;
for f = 1:n_facilities
total_flow = 0;
start_idx = idx;
for c = 1:n_customers
for p = 1:n_products
total_flow = total_flow + repaired_solution(idx);
idx = idx + 1;
end
end
capacity = upper_solution(f) * params.capacity(f);
if total_flow > capacity
% 按比例缩减
scale_factor = capacity / (total_flow + eps);
for i = start_idx:idx-1
repaired_solution(i) = repaired_solution(i) * scale_factor;
end
end
end
% 修复3:满足需求约束
for c = 1:n_customers
for p = 1:n_products
demand = params.demand(p, c);
total_supply = 0;
% 计算当前总供应
for f = 1:n_facilities
pos = (c-1)*n_products*n_facilities + (p-1)*n_facilities + f;
total_supply = total_supply + repaired_solution(pos);
end
if total_supply < demand
% 按比例增加
scale_factor = demand / (total_supply + eps);
for f = 1:n_facilities
pos = (c-1)*n_products*n_facilities + (p-1)*n_facilities + f;
repaired_solution(pos) = repaired_solution(pos) * scale_factor;
end
end
end
end
end
2.6 遗传算子实现
matlab
function selected_indices = tournament_selection(fitness, tournament_size, n_selections)
% 锦标赛选择
% 输入: fitness - 适应度向量
% tournament_size - 锦标赛大小
% n_selections - 选择数量
% 输出: selected_indices - 被选中的个体索引
n_individuals = length(fitness);
selected_indices = zeros(n_selections, 1);
for i = 1:n_selections
% 随机选择参赛者
contestants = randperm(n_individuals, tournament_size);
% 选择最优的
[~, best_idx] = min(fitness(contestants));
selected_indices(i) = contestants(best_idx);
end
end
function offspring = crossover(parents, crossover_rate)
% 模拟二进制交叉 (SBX)
% 输入: parents - 父代个体
% crossover_rate - 交叉概率
% 输出: offspring - 子代个体
[n_parents, n_vars] = size(parents);
offspring = zeros(size(parents));
for i = 1:2:n_parents-1
if rand() < crossover_rate && i+1 <= n_parents
parent1 = parents(i, :);
parent2 = parents(i+1, :);
% 生成两个子代
child1 = zeros(1, n_vars);
child2 = zeros(1, n_vars);
for j = 1:n_vars
u = rand();
if u <= 0.5
beta = (2*u)^(1/21); % 分布指数 = 20
else
beta = (1/(2*(1-u)))^(1/21);
end
child1(j) = 0.5 * ((1+beta)*parent1(j) + (1-beta)*parent2(j));
child2(j) = 0.5 * ((1-beta)*parent1(j) + (1+beta)*parent2(j));
% 边界处理
child1(j) = max(0, min(1, child1(j)));
child2(j) = max(0, min(1, child2(j)));
end
offspring(i, :) = child1;
if i+1 <= n_parents
offspring(i+1, :) = child2;
end
else
% 不交叉,直接复制
offspring(i, :) = parents(i, :);
if i+1 <= n_parents
offspring(i+1, :) = parents(i+1, :);
end
end
end
end
function mutated_pop = mutation(pop, mutation_rate)
% 多项式变异
% 输入: pop - 种群
% mutation_rate - 变异概率
% 输出: mutated_pop - 变异后的种群
[pop_size, n_vars] = size(pop);
mutated_pop = pop;
for i = 1:pop_size
for j = 1:n_vars
if rand() < mutation_rate
r = rand();
if r < 0.5
delta = (2*r)^(1/21) - 1; % 分布指数 = 20
else
delta = 1 - (2*(1-r))^(1/21);
end
mutated_pop(i, j) = pop(i, j) + delta;
% 边界处理
mutated_pop(i, j) = max(0, min(1, mutated_pop(i, j)));
end
end
end
end
2.7 结果展示与分析
matlab
function display_optimal_solution(upper_solution, lower_solution, params, fitness)
% 显示最优解
% 输入: upper_solution - 上层最优解
% lower_solution - 下层最优解
% params - 问题参数
% fitness - 最优适应度
fprintf('\n=== 最优解信息 ===\n');
% 上层决策
fprintf('上层决策(设施建设水平):\n');
for f = 1:length(upper_solution)
fprintf(' 设施%d: %.2f (投资成本: $%.2f)\n', ...
f, upper_solution(f), params.fixed_cost(f) * upper_solution(f));
end
fprintf(' 总投资: $%.2f\n', sum(params.fixed_cost .* upper_solution));
% 下层决策
fprintf('\n下层决策(运输方案):\n');
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
idx = 1;
total_transport_cost = 0;
total_production_cost = 0;
for p = 1:n_products
fprintf(' 产品%d:\n', p);
for f = 1:n_facilities
facility_total = 0;
for c = 1:n_customers
qty = lower_solution(idx);
if qty > 0
transport_cost = qty * params.transport_cost(f, c, p);
production_cost = qty * params.production_cost(p, f);
total_cost = transport_cost + production_cost;
fprintf(' 设施%d->客户%d: %.2f 单位 ($%.2f)\n', ...
f, c, qty, total_cost);
total_transport_cost = total_transport_cost + transport_cost;
total_production_cost = total_production_cost + production_cost;
facility_total = facility_total + qty;
end
idx = idx + 1;
end
fprintf(' 设施%d总产量: %.2f\n', f, facility_total);
end
end
fprintf('\n成本分析:\n');
fprintf(' 投资成本: $%.2f\n', sum(params.fixed_cost .* upper_solution));
fprintf(' 生产成本: $%.2f\n', total_production_cost);
fprintf(' 运输成本: $%.2f\n', total_transport_cost);
fprintf(' 总成本: $%.2f\n', fitness);
fprintf(' 下层目标(仅运输): $%.2f\n', total_transport_cost);
% 约束检查
fprintf('\n约束检查:\n');
% 容量约束
idx = 1;
for f = 1:n_facilities
total_throughput = 0;
for c = 1:n_customers
for p = 1:n_products
total_throughput = total_throughput + lower_solution(idx);
idx = idx + 1;
end
end
capacity = upper_solution(f) * params.capacity(f);
fprintf(' 设施%d: 使用量%.2f/容量%.2f (利用率%.1f%%)\n', ...
f, total_throughput, capacity, total_throughput/capacity*100);
end
% 需求约束
for c = 1:n_customers
for p = 1:n_products
total_supply = 0;
idx_base = (c-1)*n_products*n_facilities + (p-1)*n_facilities;
for f = 1:n_facilities
total_supply = total_supply + lower_solution(idx_base + f);
end
demand = params.demand(p, c);
satisfaction = min(1, total_supply/demand) * 100;
fprintf(' 客户%d产品%d: 供应%.2f/需求%.2f (满足度%.1f%%)\n', ...
c, p, total_supply, demand, satisfaction);
end
end
end
2.8 可视化函数
matlab
function plot_convergence_curves(fitness_history, convergence_history)
% 绘制收敛曲线
% 输入: fitness_history - 最优适应度历史
% convergence_history - 收敛历史
figure('Position', [100, 100, 1200, 400]);
% 子图1:最优适应度收敛曲线
subplot(1,2,1);
plot(fitness_history, 'b-', 'LineWidth', 2);
hold on;
grid on;
xlabel('迭代次数');
ylabel('最优适应度');
title('最优适应度收敛曲线');
legend('最优解');
% 添加平滑线
window_size = 5;
smoothed = movmean(fitness_history, window_size);
plot(smoothed, 'r--', 'LineWidth', 1.5);
legend('原始', sprintf('移动平均(窗口=%d)', window_size));
% 子图2:种群多样性
subplot(1,2,2);
plot(convergence_history(:,1), 'b-', 'LineWidth', 2);
hold on;
plot(convergence_history(:,1) + convergence_history(:,2), 'r--', 'LineWidth', 1);
plot(convergence_history(:,1) - convergence_history(:,2), 'r--', 'LineWidth', 1);
fill([1:length(fitness_history), length(fitness_history):-1:1], ...
[convergence_history(:,1)' + convergence_history(:,2)', ...
fliplr(convergence_history(:,1)' - convergence_history(:,2)')], ...
'r', 'FaceAlpha', 0.2, 'EdgeColor', 'none');
grid on;
xlabel('迭代次数');
ylabel('适应度');
title('种群适应度统计');
legend('均值', '±标准差', '标准差范围');
% 保存图片
saveas(gcf, 'convergence_curves.png');
end
function plot_solution_visualization(upper_solution, lower_solution, params)
% 绘制解的可视化
% 输入: upper_solution - 上层最优解
% lower_solution - 下层最优解
% params - 问题参数
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
% 创建图形
figure('Position', [100, 100, 1400, 600]);
% 子图1:设施决策
subplot(2,2,1);
bar(upper_solution, 'FaceColor', [0.2, 0.6, 0.8]);
hold on;
plot(1:n_facilities, params.capacity / max(params.capacity), 'r--', 'LineWidth', 2);
xlabel('设施编号');
ylabel('建设水平/标准化容量');
title('设施建设决策');
legend('建设水平', '标准化容量', 'Location', 'best');
grid on;
% 子图2:运输网络
subplot(2,2,2);
% 生成设施和客户位置
facility_pos = rand(n_facilities, 2) * 10;
customer_pos = rand(n_customers, 2) * 10;
% 绘制设施
scatter(facility_pos(:,1), facility_pos(:,2), upper_solution*500 + 100, ...
'b', 'filled', 'DisplayName', '设施');
hold on;
% 绘制客户
scatter(customer_pos(:,1), customer_pos(:,2), 100, 'r', 'filled', 'DisplayName', '客户');
% 绘制运输流
idx = 1;
max_flow = 0;
flows = zeros(n_facilities, n_customers);
for f = 1:n_facilities
for c = 1:n_customers
flow = 0;
for p = 1:n_products
flow = flow + lower_solution(idx);
idx = idx + 1;
end
flows(f, c) = flow;
max_flow = max(max_flow, flow);
end
end
% 绘制连接线
for f = 1:n_facilities
for c = 1:n_customers
if flows(f, c) > 0
line_width = 1 + 3 * flows(f, c) / max_flow;
plot([facility_pos(f,1), customer_pos(c,1)], ...
[facility_pos(f,2), customer_pos(c,2)], ...
'k-', 'LineWidth', line_width, 'Color', [0, 0.5, 0, 0.5]);
end
end
end
xlabel('X坐标');
ylabel('Y坐标');
title('运输网络可视化');
legend('设施', '客户');
axis equal;
grid on;
% 子图3:产品流分析
subplot(2,2,3);
product_flow = zeros(n_products, 1);
idx = 1;
for p = 1:n_products
for f = 1:n_facilities
for c = 1:n_customers
product_flow(p) = product_flow(p) + lower_solution(idx);
idx = idx + 1;
end
end
end
bar(product_flow, 'FaceColor', [0.8, 0.4, 0.2]);
xlabel('产品类型');
ylabel('总运输量');
title('各产品运输总量');
grid on;
% 子图4:成本构成
subplot(2,2,4);
investment_cost = sum(params.fixed_cost .* upper_solution);
production_cost = 0;
transport_cost = 0;
idx = 1;
for p = 1:n_products
for f = 1:n_facilities
for c = 1:n_customers
qty = lower_solution(idx);
production_cost = production_cost + qty * params.production_cost(p, f);
transport_cost = transport_cost + qty * params.transport_cost(f, c, p);
idx = idx + 1;
end
end
end
costs = [investment_cost, production_cost, transport_cost];
labels = {'投资成本', '生产成本', '运输成本'};
pie(costs, labels);
title('成本构成分析');
% 保存图片
saveas(gcf, 'solution_visualization.png');
end
2.9 灵敏度分析
matlab
function perform_sensitivity_analysis(best_upper, best_lower, ga_params, params)
% 执行灵敏度分析
% 输入: best_upper - 最优上层解
% best_lower - 最优下层解
% ga_params - 遗传算法参数
% params - 问题参数
fprintf('\n=== 灵敏度分析 ===\n');
% 1. 投资成本变化
fprintf('\n1. 投资成本灵敏度分析:\n');
cost_variations = 0.7:0.1:1.3; % 70%到130%的变化
cost_results = zeros(length(cost_variations), 1);
for i = 1:length(cost_variations)
factor = cost_variations(i);
temp_params = params;
temp_params.fixed_cost = params.fixed_cost * factor;
% 重新计算目标函数
fitness = evaluate_upper_objective(best_upper, best_lower, temp_params);
cost_results(i) = fitness;
fprintf(' 投资成本变化%.0f%%: 总成本 = $%.2f (变化%.2f%%)\n', ...
(factor-1)*100, fitness, (fitness-cost_results(4))/cost_results(4)*100);
end
% 2. 需求变化
fprintf('\n2. 需求变化灵敏度分析:\n');
demand_variations = 0.8:0.1:1.2;
demand_results = zeros(length(demand_variations), 1);
for i = 1:length(demand_variations)
factor = demand_variations(i);
temp_params = params;
temp_params.demand = params.demand * factor;
% 需要重新求解下层问题
[temp_lower, ~] = solve_lower_problem(best_upper, ga_params, temp_params);
fitness = evaluate_upper_objective(best_upper, temp_lower, temp_params);
demand_results(i) = fitness;
fprintf(' 需求变化%.0f%%: 总成本 = $%.2f (变化%.2f%%)\n', ...
(factor-1)*100, fitness, (fitness-demand_results(3))/demand_results(3)*100);
end
% 3. 运输成本变化
fprintf('\n3. 运输成本灵敏度分析:\n');
trans_variations = 0.8:0.1:1.2;
trans_results = zeros(length(trans_variations), 1);
for i = 1:length(trans_variations)
factor = trans_variations(i);
temp_params = params;
temp_params.transport_cost = params.transport_cost * factor;
% 需要重新求解下层问题
[temp_lower, ~] = solve_lower_problem(best_upper, ga_params, temp_params);
fitness = evaluate_upper_objective(best_upper, temp_lower, temp_params);
trans_results(i) = fitness;
fprintf(' 运输成本变化%.0f%%: 总成本 = $%.2f (变化%.2f%%)\n', ...
(factor-1)*100, fitness, (fitness-trans_results(3))/trans_results(3)*100);
end
% 绘制灵敏度分析图
figure('Position', [100, 100, 1200, 400]);
% 子图1:投资成本灵敏度
subplot(1,3,1);
plot((cost_variations-1)*100, (cost_results-cost_results(4))/cost_results(4)*100, ...
'b-o', 'LineWidth', 2, 'MarkerFaceColor', 'b');
grid on;
xlabel('投资成本变化 (%)');
ylabel('总成本变化 (%)');
title('投资成本灵敏度');
xlim([-30, 30]);
% 子图2:需求灵敏度
subplot(1,3,2);
plot((demand_variations-1)*100, (demand_results-demand_results(3))/demand_results(3)*100, ...
'r-o', 'LineWidth', 2, 'MarkerFaceColor', 'r');
grid on;
xlabel('需求变化 (%)');
ylabel('总成本变化 (%)');
title('需求灵敏度');
xlim([-20, 20]);
% 子图3:运输成本灵敏度
subplot(1,3,3);
plot((trans_variations-1)*100, (trans_results-trans_results(3))/trans_results(3)*100, ...
'g-o', 'LineWidth', 2, 'MarkerFaceColor', 'g');
grid on;
xlabel('运输成本变化 (%)');
ylabel('总成本变化 (%)');
title('运输成本灵敏度');
xlim([-20, 20]);
% 保存图片
saveas(gcf, 'sensitivity_analysis.png');
end
参考代码 用遗传算法求解双层规划模型得到最优解 www.youwenfan.com/contentcsu/54783.html
三、算法改进
3.1 加速策略
matlab
function [lower_solution, lower_obj] = fast_lower_solution(upper_solution, params)
% 快速下层求解(使用线性规划近似)
% 输入: upper_solution - 上层决策变量
% params - 问题参数
% 输出: lower_solution - 下层近似解
% lower_obj - 下层目标值
n_facilities = length(upper_solution);
n_customers = size(params.demand, 2);
n_products = size(params.demand, 1);
% 构建线性规划
f = []; % 目标系数
A = []; % 约束矩阵
b = []; % 约束右端
Aeq = []; % 等式约束矩阵
beq = []; % 等式约束右端
lb = []; % 下界
ub = []; % 上界
% 使用MATLAB优化工具箱求解
% 如果不可用,则使用启发式方法
% 启发式:按单位成本排序分配
lower_solution = zeros(n_facilities * n_customers * n_products, 1);
idx = 1;
for p = 1:n_products
for c = 1:n_customers
demand = params.demand(p, c);
% 按单位成本排序设施
unit_costs = zeros(n_facilities, 1);
for f = 1:n_facilities
unit_costs(f) = params.transport_cost(f, c, p) + params.production_cost(p, f);
end
[~, sorted_idx] = sort(unit_costs);
% 按成本从低到高分配
remaining_demand = demand;
for f_idx = 1:n_facilities
f = sorted_idx(f_idx);
if remaining_demand <= 0
break;
end
% 计算可分配量
capacity = upper_solution(f) * params.capacity(f);
allocated = min(remaining_demand, capacity * 0.3); % 假设比例分配
lower_solution(idx) = allocated;
remaining_demand = remaining_demand - allocated;
idx = idx + 1;
end
% 调整索引
idx = idx + (n_facilities - f_idx);
end
end
lower_obj = evaluate_lower_objective(lower_solution, upper_solution, params);
end
四、应用示例
4.1 供应链网络设计
matlab
% 供应链双层规划示例
% 上层:设施选址决策
% 下层:库存-运输联合优化
% 初始化参数
n_warehouses = 4;
n_retailers = 8;
n_periods = 12;
% 上层决策变量:是否建设仓库 [0-1]
% 下层决策变量:库存水平、运输量
% 调用双层遗传算法
[best_location, best_operation, best_cost] = bilevel_supply_chain_optimization(...
n_warehouses, n_retailers, n_periods);
五、总结
这个双层遗传算法实现具有以下特点:
完整框架 :包含上层和下层优化的完整嵌套结构
约束处理 :包含惩罚函数和修复策略处理双层约束
性能评估 :全面的收敛分析和灵敏度分析
可视化 :多种图形展示优化过程和结果
实用性强:针对实际问题(设施选址-运输优化)
算法优势:
- 嵌套优化结构清晰
- 自适应约束处理
- 多种遗传算子可选
- 并行计算潜力大
- 结果解释性强
应用场景:
- 供应链网络设计
- 交通网络规划
- 能源系统优化
- 定价-库存联合决策
- 资源分配问题