电动汽车充电站选址优化模型,采用遗传算法求解。该问题综合考虑了建设成本、用户充电便利性、电网负荷等多重因素。
一、 问题数学模型
1.1 问题描述
在给定区域内,从 MMM 个候选站点中选择 NNN 个建设充电站,使得:
- 总建设成本最小
- 用户充电总距离最小
- 电网负荷均衡性最好
1.2 数学模型
决策变量 :
xj={1在候选点j建设充电站0否则x_j = \begin{cases} 1 & \text{在候选点} j \text{建设充电站} \\ 0 & \text{否则} \end{cases}xj={10在候选点j建设充电站否则
目标函数(多目标优化) :
minF=w1⋅f1+w2⋅f2+w3⋅f3\min F = w_1 \cdot f_1 + w_2 \cdot f_2 + w_3 \cdot f_3minF=w1⋅f1+w2⋅f2+w3⋅f3
其中:
- 建设成本 :f1=∑j=1Mcj⋅xjf_1 = \sum_{j=1}^{M} c_j \cdot x_jf1=∑j=1Mcj⋅xj
- 用户充电距离 :f2=∑i=1Kminj∈Sdij⋅dif_2 = \sum_{i=1}^{K} \min_{j \in S} d_{ij} \cdot d_if2=∑i=1Kminj∈Sdij⋅di
- 负荷均衡度 :f3=1N∑j=1M(Lj−Lˉ)2f_3 = \sqrt{\frac{1}{N} \sum_{j=1}^{M} (L_j - \bar{L})^2}f3=N1∑j=1M(Lj−Lˉ)2
约束条件:
- 建设数量约束:∑j=1Mxj=N\sum_{j=1}^{M} x_j = N∑j=1Mxj=N
- 容量约束:∑i∈Ajdi≤Cj⋅xj,∀j\sum_{i \in A_j} d_i \leq C_j \cdot x_j, \quad \forall j∑i∈Ajdi≤Cj⋅xj,∀j
- 服务半径约束:dij≤Rmax,∀i,jd_{ij} \leq R_{\max}, \quad \forall i,jdij≤Rmax,∀i,j
二、 MATLAB代码
2.1 主程序:充电站选址优化
matlab
%% 基于遗传算法的电动汽车充电站选址优化
clear; clc; close all;
%% 1. 参数设置与数据生成
% 算法参数
pop_size = 100; % 种群规模
max_gen = 200; % 最大迭代次数
pc = 0.8; % 交叉概率
pm = 0.05; % 变异概率
elite_rate = 0.1; % 精英保留比例
% 问题参数
num_candidates = 50; % 候选站点数量
num_selected = 10; % 需要建设的站点数量
num_demand_points = 200; % 需求点数量
% 权重设置 (多目标权重)
w_cost = 0.4; % 建设成本权重
w_distance = 0.4; % 充电距离权重
w_balance = 0.2; % 负荷均衡权重
% 生成模拟数据
rng(42); % 设置随机种子确保可重复性
[candidate_coords, demand_coords, candidate_costs, demand_weights] = ...
generate_charging_station_data(num_candidates, num_demand_points);
% 计算距离矩阵
dist_matrix = pdist2(demand_coords, candidate_coords);
%% 2. 遗传算法初始化
% 初始化种群 (二进制编码)
population = init_population(pop_size, num_candidates, num_selected);
% 计算初始适应度
fitness = zeros(pop_size, 1);
for i = 1:pop_size
fitness(i) = calculate_fitness(population(i,:), candidate_costs, ...
demand_weights, dist_matrix, w_cost, w_distance, w_balance);
end
% 记录最优解
[best_fitness, best_idx] = min(fitness);
best_solution = population(best_idx, :);
fitness_history = zeros(max_gen, 1);
%% 3. 遗传算法主循环
fprintf('开始遗传算法优化...\n');
for gen = 1:max_gen
% 选择操作 (锦标赛选择)
parents = tournament_selection(population, fitness, pop_size);
% 交叉操作 (单点交叉)
offspring = crossover(parents, pc, num_selected);
% 变异操作 (位翻转变异)
offspring = mutation(offspring, pm, num_selected);
% 精英保留策略
[~, sorted_idx] = sort(fitness);
elite_count = round(elite_rate * pop_size);
elite_pop = population(sorted_idx(1:elite_count), :);
% 合并种群
new_population = [elite_pop; offspring(1:pop_size-elite_count, :)];
% 计算新种群适应度
new_fitness = zeros(size(new_population, 1), 1);
for i = 1:size(new_population, 1)
new_fitness(i) = calculate_fitness(new_population(i,:), candidate_costs, ...
demand_weights, dist_matrix, w_cost, w_distance, w_balance);
end
% 更新种群
population = new_population;
fitness = new_fitness;
% 更新最优解
[current_best, current_idx] = min(fitness);
if current_best < best_fitness
best_fitness = current_best;
best_solution = population(current_idx, :);
end
fitness_history(gen) = best_fitness;
% 显示进度
if mod(gen, 20) == 0
fprintf('第 %d 代,最优适应度: %.4f\n', gen, best_fitness);
end
end
%% 4. 结果分析与可视化
fprintf('\n========== 优化结果 ==========\n');
fprintf('最优适应度值: %.4f\n', best_fitness);
selected_sites = find(best_solution == 1);
fprintf('选中的充电站位置编号: %s\n', mat2str(selected_sites));
% 计算各项目标值
[total_cost, total_distance, balance_degree] = ...
evaluate_solution(best_solution, candidate_costs, demand_weights, dist_matrix);
fprintf('总建设成本: %.2f 万元\n', total_cost);
fprintf('用户总充电距离: %.2f km\n', total_distance);
fprintf('负荷均衡度: %.4f\n', balance_degree);
% 可视化结果
visualize_results(candidate_coords, demand_coords, best_solution, ...
demand_weights, dist_matrix);
% 绘制收敛曲线
figure('Name', '遗传算法收敛曲线', 'Color', 'w');
plot(1:max_gen, fitness_history, 'b-', 'LineWidth', 2);
xlabel('迭代次数');
ylabel('适应度值');
title('遗传算法收敛曲线');
grid on;
2.2 数据生成函数
matlab
function [candidate_coords, demand_coords, candidate_costs, demand_weights] = ...
generate_charging_station_data(num_candidates, num_demand_points)
% 生成候选站点坐标 (均匀分布)
candidate_coords = rand(num_candidates, 2) * 100;
% 生成需求点坐标 (聚类分布,模拟居民区)
demand_coords = zeros(num_demand_points, 2);
cluster_centers = [20, 20; 80, 20; 50, 80; 20, 80; 80, 80];
cluster_sizes = [0.3, 0.2, 0.25, 0.15, 0.1] * num_demand_points;
idx = 1;
for c = 1:length(cluster_sizes)
n_points = round(cluster_sizes(c));
for i = 1:n_points
if idx > num_demand_points
break;
end
demand_coords(idx, :) = cluster_centers(c, :) + randn(1,2)*10;
idx = idx + 1;
end
end
% 生成候选站点建设成本 (万元)
candidate_costs = 50 + 150 * rand(num_candidates, 1);
% 生成需求点权重 (充电需求强度)
demand_weights = 0.5 + 1.5 * rand(num_demand_points, 1);
end
2.3 适应度计算函数
matlab
function fitness = calculate_fitness(solution, candidate_costs, ...
demand_weights, dist_matrix, w_cost, w_distance, w_balance)
% 计算单个解的适应度值
% 1. 建设成本
total_cost = sum(candidate_costs(solution == 1));
% 2. 用户充电距离
selected_sites = find(solution == 1);
if isempty(selected_sites)
fitness = inf;
return;
end
% 为每个需求点分配最近的充电站
dist_to_selected = dist_matrix(:, selected_sites);
[min_dist, ~] = min(dist_to_selected, [], 2);
total_distance = sum(min_dist .* demand_weights);
% 3. 负荷均衡度
% 计算每个充电站的负荷
station_loads = zeros(length(selected_sites), 1);
for i = 1:length(selected_sites)
% 找到分配给该站点的需求点
[~, assigned_station] = min(dist_to_selected, [], 2);
station_idx = (assigned_station == i);
station_loads(i) = sum(demand_weights(station_idx));
end
if length(selected_sites) > 1
avg_load = mean(station_loads);
balance_degree = sqrt(sum((station_loads - avg_load).^2) / length(selected_sites));
else
balance_degree = 0;
end
% 4. 归一化处理
max_cost = sum(candidate_costs);
max_distance = sum(max(dist_matrix, [], 2) .* demand_weights);
norm_cost = total_cost / max_cost;
norm_distance = total_distance / max_distance;
norm_balance = balance_degree / (sum(demand_weights) / length(selected_sites));
% 5. 加权求和得到适应度
fitness = w_cost * norm_cost + w_distance * norm_distance + w_balance * norm_balance;
end
2.4 遗传算法操作函数
matlab
%% 初始化种群
function population = init_population(pop_size, num_candidates, num_selected)
population = zeros(pop_size, num_candidates);
for i = 1:pop_size
% 随机选择num_selected个位置设为1
idx = randperm(num_candidates, num_selected);
population(i, idx) = 1;
end
end
%% 锦标赛选择
function parents = tournament_selection(population, fitness, pop_size)
tournament_size = 3;
parents = zeros(size(population));
for i = 1:pop_size
% 随机选择tournament_size个个体
candidates = randperm(pop_size, tournament_size);
[~, best_idx] = min(fitness(candidates));
parents(i, :) = population(candidates(best_idx), :);
end
end
%% 单点交叉
function offspring = crossover(parents, pc, num_selected)
[pop_size, num_candidates] = size(parents);
offspring = parents;
for i = 1:2:pop_size-1
if rand() < pc
% 随机选择交叉点
crossover_point = randi([1, num_candidates-1]);
% 执行交叉
parent1 = parents(i, :);
parent2 = parents(i+1, :);
child1 = [parent1(1:crossover_point), parent2(crossover_point+1:end)];
child2 = [parent2(1:crossover_point), parent1(crossover_point+1:end)];
% 修复解:确保选中站点数量正确
child1 = repair_solution(child1, num_selected);
child2 = repair_solution(child2, num_selected);
offspring(i, :) = child1;
offspring(i+1, :) = child2;
end
end
end
%% 位翻转变异
function offspring = mutation(offspring, pm, num_selected)
[pop_size, num_candidates] = size(offspring);
for i = 1:pop_size
if rand() < pm
% 随机选择两个位置进行位翻转
idx1 = randi(num_candidates);
idx2 = randi(num_candidates);
while idx1 == idx2
idx2 = randi(num_candidates);
end
% 执行变异
offspring(i, idx1) = 1 - offspring(i, idx1);
offspring(i, idx2) = 1 - offspring(i, idx2);
% 修复解
offspring(i, :) = repair_solution(offspring(i, :), num_selected);
end
end
end
%% 修复解:确保选中站点数量正确
function solution = repair_solution(solution, num_selected)
current_selected = sum(solution);
if current_selected > num_selected
% 随机移除多余的站点
selected_idx = find(solution == 1);
remove_idx = randperm(length(selected_idx), current_selected - num_selected);
solution(selected_idx(remove_idx)) = 0;
elseif current_selected < num_selected
% 随机添加缺失的站点
unselected_idx = find(solution == 0);
add_idx = randperm(length(unselected_idx), num_selected - current_selected);
solution(unselected_idx(add_idx)) = 1;
end
end
2.5 结果评估与可视化
matlab
function [total_cost, total_distance, balance_degree] = ...
evaluate_solution(solution, candidate_costs, demand_weights, dist_matrix)
% 评估解的质量
selected_sites = find(solution == 1);
% 1. 建设成本
total_cost = sum(candidate_costs(selected_sites));
% 2. 用户充电距离
dist_to_selected = dist_matrix(:, selected_sites);
[min_dist, assigned_station] = min(dist_to_selected, [], 2);
total_distance = sum(min_dist .* demand_weights);
% 3. 负荷均衡度
station_loads = zeros(length(selected_sites), 1);
for i = 1:length(selected_sites)
station_idx = (assigned_station == i);
station_loads(i) = sum(demand_weights(station_idx));
end
if length(selected_sites) > 1
avg_load = mean(station_loads);
balance_degree = sqrt(sum((station_loads - avg_load).^2) / length(selected_sites));
else
balance_degree = 0;
end
end
function visualize_results(candidate_coords, demand_coords, solution, ...
demand_weights, dist_matrix)
% 可视化优化结果
figure('Name', '充电站选址优化结果', 'Color', 'w', 'Position', [100, 100, 1200, 500]);
% 子图1:站点分布
subplot(1, 2, 1);
hold on; grid on; axis equal;
% 绘制所有候选站点
scatter(candidate_coords(:,1), candidate_coords(:,2), 50, 'k', 'o', 'filled');
% 绘制选中的充电站
selected_sites = find(solution == 1);
scatter(candidate_coords(selected_sites,1), candidate_coords(selected_sites,2), ...
100, 'r', 's', 'filled', 'LineWidth', 2);
% 绘制需求点(大小表示需求强度)
demand_sizes = 20 + 80 * (demand_weights - min(demand_weights)) / ...
(max(demand_weights) - min(demand_weights));
scatter(demand_coords(:,1), demand_coords(:,2), demand_sizes, 'b', '^', 'filled', ...
'MarkerFaceAlpha', 0.3);
% 绘制服务关系
dist_to_selected = dist_matrix(:, selected_sites);
[~, assigned_station] = min(dist_to_selected, [], 2);
colors = lines(length(selected_sites));
for i = 1:length(selected_sites)
station_demands = find(assigned_station == i);
if ~isempty(station_demands)
for j = 1:min(20, length(station_demands)) % 只绘制部分连接线避免混乱
plot([candidate_coords(selected_sites(i),1), demand_coords(station_demands(j),1)], ...
[candidate_coords(selected_sites(i),2), demand_coords(station_demands(j),2)], ...
'Color', colors(i,:), 'LineWidth', 0.5, 'LineStyle', '--');
end
end
end
legend('候选站点', '选中站点', '需求点', 'Location', 'best');
title('充电站选址与需求点分配');
xlabel('X坐标 (km)'); ylabel('Y坐标 (km)');
% 子图2:负荷分布
subplot(1, 2, 2);
station_loads = zeros(length(selected_sites), 1);
for i = 1:length(selected_sites)
station_idx = (assigned_station == i);
station_loads(i) = sum(demand_weights(station_idx));
end
bar(1:length(selected_sites), station_loads, 'FaceColor', [0.2, 0.6, 0.8]);
hold on;
avg_load = mean(station_loads);
plot([0, length(selected_sites)+1], [avg_load, avg_load], 'r--', 'LineWidth', 2);
xlabel('充电站编号');
ylabel('负荷强度');
title('各充电站负荷分布');
legend('实际负荷', '平均负荷', 'Location', 'best');
grid on;
end
三、 工程实践建议与扩展方向
3.1 实际应用中的关键考虑
-
多目标优化改进:
- 使用 NSGA-II(非支配排序遗传算法)处理真正的多目标优化
- 采用 Pareto前沿 分析,提供多个非劣解供决策者选择
-
约束处理增强:
matlab% 添加电网容量约束 function penalty = check_grid_constraints(solution, grid_capacity) total_power = sum(solution .* station_power_demand); if total_power > grid_capacity penalty = 1000 * (total_power - grid_capacity); else penalty = 0; end end -
动态需求考虑:
- 考虑不同时段的充电需求变化
- 引入时间维度,优化充电站容量配置
3.2 算法性能优化
-
并行计算加速:
matlab% 使用parfor并行计算适应度 parfor i = 1:pop_size fitness(i) = calculate_fitness(population(i,:), ...); end -
局部搜索增强:
- 在遗传算法中嵌入 2-opt 或 变邻域搜索 提升局部搜索能力
- 采用 自适应参数调整:根据进化过程动态调整交叉和变异概率
3.3 实际数据接口
matlab
% 从实际GIS数据读取
function [coords, costs] = read_real_data(filename)
data = readtable(filename);
coords = [data.Longitude, data.Latitude];
costs = data.ConstructionCost;
% 坐标转换(如需要)
% coords = lla2utm(coords);
end
% 从电力系统数据读取负荷信息
function load_profile = read_load_profile(power_system_data)
% 处理实际负荷曲线
load_profile = power_system_data.Demand;
end
3.4 扩展为多类型充电站
matlab
% 考虑快充站和慢充站混合配置
classdef ChargingStation
properties
Type % 'fast' 或 'slow'
Power % 充电功率 (kW)
Cost % 建设成本
Capacity % 最大服务车辆数
end
end
% 在适应度函数中考虑不同类型
function fitness = calculate_fitness_multi_type(solution, stations, ...)
% solution: 三维矩阵 [位置 × 类型 × 数量]
% 计算混合类型充电站的综合适应度
end
参考代码 基于遗传算法的充电站选址优化求解方法实例 www.youwenfan.com/contentcsu/65103.html
四、 运行与调试建议
-
首次运行:
- 直接运行主程序,观察收敛曲线
- 调整权重参数
w_cost,w_distance,w_balance观察不同偏好下的选址方案
-
参数调优:
- 种群大小
pop_size: 50-200 - 迭代次数
max_gen: 100-500 - 交叉概率
pc: 0.7-0.9 - 变异概率
pm: 0.01-0.1
- 种群大小
-
结果验证:
- 多次运行验证算法稳定性
- 与穷举法(小规模问题)或商业求解器结果对比