基于遗传算法的双层规划模型求解MATLAB实现

一、双层规划问题与遗传算法原理

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);

五、总结

这个双层遗传算法实现具有以下特点:

完整框架 :包含上层和下层优化的完整嵌套结构
约束处理 :包含惩罚函数和修复策略处理双层约束
性能评估 :全面的收敛分析和灵敏度分析
可视化 :多种图形展示优化过程和结果
实用性强:针对实际问题(设施选址-运输优化)

算法优势

  1. 嵌套优化结构清晰
  2. 自适应约束处理
  3. 多种遗传算子可选
  4. 并行计算潜力大
  5. 结果解释性强

应用场景

  • 供应链网络设计
  • 交通网络规划
  • 能源系统优化
  • 定价-库存联合决策
  • 资源分配问题
相关推荐
凯瑟琳.奥古斯特3 小时前
SQLAlchemy核心功能解析
开发语言·python·flask
卷Java3 小时前
GPTQ vs AWQ vs GGUF:模型量化工具横向测评
开发语言·windows·python
charlie1145141913 小时前
嵌入式C++工程实践第20篇:GPIO 输入模式内部电路 —— 芯片是如何“听“到外部信号的
开发语言·c++·stm32·单片机
aini_lovee3 小时前
多目标粒子群优化(MOPSO)双适应度函数MATLAB实现
人工智能·算法·matlab
yong99903 小时前
图像融合与拼接:完整MATLAB工具箱
算法·计算机视觉·matlab
xinhuanjieyi4 小时前
极语言让ai学习的方法
开发语言·学习
xiaogutou11214 小时前
2026年历史课件PPT模板选购指南:教师备课效率与精度的平衡方案
开发语言·c#
StockTV4 小时前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python
chaofan9804 小时前
GPT-5.5 领衔 Image 2.0:像素级控制时代,AI 绘图告别开盲盒
开发语言·人工智能·python·gpt·自动化·api