1. 微电网最优调度问题概述
微电网作为分布式能源系统的重要实现形式,其运行优化一直是能源领域的研究热点。在实际运行中,如何协调各类发电单元(光伏、风电、柴油发电机等)与储能系统,以最小化运行成本同时满足负荷需求,是微电网调度中的核心问题。
这个Matlab例程展示了一个典型微电网系统的24小时最优调度方案,采用YALMIP建模工具和CPLEX商业求解器,以运行费用最小化为目标函数进行求解。这种组合在学术界和工业界都得到广泛应用,特别适合处理包含复杂约束的混合整数规划问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统建模与数学表达
2.1 微电网组成要素
典型的微电网系统包含以下组件:
- 可再生能源发电(光伏、风电)
- 传统发电机组(柴油发电机等)
- 储能系统(电池)
- 可中断负荷与必须负荷
- 与主网的连接点(可买卖电能)
在我们的模型中,假设系统包含:
- 1台柴油发电机(可控电源)
- 光伏发电系统(不可控但可预测)
- 电池储能系统(可充放电)
- 必须满足的基础负荷
- 可选的与主网交互
2.2 目标函数构建
以24小时总运行费用最小化为目标:
code复制min Σ [C_gen(t) + C_grid(t) + C_battery(t)] for t=1:24
其中:
- C_gen(t): 柴油发电机在t时段的运行成本
- C_grid(t): 与主网交互的成本(购电为正,售电为负)
- C_battery(t): 电池充放电损耗成本
柴油发电机成本通常采用二次函数表示:
code复制C_gen(t) = a·P_gen(t)^2 + b·P_gen(t) + c
其中a,b,c为成本系数,P_gen(t)为t时段发电功率。
2.3 约束条件设置
- 功率平衡约束:
code复制P_gen(t) + P_pv(t) + P_bat(t) + P_grid(t) = P_load(t) ∀t
- 发电机运行约束:
code复制P_gen_min ≤ P_gen(t) ≤ P_gen_max
|P_gen(t) - P_gen(t-1)| ≤ Ramp_max
- 电池储能约束:
code复制SOC_min ≤ SOC(t) ≤ SOC_max
SOC(t) = SOC(t-1) + [η_ch·P_ch(t) - P_dis(t)/η_dis]·Δt/E_max
P_bat(t) = P_dis(t) - P_ch(t)
0 ≤ P_ch(t) ≤ P_ch_max
0 ≤ P_dis(t) ≤ P_dis_max
- 电网交互约束:
code复制|P_grid(t)| ≤ P_grid_max
3. YALMIP建模实现
3.1 YALMIP安装与配置
YALMIP是MATLAB下的建模语言,安装步骤:
- 从官网下载最新YALMIP
- 将文件夹添加到MATLAB路径
- 安装求解器(如CPLEX、Gurobi等)
matlab复制addpath(genpath('yalmip_directory'));
yalmip('clear')
3.2 变量定义
定义24小时调度周期内的决策变量:
matlab复制% 发电机出力
P_gen = sdpvar(24,1);
% 电池充放电功率
P_ch = sdpvar(24,1); % 充电功率
P_dis = sdpvar(24,1); % 放电功率
% 电网交互功率
P_grid = sdpvar(24,1);
% 电池SOC状态
SOC = sdpvar(24,1);
3.3 目标函数实现
matlab复制% 发电机成本系数
a = 0.01; b = 10; c = 100;
% 电网电价(假设分时电价)
buy_price = [0.5*ones(1,7), 0.8*ones(1,8), 1.2*ones(1,6), 0.8*ones(1,3)];
sell_price = 0.3; % 售电价格
% 电池损耗成本系数
battery_cost = 0.05;
% 构建目标函数
total_cost = 0;
for t = 1:24
% 发电机成本
gen_cost = a*P_gen(t)^2 + b*P_gen(t) + c;
% 电网交互成本
if P_grid(t) >= 0
grid_cost = buy_price(t)*P_grid(t);
else
grid_cost = sell_price*P_grid(t);
end
% 电池损耗
bat_cost = battery_cost*(P_ch(t) + P_dis(t));
total_cost = total_cost + gen_cost + grid_cost + bat_cost;
end
% 设置目标
Objective = total_cost;
3.4 约束条件实现
matlab复制Constraints = [];
% 初始状态
Constraints = [Constraints, SOC(1) == 0.5]; % 初始SOC=50%
% 循环添加每小时约束
for t = 1:24
% 功率平衡
Constraints = [Constraints,
P_gen(t) + P_pv(t) + (P_dis(t) - P_ch(t)) + P_grid(t) == P_load(t)];
% 发电机约束
Constraints = [Constraints,
20 <= P_gen(t) <= 100, % 发电功率范围
-20 <= P_gen(t)-P_gen(max(1,t-1)) <= 20]; % 爬坡率
% 电池约束
if t > 1
Constraints = [Constraints,
SOC(t) == SOC(t-1) + (0.95*P_ch(t) - P_dis(t)/0.95)/100, % 假设E_max=100kWh
0.2 <= SOC(t) <= 0.9]; % SOC范围
end
Constraints = [Constraints,
0 <= P_ch(t) <= 30, % 最大充电功率
0 <= P_dis(t) <= 30, % 最大放电功率
P_ch(t)*P_dis(t) == 0]; % 不能同时充放电
end
4. CPLEX求解与结果分析
4.1 求解器配置
matlab复制% 设置CPLEX为求解器
options = sdpsettings('solver','cplex','verbose',1);
% 求解优化问题
sol = optimize(Constraints, Objective, options);
% 检查求解状态
if sol.problem == 0
disp('求解成功');
else
disp('求解失败');
yalmiperror(sol.problem)
end
4.2 结果提取与可视化
matlab复制% 提取优化结果
P_gen_opt = value(P_gen);
P_grid_opt = value(P_grid);
P_ch_opt = value(P_ch);
P_dis_opt = value(P_dis);
SOC_opt = value(SOC);
% 绘制调度结果
figure;
subplot(3,1,1);
plot(1:24, P_load, 'k-', 'LineWidth', 2); hold on;
plot(1:24, P_pv, 'g-');
plot(1:24, P_gen_opt, 'b-');
plot(1:24, P_dis_opt-P_ch_opt, 'm-');
plot(1:24, P_grid_opt, 'r-');
legend('负荷','光伏','发电机','电池','电网');
title('功率平衡');
subplot(3,1,2);
bar(1:24, [P_gen_opt, P_pv', max(0,P_grid_opt'), -min(0,P_grid_opt'), ...
P_dis_opt, -P_ch_opt], 'stacked');
legend('发电机','光伏','购电','售电','放电','充电');
title('电源组成');
subplot(3,1,3);
plot(1:24, SOC_opt, 'b-o');
ylabel('SOC');
title('电池状态');
4.3 成本分析
matlab复制% 计算各项成本
total_gen_cost = sum(a*P_gen_opt.^2 + b*P_gen_opt + c);
total_grid_cost = sum(buy_price'.*max(0,P_grid_opt) + sell_price*min(0,P_grid_opt));
total_battery_cost = battery_cost*sum(P_ch_opt + P_dis_opt);
% 显示成本构成
fprintf('总运行成本: %.2f 元\n', total_gen_cost+total_grid_cost+total_battery_cost);
fprintf('其中:\n');
fprintf(' 发电机成本: %.2f 元\n', total_gen_cost);
fprintf(' 电网交互成本: %.2f 元\n', total_grid_cost);
fprintf(' 电池损耗成本: %.2f 元\n', total_battery_cost);
5. 实际应用中的注意事项
5.1 预测数据准确性
微电网优化调度的效果很大程度上依赖于预测数据的准确性:
- 光伏出力预测:受天气影响大,建议采用多场景或鲁棒优化
- 负荷预测:考虑工作日/节假日模式,使用历史数据分析
- 电价预测:对于参与电力市场的微电网尤为重要
5.2 求解器选择建议
虽然CPLEX性能优异,但商业许可费用较高。替代方案包括:
- Gurobi:性能接近CPLEX,学术用户可免费申请license
- MOSEK:特别适合锥优化问题
- 开源方案:GLPK(适合小规模问题)、CBC(混合整数规划)
matlab复制% 切换求解器示例
options = sdpsettings('solver','gurobi','verbose',1);
5.3 模型扩展方向
- 考虑不确定性:使用随机规划或鲁棒优化处理预测误差
- 多时间尺度优化:日前调度+实时调整
- 需求响应:将可调节负荷纳入优化
- 多微电网协同:考虑微电网间的功率交换
5.4 常见问题排查
-
求解器报"infeasible":
- 检查约束条件是否自相矛盾
- 逐步放松约束,定位问题来源
- 使用
diagnostics功能分析不可行原因
-
求解时间过长:
- 尝试简化模型(如线性化目标函数)
- 调整求解器参数(如MIP gap tolerance)
- 考虑分解算法(如Benders分解)
-
结果不符合预期:
- 检查目标函数权重设置
- 验证约束条件的物理意义
- 绘制中间结果辅助调试
6. 性能优化技巧
6.1 模型简化方法
-
线性化处理:
- 将发电机成本二次函数分段线性化
- 使用二进制变量处理电池充放电互斥约束
-
时间尺度聚合:
- 对长时间尺度问题,将相似时段合并
- 关键时段保持高分辨率
-
减少整数变量:
- 合理设置发电机启停的最小运行时间
- 使用连续变量+约束近似离散决策
6.2 求解加速策略
- 提供初始解:
matlab复制% 设置初始猜测
assign(P_gen, P_load - P_pv);
assign(SOC, 0.5*ones(24,1));
- 调整CPLEX参数:
matlab复制options.cplex.mip.tolerances.mipgap = 0.01; % 设置MIP gap为1%
options.cplex.timelimit = 3600; % 设置时间限制1小时
- 并行计算:
matlab复制options.cplex.threads = 4; % 使用4线程
6.3 大规模问题处理
对于包含多个微电网或长时间尺度的问题:
- 使用Benders分解:将问题分解为主问题和子问题
- 采用Benders分解:将问题按时间或空间分解
- 考虑近似动态规划:特别适合多阶段问题
matlab复制% Benders分解示例
controller = optimizer(Constraints, Objective, options, parameters, variables);
7. 工程实践建议
-
数据预处理:
- 对异常数据进行清洗和插补
- 归一化处理提高数值稳定性
- 准备典型场景数据用于测试
-
结果验证:
- 检查功率平衡是否严格满足
- 验证设备运行是否在物理限制内
- 对比不同求解器的结果一致性
-
代码维护:
- 采用模块化设计(分离数据、模型、求解部分)
- 添加详细注释说明变量和约束的物理意义
- 版本控制保存不同模型迭代
-
实时部署考虑:
- 将MATLAB模型转换为C/C++代码
- 设计反馈校正机制处理预测误差
- 设置安全裕度应对不确定性
