在电力系统面临极端天气事件日益频繁的今天,如何提升配电网的韧性成为学术界和工业界共同关注的焦点。移动式应急电源(MPS)的预部署策略,作为提升配电网韧性的有效手段,正在获得越来越多的应用。本文将带领读者从零开始,完整实现一篇顶刊论文中提出的两阶段鲁棒优化模型,解决MPS预部署中的关键问题。
实现这一复杂优化模型需要以下工具协同工作:
安装完成后,建议运行以下代码验证环境配置:
matlab复制% 验证YALMIP安装
if exist('yalmiptest','file')
yalmiptest
else
error('YALMIP未正确安装');
end
% 验证Gurobi安装
try
gurobi('version');
catch
error('Gurobi未正确配置');
end
论文中使用了IEEE 33节点和123节点系统作为测试案例。这些数据可以直接从MATPOWER获取:
matlab复制% 加载IEEE 33节点系统数据
case33 = loadcase('case33bw');
% 加载IEEE 123节点系统数据
case123 = loadcase('case123');
对于MATPOWER未包含的额外参数(如负荷权重、MPS容量等),需要根据论文描述进行补充:
matlab复制% 补充负荷权重参数
case33.bus(:,11) = ones(33,1); % 默认权重为1
case33.bus([3,7,12],11) = [1.5, 2.0, 1.8]; % 关键节点权重增加
% MPS参数设置
case33.mps = struct(...
'num_ev', 3, ... % 电动汽车数量
'num_mess', 2, ... % 移动储能系统数量
'num_meg', 1, ... % 移动发电机数量
'candidate_nodes', [5,12,18,22,25,29,33]... % 候选节点
);
第一阶段决策变量包括MPS的预部署位置和网络重构方案。在YALMIP中定义这些变量:
matlab复制% 定义二进制决策变量
y_ev = binvar(length(candidate_nodes), 1, 'full'); % EV部署决策
y_mess = binvar(length(candidate_nodes), 1, 'full'); % MESS部署决策
y_meg = binvar(length(candidate_nodes), 1, 'full'); % MEG部署决策
u = binvar(nl, 1, 'full'); % 支路开关状态(1=闭合,0=断开)
% 定义约束条件
Constraints = [];
% 每个MPS只能部署在一个节点
Constraints = [Constraints, sum(y_ev) == num_ev];
Constraints = [Constraints, sum(y_mess) == num_mess];
Constraints = [Constraints, sum(y_meg) == num_meg];
% 网络径向性约束
Constraints = [Constraints, sum(u) == nb-ns]; % 闭合支路数=节点数-子站数
第二阶段需要考虑最坏故障场景下的系统运行状态。这需要引入对偶变量来处理max-min问题:
matlab复制% 定义第二阶段变量
z = sdpvar(nb,1); % 节点电压平方
p = sdpvar(nb,1); % 节点有功注入
q = sdpvar(nb,1); % 节点无功注入
% 对偶变量
pi = sdpvar(nb,1); % 有功平衡对偶变量
phi = sdpvar(nb,1); % 无功平衡对偶变量
mu = sdpvar(nl,1); % 支路容量对偶变量
列与约束生成(C&CG)算法是解决两阶段鲁棒优化问题的有效方法。下面展示其MATLAB实现框架。
matlab复制function [MP, y, eta] = buildMasterProblem(case_data)
% 初始化变量
y_ev = binvar(length(case_data.mps.candidate_nodes), 1, 'full');
y_mess = binvar(length(case_data.mps.candidate_nodes), 1, 'full');
y_meg = binvar(length(case_data.mps.candidate_nodes), 1, 'full');
u = binvar(case_data.nl, 1, 'full');
eta = sdpvar(1,1);
% 目标函数:最大化eta(最坏场景下的最小负荷削减)
MP.Objective = -eta; % 转换为最小化问题
% 第一阶段约束
MP.Constraints = [];
MP.Constraints = [MP.Constraints, sum(y_ev) == case_data.mps.num_ev];
% 其他约束...
% 初始可行解约束
MP.Constraints = [MP.Constraints, eta <= 1000]; % 初始上界
end
子问题需要找到给定预部署方案下的最坏故障场景:
matlab复制function [worst_case, obj] = solveSubProblem(case_data, y_ev, y_mess, y_meg, u)
% 定义故障场景变量
xi = binvar(case_data.nl,1); % 支路故障状态(1=故障)
% 定义第二阶段变量和对偶变量...
% 构建子问题
SP = [];
SP.Objective = ...; % 最小化生存负荷
SP.Constraints = [...]; % 系统运行约束
% 求解
options = sdpsettings('solver','gurobi','verbose',0);
optimize(SP.Constraints, SP.Objective, options);
% 返回结果
worst_case.xi = value(xi);
obj = value(SP.Objective);
end
matlab复制function [y_opt, obj_hist] = solveCCG(case_data, max_iter, tol)
% 初始化
[MP, y, eta] = buildMasterProblem(case_data);
obj_hist = [];
LB = -inf;
UB = inf;
for k = 1:max_iter
% 求解主问题
optimize(MP.Constraints, MP.Objective);
LB = -value(MP.Objective);
y_current = value(y);
% 求解子问题
[worst_case, sub_obj] = solveSubProblem(case_data, y_current);
UB = min(UB, sub_obj);
% 记录目标值
obj_hist = [obj_hist; [LB, UB]];
% 收敛判断
if (UB - LB) < tol
break;
end
% 添加新约束到主问题
MP.Constraints = [MP.Constraints, ...
eta <= calculateNewConstraint(y, worst_case)];
end
y_opt = y_current;
end
原始模型中的非线性项需要进行适当处理:
matlab复制% 处理双线性项 λ_ij * u_ij
% 引入辅助变量和McCormick包络
for ij = 1:nl
w = sdpvar(1,1);
Constraints = [Constraints, w >= 0];
Constraints = [Constraints, w <= M*u(ij)];
Constraints = [Constraints, w <= lambda(ij)];
Constraints = [Constraints, w >= lambda(ij) - M*(1-u(ij))];
% 在原始约束中用w替换λ_ij*u_ij
end
对于大规模系统,可以并行化C&CG的子问题求解:
matlab复制% 启用并行池
if isempty(gcp('nocreate'))
parpool('local',4); % 使用4个工作进程
end
% 并行求解多个场景
parfor scenario = 1:num_scenarios
[results(scenario)] = solveScenario(scenario_data{scenario});
end
清晰的展示有助于理解优化结果:
matlab复制function plotDeploymentResult(case_data, y_ev, y_mess, y_meg)
figure;
% 绘制网络拓扑
plot_case(case_data);
% 标记MPS部署位置
hold on;
ev_nodes = case_data.mps.candidate_nodes(logical(y_ev));
mess_nodes = case_data.mps.candidate_nodes(logical(y_mess));
meg_nodes = case_data.mps.candidate_nodes(logical(y_meg));
scatter(case_data.bus(ev_nodes,1), case_data.bus(ev_nodes,2), 100, 'r', 'filled');
scatter(case_data.bus(mess_nodes,1), case_data.bus(mess_nodes,2), 100, 'b', 'filled');
scatter(case_data.bus(meg_nodes,1), case_data.bus(meg_nodes,2), 100, 'g', 'filled');
legend('电网节点','EV部署','MESS部署','MEG部署');
title('MPS预部署方案');
end
| 错误类型 | 可能原因 | 解决方案 |
|---|---|---|
| 模型不可行 | 约束冲突 | 使用diagnostics检查不可行约束 |
| 求解时间过长 | 问题规模大 | 尝试线性化、增加割平面 |
| 结果不收敛 | 算法参数不当 | 调整容差、增加最大迭代次数 |
matlab复制options = sdpsettings('solver','gurobi',...
'gurobi.MIPGap',0.01,... % 设置MIP间隙容差
'gurobi.TimeLimit',3600,... % 时间限制
'gurobi.Presolve',2); % 积极预处理
在实现过程中,我发现最关键的环节是第二阶段子问题的对偶转换。正确的对偶化可以显著提高求解效率,而错误的转换则可能导致问题无法求解。经过多次试验,采用分段线性化技术处理非线性约束,可以在精度和效率之间取得良好平衡。