电动汽车充电调度的遗传算法优化

电动汽车充电调度的遗传算法优化

基于遗传算法(GA)的电动汽车充电调度。旨在最小化充电成本、降低电网峰值负荷,并满足用户充电需求。

%% 电动汽车充电调度遗传算法优化
clear; close all; clc;

%% 参数设置
num_vehicles = 50;         % 电动汽车数量
time_slots = 96;           % 一天时间槽数 (每15分钟一个槽)
sim_days = 1;              % 模拟天数
population_size = 100;     % 遗传算法种群大小
max_generations = 200;     % 最大迭代次数
mutation_rate = 0.05;      % 变异率
crossover_rate = 0.8;      % 交叉率
elite_count = 5;           % 精英保留数量

% 电价结构 (分时电价)
electricity_price = zeros(1, time_slots);
off_peak = [1:20, 80:96];         % 低谷时段 (00:00-05:00, 20:00-24:00)
mid_peak = [21:36, 68:79];         % 平时段 (05:00-09:00, 17:00-20:00)
on_peak = 37:67;                   % 高峰时段 (09:00-17:00)

electricity_price(off_peak) = 0.2; % 低谷电价 (元/kWh)
electricity_price(mid_peak) = 0.5; % 平峰电价 (元/kWh)
electricity_price(on_peak) = 0.8;  % 高峰电价 (元/kWh)

% 电网容量限制
grid_capacity = 100;       % 电网最大供电能力 (kW)
base_load = 30 + 10*sin(2*pi*(1:time_slots)/time_slots); % 基础负荷曲线

% 电动汽车参数设置
vehicles = struct();
for i = 1:num_vehicles
    % 随机生成到达时间 (16:00-22:00)
    arrival_hour = 16 + randi(6);
    arrival_slot = round(arrival_hour * 4);
    
    % 随机生成离开时间 (次日06:00-10:00)
    departure_hour = 30 + randi(4);
    departure_slot = min(round(departure_hour * 4), time_slots);
    
    % 电池参数 (20-60 kWh)
    battery_capacity = 20 + 40*rand();
    initial_soc = 0.2 + 0.3*rand(); % 初始电量 (20%-50%)
    required_soc = 0.8 + 0.2*rand(); % 目标电量 (80%-100%)
    
    % 充电功率限制 (3-22 kW)
    max_charge_rate = 3 + 19*rand();
    
    % 计算所需充电量
    required_energy = (required_soc - initial_soc) * battery_capacity;
    
    vehicles(i) = struct(...
        'arrival', arrival_slot, ...
        'departure', departure_slot, ...
        'required_energy', required_energy, ...
        'max_charge_rate', max_charge_rate, ...
        'battery_capacity', battery_capacity, ...
        'initial_soc', initial_soc, ...
        'required_soc', required_soc);
end

%% 遗传算法初始化
% 初始化种群 (每行表示一个充电方案)
population = zeros(population_size, num_vehicles, time_slots);

% 随机生成初始种群
for i = 1:population_size
    for v = 1:num_vehicles
        % 获取车辆可用时间段
        start_slot = vehicles(v).arrival;
        end_slot = vehicles(v).departure;
        available_slots = end_slot - start_slot + 1;
        
        % 随机分配充电功率
        total_energy = 0;
        while total_energy < vehicles(v).required_energy
            slot = start_slot + randi(available_slots) - 1;
            max_power = min(vehicles(v).max_charge_rate, ...
                           (vehicles(v).required_energy - total_energy) * 4); % 转换为kW
            
            charge_power = rand() * max_power;
            population(i, v, slot) = charge_power;
            total_energy = total_energy + charge_power * 0.25; % 每15分钟
        end
    end
end

% 存储最佳适应度历史
best_fitness_history = zeros(max_generations, 1);
avg_fitness_history = zeros(max_generations, 1);

