1. 项目概述:两阶段鲁棒优化问题背景
电力系统调度中,风光出力和负荷需求的不确定性一直是影响决策可靠性的关键因素。传统随机规划方法需要精确的概率分布假设,而实际场景中往往难以获取足够数据支撑这种假设。这正是鲁棒优化(Robust Optimization)的用武之地——它只需要定义不确定参数的波动范围(即不确定集),就能在最坏情况下保证系统可行性。
我最近在Matlab中实现了一个典型的两阶段鲁棒优化模型,用于解决含风光负荷不确定性的电力调度问题。第一阶段确定机组启停、储能配置等"here-and-now"决策;第二阶段根据实时风光出力和负荷波动调整发电计划,属于"wait-and-see"决策。这种分离设计既保证了事前决策的稳健性,又保留了事中调整的灵活性。
2. 核心算法原理拆解
2.1 鲁棒优化建模要点
鲁棒优化的核心在于不确定集的构造。对于风光出力不确定性,通常采用多面体集合(Polyhedral Set)描述:
code复制U = {u | u = u0 + ξ, ||ξ||_∞ ≤ Γ}
其中u0为预测值,Γ为不确定性预算参数。Γ=0时退化为确定性优化,Γ越大系统越保守。
2.2 大M法实现线性化
当模型中存在非线性约束(如if-then逻辑)时,需要引入大M法进行线性化处理。例如对于约束:
code复制如果x>0,则y≤a
可转化为:
code复制y - a ≤ M(1-z)
x ≤ Mz
z ∈ {0,1}
其中M是足够大的常数,z为辅助二元变量。选择M值时需注意:
- 过小会导致约束失效
- 过大会引发数值不稳定
- 建议取比问题规模大2-3个数量级的数值
2.3 C&CG算法流程
列与约束生成(Column and Constraint Generation, C&CG)算法是求解两阶段问题的有效方法。其实施步骤为:
- 初始化:求解不考虑不确定性的主问题(MP),获得第一阶段决策x0
- 子问题(SP):固定x0,寻找使系统最恶劣的场景u*
- 判断:若SP目标值超过阈值,将u*对应的约束加入MP
- 迭代:重复求解MP和SP直至收敛
matlab复制while gap > tolerance
% 求解主问题
[x, obj_MP] = solve_MP();
% 求解子问题
[u, obj_SP] = solve_SP(x);
% 计算对偶间隙
gap = obj_SP - obj_MP;
% 添加恶劣场景约束
if gap > tolerance
add_constraint_to_MP(u);
end
end
3. Matlab实现关键代码解析
3.1 不确定集建模
matlab复制% 定义风光负荷波动范围
P_wind_uncertainty = 0.2; % 风电波动20%
P_pv_uncertainty = 0.15; % 光伏波动15%
Load_uncertainty = 0.1; % 负荷波动10%
% 构建多面体不确定集
Gamma = 3; % 不确定性预算
uncertainty_set = Polyhedron('lb', -[P_wind_uncertainty; P_pv_uncertainty; Load_uncertainty], ...
'ub', [P_wind_uncertainty; P_pv_uncertainty; Load_uncertainty]);
3.2 主问题建模(YALMIP)
matlab复制function [x, obj] = solve_MP(prev_extreme_scenarios)
% 定义决策变量
x = sdpvar(n_units, T, 'full'); % 机组启停状态
y = sdpvar(n_units, T, 'full'); % 机组出力
% 目标函数:最小化总成本
obj = sum(sum(C_fixed.*x + C_var.*y));
% 添加基本约束
constraints = [x >= 0, x <= 1, y >= 0];
% 添加历史恶劣场景约束
for i = 1:length(prev_extreme_scenarios)
u = prev_extreme_scenarios{i};
constraints = [constraints, feasibility_constraint(x, y, u)];
end
% 求解优化问题
ops = sdpsettings('solver','gurobi','verbose',0);
optimize(constraints, obj, ops);
end
3.3 子问题求解(对抗性场景生成)
matlab复制function [u_star, worst_cost] = solve_SP(x_fixed)
% 定义不确定变量
u = sdpvar(3, T, 'full'); % [风电波动, 光伏波动, 负荷波动]
% 定义第二阶段决策变量
y = sdpvar(n_units, T, 'full');
% 构建最恶劣场景目标
obj = sum(sum(C_var.*y)); % 最大化运行成本
% 不确定性集约束
constraints = [uncertainty_set.A * u(:) <= uncertainty_set.b];
% 系统可行性约束
constraints = [constraints, balance_constraint(x_fixed, y, u)];
% 求解双线性问题(可线性化处理)
ops = sdpsettings('solver','gurobi','verbose',0);
optimize(constraints, -obj, ops); % 注意目标取负
u_star = value(u);
worst_cost = value(obj);
end
4. 实战经验与调优技巧
4.1 算法加速策略
-
热启动(Warm Start):每次MP迭代使用前次解作为初始点
matlab复制ops.gurobi.WarmStart = 1; -
并行计算:利用Matlab并行工具箱加速多场景计算
matlab复制parfor i = 1:n_scenarios % 并行处理场景 end -
有效不等式:添加冗余约束缩小可行域
matlab复制constraints = [constraints, sum(x,2) >= min_up_time];
4.2 数值稳定性处理
-
大M值选择:通过问题规模自适应确定
matlab复制M = 1e3 * max(C_fixed(:)); -
正则化项:避免目标函数尺度差异过大
matlab复制obj = obj + 1e-6*norm(y,2); -
容差设置:适当放宽收敛条件
matlab复制ops.gurobi.OptimalityTol = 1e-4;
4.3 典型问题排查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 算法不收敛 | 不确定集过大 | 调整Γ参数 |
| 求解时间过长 | 整数变量过多 | 松弛部分整数约束 |
| 结果过于保守 | 大M值过大 | 重新校准M值 |
| 内存溢出 | 场景约束累积 | 定期清理非活跃约束 |
5. 扩展应用与进阶方向
5.1 数据驱动不确定集
利用历史数据构建更精确的不确定集:
matlab复制% 基于KDE估计概率密度
[pd_wind, xi] = ksdensity(wind_hist);
uncertainty_set = fit_confidence_region(xi, pd_wind, 0.95);
5.2 分布式鲁棒优化
结合分布信息的部分知识:
matlab复制% 定义Wasserstein模糊集
DRO_model = dropt(hist_data, 'Wasserstein', 0.1);
5.3 硬件加速实现
利用GPU加速矩阵运算:
matlab复制y = gpuArray(y);
constraints = gpuArray(constraints);
在实际项目中,我发现鲁棒优化对参数设置非常敏感。建议先用小规模测试案例校准Γ和M值,再扩展到全系统。对于100节点以上的电网,可以考虑采用Benders分解等分布式算法降低计算复杂度。