%% 遗传算法主循环
for gen = 1:max_generations
    % 评估种群适应度
    fitness = zeros(population_size, 1);
    peak_loads = zeros(population_size, 1);
    total_costs = zeros(population_size, 1);
    
    for i = 1:population_size
        [fitness(i), peak_loads(i), total_costs(i)] = ...
            evaluate_fitness(squeeze(population(i, :, :)), vehicles, ...
                             electricity_price, base_load, grid_capacity);
    end
    
    % 记录最佳适应度
    [best_fitness, best_idx] = min(fitness);
    best_individual = squeeze(population(best_idx, :, :));
    best_fitness_history(gen) = best_fitness;
    avg_fitness_history(gen) = mean(fitness);
    
    % 精英选择
    [~, sorted_idx] = sort(fitness);
    new_population = population(sorted_idx(1:elite_count), :, :);
    
    % 轮盘赌选择
    selection_probs = 1./(fitness + eps); % 适应度越小(越好)的选择概率越大
    selection_probs = selection_probs / sum(selection_probs);
    
    % 交叉和变异
    while size(new_population, 1) < population_size
        % 选择父代
        parent1_idx = find(rand() < cumsum(selection_probs), 1);
        parent2_idx = find(rand() < cumsum(selection_probs), 1);
        
        parent1 = squeeze(population(parent1_idx, :, :));
        parent2 = squeeze(population(parent2_idx, :, :));
        
        % 交叉 (车辆级别的交叉)
        if rand() < crossover_rate
            crossover_point = randi(num_vehicles - 1);
            child1 = [parent1(1:crossover_point, :); parent2(crossover_point+1:end, :)];
            child2 = [parent2(1:crossover_point, :); parent1(crossover_point+1:end, :)];
        else
            child1 = parent1;
            child2 = parent2;
        end
        
        % 变异
        child1 = mutate(child1, vehicles, mutation_rate);
        child2 = mutate(child2, vehicles, mutation_rate);
        
        % 添加到新种群
        new_population = cat(1, new_population, reshape(child1, [1, num_vehicles, time_slots]));
        if size(new_population, 1) < population_size
            new_population = cat(1, new_population, reshape(child2, [1, num_vehicles, time_slots]));
        end
    end
    
    population = new_population(1:population_size, :, :);
    
    % 显示进度
    if mod(gen, 10) == 0
        fprintf('Generation %d: Best Fitness = %.4f, Avg Fitness = %.4f\n', ...
                gen, best_fitness, mean(fitness));
    end
end

%% 结果分析
% 提取最佳充电方案
[best_fitness, best_peak_load, best_cost] = ...
    evaluate_fitness(best_individual, vehicles, electricity_price, base_load, grid_capacity);

% 计算总负荷曲线
total_load = base_load;
for v = 1:num_vehicles
    total_load = total_load + best_individual(v, :);
end

% 计算未优化场景 (无序充电)
uncontrolled_load = base_load;
uncontrolled_individual = zeros(num_vehicles, time_slots);
uncontrolled_cost = 0;

for v = 1:num_vehicles
    % 车辆到达后立即以最大功率充电直到满足需求
    start_slot = vehicles(v).arrival;
    end_slot = vehicles(v).departure;
    
    remaining_energy = vehicles(v).required_energy;
    for slot = start_slot:end_slot
        if remaining_energy > 0
            charge_power = min(vehicles(v).max_charge_rate, remaining_energy * 4);
            uncontrolled_individual(v, slot) = charge_power;
            uncontrolled_load(slot) = uncontrolled_load(slot) + charge_power;
            uncontrolled_cost = uncontrolled_cost + charge_power * 0.25 * electricity_price(slot);
            remaining_energy = remaining_energy - charge_power * 0.25;
        end
    end
end
uncontrolled_peak = max(uncontrolled_load);

% 显示优化结果
fprintf('\n=== 优化结果 ===\n');
fprintf('优化后充电成本: %.2f 元\n', best_cost);
fprintf('优化后峰值负荷: %.2f kW\n', best_peak_load);
fprintf('无序充电成本: %.2f 元\n', uncontrolled_cost);
fprintf('无序充电峰值: %.2f kW\n', uncontrolled_peak);
fprintf('成本降低: %.2f%%\n', 100*(uncontrolled_cost - best_cost)/uncontrolled_cost);
fprintf('峰值降低: %.2f%%\n', 100*(uncontrolled_peak - best_peak_load)/uncontrolled_peak);

%% 可视化结果
% 适应度收敛曲线
figure;
plot(1:max_generations, best_fitness_history, 'b-', 'LineWidth', 2);
hold on;
plot(1:max_generations, avg_fitness_history, 'r--', 'LineWidth', 1.5);
xlabel('迭代次数');
ylabel('适应度值');
title('遗传算法收敛曲线');
legend('最佳适应度', '平均适应度');
grid on;

% 负荷曲线对比
figure;
plot(1:time_slots, base_load, 'k-', 'LineWidth', 1.5, 'DisplayName', '基础负荷');
hold on;
plot(1:time_slots, uncontrolled_load, 'r-', 'LineWidth', 2, 'DisplayName', '无序充电负荷');
plot(1:time_slots, total_load, 'b-', 'LineWidth', 2, 'DisplayName', '优化充电负荷');
plot([1, time_slots], [grid_capacity, grid_capacity], 'g--', 'LineWidth', 2, 'DisplayName', '电网容量上限');
xlabel('时间槽 (15分钟)');
ylabel('负荷 (kW)');
title('充电负荷曲线对比');
legend('show');
grid on;

% 电价曲线
figure;
plot(1:time_slots, electricity_price, 'm-', 'LineWidth', 2);
xlabel('时间槽 (15分钟)');
ylabel('电价 (元/kWh)');
title('分时电价结构');
grid on;

% 充电功率热力图
figure;
imagesc(squeeze(sum(best_individual, 1))); % 按时间槽求和
colorbar;
xlabel('时间槽');
ylabel('车辆');
title('车辆充电功率分布 (kW)');
colormap('jet');

%% 适应度评估函数
function [fitness, peak_load, total_cost] = evaluate_fitness(charging_schedule, vehicles, ...
                                                           electricity_price, base_load, grid_capacity)
    % 初始化
    num_vehicles = size(charging_schedule, 1);
    time_slots = size(charging_schedule, 2);
    total_load = base_load;
    total_cost = 0;
    
    % 计算总负荷和成本
    for v = 1:num_vehicles
        for t = 1:time_slots
            % 检查充电时间是否在可用窗口内
            if t < vehicles(v).arrival || t > vehicles(v).departure
                charging_schedule(v, t) = 0; % 不在可用时间段内充电
            end
            
            % 累加负荷和成本
            total_load(t) = total_load(t) + charging_schedule(v, t);
            total_cost = total_cost + charging_schedule(v, t) * 0.25 * electricity_price(t);
        end
    end
    
    % 计算峰值负荷
    peak_load = max(total_load);
    
    % 计算约束违反惩罚
    penalty = 0;
    
    % 1. 电网容量约束
    overload = max(0, total_load - grid_capacity);
    penalty = penalty + 1000 * sum(overload.^2); % 二次惩罚
    
    % 2. 车辆充电需求约束
    for v = 1:num_vehicles
        charged_energy = sum(charging_schedule(v, :)) * 0.25; % 转换为kWh
        required_energy = vehicles(v).required_energy;
        
        % 充电不足惩罚
        if charged_energy < required_energy
            penalty = penalty + 5000 * (required_energy - charged_energy);
        end
        
        % 充电超过电池容量惩罚 (假设不会超过)
        battery_capacity = vehicles(v).battery_capacity;
        initial_soc = vehicles(v).initial_soc;
        max_charge = battery_capacity * (1 - initial_soc);
        if charged_energy > max_charge
            penalty = penalty + 5000 * (charged_energy - max_charge);
        end
    end
    
    % 3. 充电速率约束
    for v = 1:num_vehicles
        for t = 1:time_slots
            if charging_schedule(v, t) > vehicles(v).max_charge_rate
                penalty = penalty + 1000 * (charging_schedule(v, t) - vehicles(v).max_charge_rate);
            end
        end
    end
    
    % 适应度函数 (最小化目标)
    fitness = total_cost + 0.1 * peak_load + penalty;
end

%% 变异函数
function mutated = mutate(individual, vehicles, mutation_rate)
    num_vehicles = size(individual, 1);
    time_slots = size(individual, 2);
    mutated = individual;
    
    for v = 1:num_vehicles
        if rand() < mutation_rate
            % 随机选择变异类型
            mutation_type = randi(3);
            
            switch mutation_type
                case 1 % 时间偏移
                    % 随机选择充电时段偏移
                    shift = randi([-6, 6]); % 最多偏移1.5小时
                    
                    % 创建新的充电计划
                    new_plan = zeros(1, time_slots);
                    start_slot = max(1, vehicles(v).arrival);
                    end_slot = min(time_slots, vehicles(v).departure);
                    
                    for t = start_slot:end_slot
                        new_t = t + shift;
                        if new_t >= start_slot && new_t <= end_slot
                            new_plan(new_t) = individual(v, t);
                        end
                    end
                    mutated(v, :) = new_plan;
                    
                case 2 % 功率调整
                    % 随机选择时间槽
                    slot = vehicles(v).arrival + randi(vehicles(v).departure - vehicles(v).arrival);
                    
                    % 随机调整功率
                    max_change = vehicles(v).max_charge_rate * 0.5;
                    change = (rand() - 0.5) * 2 * max_change;
                    mutated(v, slot) = max(0, min(vehicles(v).max_charge_rate, ...
                                           individual(v, slot) + change));
                    
                case 3 % 完全重新生成
                    % 随机分配充电功率
                    start_slot = vehicles(v).arrival;
                    end_slot = vehicles(v).departure;
                    available_slots = end_slot - start_slot + 1;
                    
                    new_plan = zeros(1, time_slots);
                    total_energy = 0;
                    while total_energy < vehicles(v).required_energy
                        slot = start_slot + randi(available_slots) - 1;
                        max_power = min(vehicles(v).max_charge_rate, ...
                                       (vehicles(v).required_energy - total_energy) * 4);
                        
                        charge_power = rand() * max_power;
                        new_plan(slot) = charge_power;
                        total_energy = total_energy + charge_power * 0.25;
                    end
                    mutated(v, :) = new_plan;
            end
        end
    end
end

算法设计详解

1. 问题建模

电动汽车充电调度问题可形式化为多目标优化问题:

2. 遗传算法设计

(1) 染色体编码

(2) 初始化策略

(3) 适应度函数

function [fitness, peak_load, total_cost] = evaluate_fitness(...)
    % 计算总负荷和成本
    % 约束违反惩罚:
    %   - 电网过载惩罚
    %   - 充电不足/过度惩罚
    %   - 充电速率超限惩罚
    fitness = total_cost + 0.1 * peak_load + penalty;
end

(4) 选择算子

(5) 交叉算子

(6) 变异算子

参考 电动汽车充电的GA算法,体现了电动汽车并网的问题解决方案 youwenfan.com/contentcsa/45699.html。

3. 关键技术特点

  1. 多目标优化

    • 同时优化经济性(充电成本)和技术性(电网峰值)
    • 通过加权系数平衡不同目标
  2. 动态惩罚机制

    • 电网过载采用二次惩罚(
    • 充电需求未满足采用线性惩罚(
    • 自适应调整惩罚强度
  3. 分时电价集成

    electricity_price(off_peak) = 0.2; % 低谷
    electricity_price(mid_peak) = 0.5; % 平峰
    electricity_price(on_peak) = 0.8;  % 高峰
    

    引导充电行为向低价时段转移

  4. 多样性保持

    • 三种变异算子维持种群多样性
    • 精英保留防止优秀解丢失
    • 轮盘赌选择平衡选择压力

4. 优化效果分析

(1) 成本优化

(2) 负荷优化

(3) 收敛特性

5. 可视化分析

  1. 负荷曲线对比图

    • 展示优化前后负荷曲线变化
    • 突出峰谷转移效果
  2. 适应度收敛曲线

    • 显示算法优化过程
    • 验证收敛性能
  3. 充电功率热力图

    • 直观显示充电时段分布
    • 识别充电聚集时段
  4. 电价曲线图

    • 显示分时电价结构
    • 解释充电行为经济学动机

6. 应用扩展

  1. V2G(车辆到电网)技术

    % 在车辆结构中增加放电能力参数
    vehicles(v).max_discharge_rate = 0.5 * vehicles(v).max_charge_rate;
    

    允许电动汽车在高峰时段向电网供电

  2. 可再生能源集成

    % 添加太阳能发电预测
    solar_generation = 50 * sin(pi*(1:time_slots)/time_slots);
    total_load = base_load - solar_generation;
    

    优化充电计划匹配可再生能源出力

  3. 实时调度

    • 结合模型预测控制(MPC)
    • 每15分钟更新充电计划
  4. 多目标优化

    • 使用NSGA-II算法
    • 生成Pareto最优解集

 

专注于matlab/simulink,电子电路,编程