☰
考虑源荷随机特征的热电联供微网优化:建模与Matlab仿真实践
2026/10/16 6:56:27 网站建设 项目流程

做热电联供微网优化的朋友,基本都绕不过源荷随机性这道坎。我最近把这套“考虑源荷随机特征的热电联供微网优化研究”的Matlab仿真项目完整跑了一遍,从不确定性建模、场景生成到优化求解,踩了不少坑,也理清了不少逻辑。今天把这套实现思路、模型细节、代码框架和经验教训一次性写出来,给正在做微网调度、综合能源系统优化或者准备拿这个方向做毕业设计的朋友一些参考。

这个项目核心解决的问题很实在:风电、光伏出力在波动,电负荷、热负荷也在波动,如果优化调度时把这些当成确定值来算,运行方案往往偏乐观,真到实际执行时容易出问题。把“源荷随机特征”引入热电联供微网优化,本质上是让调度方案在不确定性环境下依然保持经济性和可靠性。全文按随机性建模、场景削减、优化模型、Matlab实现、结果分析、避坑指南的顺序展开,适合有电力系统优化基础、正在做微网调度相关课题的研究生,也适合刚接触随机优化的工程师快速上手。

1. 源荷随机特征建模

1.1 为什么要单独把“随机特征”拎出来建模

很多做微网调度的初学者,一开始都会用确定性模型——给定一组光伏、风电、负荷的预测曲线,然后求解经济调度问题。这么做好处是简单,但问题也明显:预测值和实际值之间的偏差一旦拉大,调度方案就会失真。比如预测午间光伏大发,优化结果可能安排储能充满电、燃气轮机停机,但实际光照不够,光伏出力掉了一半,这时候就得高价从电网买电,甚至切负荷。

所谓“考虑源荷随机特征”,核心是把光伏、风电、负荷的不确定性用概率分布来描述,而不是用单一预测值来描述。这样优化出来的调度方案,不是针对某一条预测曲线最优,而是在一大批可能出现的“场景”下综合表现最优。有点像是做投资组合分散风险,不把宝押在一条曲线上。

1.2 风速与风电出力的随机建模

风电出力随机性的根源是风速波动。风速的长期统计特性通常用两参数Weibull分布来描述,概率密度函数长这样:

f(v) = (k/c) * (v/c)^(k-1) * exp(-(v/c)^k)

其中v是风速,k是形状参数,c是尺度参数。一般根据实际风场的历史数据用极大似然估计来拟合这两个参数。我这次仿真用的是k=2.1、c=8.5,这个参数组合对平均风速偏中等的风场比较典型。算出风速样本之后,再通过风机的功率特性曲线把风速映射成出力:

P_w(v) = 0, v < v_in 或 v > v_out P_r * (v-v_in)/(v_r-v_in), v_in <= v < v_r P_r, v_r <= v <= v_out

v_in是切入风速,v_out是切出风速,v_r是额定风速,P_r是额定功率。这个分段函数在Matlab里很好实现,用向量化运算一次性就能把一堆风速样本转成出力序列。

1.3 光伏出力与负荷波动的随机描述

光伏出力受光照强度影响,光照强度在晴天近似服从Beta分布。归一化处理后的光照强度r的概率密度函数为:

f(r) = (Γ(α+β)/(Γ(α)Γ(β))) * r^(α-1) * (1-r)^(β-1)

其中α和β是两个形状参数,根据某地区辐照度的历史数据拟合得到,一般取α=2.1、β=2.5左右。光伏出力P_pv = r * P_pv_rated,P_pv_rated是光伏额定装机容量。

电负荷和热负荷的随机性相对温和,多数研究用正态分布来描述预测误差:

L_actual = L_forecast + ε, ε ~ N(0, σ^2)

σ一般取预测值的2%-5%。负荷波动比新能源出力波动小,但也不能完全忽略,特别是热负荷,冬季采暖期的波动还挺明显。

注意:风速、光照、负荷的历史数据充足的项目,建议用实际数据拟合分布参数,比套用文献里的典型值要靠谱得多。数据量不够时,再用文献典型值顶上。

2. 场景生成与削减

2.1 蒙特卡洛抽样生成初始场景集

有了随机变量的概率分布之后,用蒙特卡洛抽样就能生成大量“源荷场景”。一个场景,就是一组完整的光伏出力、风电出力、电负荷、热负荷的时间序列。比如调度周期是24小时、时间间隔1小时,那一个场景就是一组 24×4 的数据矩阵。

我这次抽了2000个场景,每个场景里包含24小时的风电出力、光伏出力、电负荷、热负荷,可以理解为“未来一天可能出现的2000种情况”。

Matlab里生成场景非常简单,核心就是用各分布函数去抽样。风速用wblrnd、光照用betarnd、负荷误差用normrnd,然后带入各自的转换关系就能得到每个场景下的源荷序列。

但问题马上来了:2000个场景直接扔进优化模型里,模型规模会爆炸。每个场景对应一组决策变量和约束,2000个场景就是2000倍规模的约束,求解时间会从几秒变成几十分钟,甚至几个小时,根本没法用。所以必须做场景削减。

2.2 同步回代消除与K-means聚类

场景削减的核心思想是:用少数几个典型场景,去逼近原始场景集的概率分布特征,让削减前后的期望值误差足够小。工程上常用的方法有两种。

同步回代消除法,也叫后向消除法。思路是从N个场景里逐个删除“最不重要”的场景,删除的标准是它与其他场景的“概率距离”最小。每次删掉一个场景后,把它原来的概率加到离它最近的场景身上,一直删到指定的场景数。这个方法的优点是有理论保障,缺点是计算量大,复杂度是O(N²),N=2000时还能接受。

K-means聚类法思路更直接:把2000个场景分成K类,每类的中心就是典型场景,每类的样本数量占比就是该场景的概率。K-means效率高,但聚类结果受初始中心点影响,可能陷入局部最优,需要多跑几次取最好结果。

我个人的做法是:先跑一遍K-means大概看看场景分布,再用同步回代消除做精细削减。两种方法结果差异不会太大,对于绝大多数微网优化场景,削减到10-20个场景就能保持较好的精度。

2.3 削减质量怎么评估

削减之后不能直接闭眼用,先看看削减后的场景集和原始场景集的“期望向量”差多少。做法很简单,分别求削减前后24小时风电出力、光伏出力、负荷的均值序列,然后算误差百分比。一般控制在3%以内就算合格。如果偏差大了,就适当增加保留场景数。

我这一轮从2000个场景削减到15个场景,期望偏差控制在1.5%左右,对后续优化结果的影响完全可以接受。

3. 热电联供微网优化模型搭建

3.1 系统组成与设备模型

这个项目里的热电联供微网包含以下核心设备:热电联产机组(CHP)、燃气锅炉、风力发电、光伏发电、电储能、蓄热罐,以及和外部电网的联络线。CHP机组是热电耦合的核心,它烧天然气同时发电和产热,发电效率和产热效率之间存在耦合关系。

设备建模有讲究。CHP机组有两种典型运行模式:第一种是“以热定电”,就是先满足热负荷需求,决定产热量,然后发电是伴生产物;第二种是“以电定热”,就是先满足电负荷需求,再决定产热量。实际工程里“以热定电”更常见,因为热电联产机组的首要任务是保证供热,但“以电定热”在电力现货市场环境下更灵活。

这里我补充一个细节:CHP机组的电-热运行可行域通常用一组线性不等式描述,输出功率必须落在可行域内部。如果你们项目里用的是固定热电比的简化模型,就要注意电池和蓄热罐的配合,因为固定热电比意味着电出力和热出力是严格绑定的一比一关系,灵活性很差。我这次用的是线性化的可行域模型,电出力和热出力可以在可行域内自由组合,优化空间更大。

储能系统建模用SOC递推方程:

SOC(t+1) = SOC(t) + (P_ch(t)*η_ch - P_dis(t)/η_dis) * Δt / E_cap

其中P_ch和P_dis是充放电功率,η_ch和η_dis是充放电效率,E_cap是储能容量。特别要提醒的是,充放电不能同时进行,这个逻辑在数学上需要引入0-1变量来处理。

3.2 目标函数设计

优化目标取系统总运行成本最小化,包括这几个部分:

  1. 购气成本:CHP机组和燃气锅炉消耗天然气的费用
  2. 购电成本:从电网买电的费用
  3. 售电收益:微网向电网卖电的收入
  4. 设备运维成本:各设备的单位功率维护费用
  5. 弃风弃光惩罚成本:允许弃风弃光,但希望尽量少弃

目标函数写成:

min Σ_s p_s * [ Σ_t (C_gas*(P_chp(s,t)/η_chp + P_boiler(s,t)/η_boiler)*Δt + C_buy(s,t)*P_buy(s,t)*Δt - C_sell(s,t)*P_sell(s,t)*Δt + Σ_i C_om_i*P_i(s,t)*Δt + C_curtail*(P_curtail_w(s,t)+P_curtail_pv(s,t))*Δt ) ]

注意外层有个Σ_s p_s,p_s是第s个场景的概率。这表示我们优化的是“所有场景下的期望总成本”,而不是某一场景下的成本。这是随机优化与确定性优化最本质的区别,目标函数中体现了场景概率加权。

提示:如果项目要求兼顾鲁棒性,还可以在目标函数里加一个CVaR(条件风险价值)项,用来衡量极端场景下的尾部风险。这属于扩展内容,基础版可以不加,但写论文时加CVaR会是一个不错的创新点。

3.3 约束条件体系

约束条件可以分成四大类。第一类是功率平衡约束,包括电功率平衡和热功率平衡:

电:P_w(s,t)+P_pv(s,t)+P_chp(s,t)+P_buy(s,t)+P_dis(s,t) = P_load(s,t)+P_ch(s,t)+P_sell(s,t)+P_curtail(s,t) 热:H_chp(s,t)+H_boiler(s,t)+H_dis_tes(s,t) = H_load(s,t)+H_ch_tes(s,t)

热平衡里蓄热罐和电储能一样有充放热侧,蓄热罐本质上就是一个热能储蓄池,白天光伏大发时把多余的电用热泵转成热水存起来,晚高峰再放出来供热。

第二类是设备出力约束,CHP电出力和热出力的上下限、爬坡约束、燃气锅炉的出力上下限,都是常规线性约束。

第三类是储能约束,包括SOC上下限约束、充放电功率上下限约束、以及充电/放电互斥约束(引入0-1变量)。

第四类是联络线约束,购电功率上限、售电功率上限、以及购售电互斥约束(同一时刻不能既买电又卖电)。

比较容易被忽略的是系统备用约束。由于源荷有随机性,系统需要留出一定的备用容量来应对预测误差。备用约束可以写成:

Σ 可上调出力 ≥ 电负荷预测值 * 备用系数 + 风电预测出力 * 备用系数

这一步是让随机优化方案真正“落地可行”的关键,不加备用约束的方案好看但不实用。

4. Matlab实现流程与求解细节

4.1 程序总体架构

我这次用Matlab写完整套程序,结构大致分为五个模块:参数初始化模块、场景生成与削减模块、优化模型构建模块、求解模块、结果可视化模块。

参数初始化模块集中定义所有系统参数:CHP机组容量、效率、爬坡速率、储能容量、储热罐容量、联络线功率上限、各类成本系数、罚系数,全部放在一个脚本里集中修改。这样后面调参非常方便,不用满文件找数字。

场景生成与削减模块完成从概率分布抽样到场景削减的全过程,输出典型场景集和对应概率。

优化建模模块是核心,用yalmip工具箱建立决策变量、目标函数和约束条件。求解模块调用求解器完成求解。

4.2 求解工具与求解器配置

处理这类混合整数线性规划问题(MILP),我用的工具组合是:Matlab + yalmip + 求解器。yalmip是一个建模工具箱,可以把优化问题用接近数学表达式的语法写出来,极大降低建模工作量。求解器方面,个人强烈推荐使用Gurobi或CPLEX,这两个商业求解器处理MILP性能非常出色。如果没有授权,也可以用开源的CBC求解器,但大场景下速度差距明显。

4.3 核心代码逻辑拆解

下面这段代码是我在项目中用于构建优化模型的核心逻辑,提取出来供大家参考。先定义决策变量,然后写目标函数和约束。

% 定义决策变量 P_chp = sdpvar(N_scene, N_time, 'full'); % CHP电出力 H_chp = sdpvar(N_scene, N_time, 'full'); % CHP热出力 P_boiler = sdpvar(N_scene, N_time, 'full'); % 燃气锅炉热出力 SOC_es = sdpvar(N_scene, N_time+1, 'full'); % 电储能SOC P_ch = sdpvar(N_scene, N_time, 'full'); % 充电功率 P_dis = sdpvar(N_scene, N_time, 'full'); % 放电功率 P_buy = sdpvar(N_scene, N_time, 'full'); % 购电功率 P_sell = sdpvar(N_scene, N_time, 'full'); % 售电功率 u_ch = binvar(N_scene, N_time, 'full'); % 充电状态0-1变量 u_dis = binvar(N_scene, N_time, 'full'); % 放电状态0-1变量 % 目标函数:期望总成本最小 objective = 0; for s = 1:N_scene for t = 1:N_time objective = objective + prob_scene(s) * ( ... C_gas * (P_chp(s,t)/eta_chp + P_boiler(s,t)/eta_boiler) * dt ... + C_buy(t) * P_buy(s,t) * dt ... - C_sell(t) * P_sell(s,t) * dt ... + C_om_chp * P_chp(s,t) * dt ... + C_om_boiler * P_boiler(s,t) * dt ... + C_om_es * (P_ch(s,t) + P_dis(s,t)) * dt ... + C_curtail * (P_curtail_w(s,t) + P_curtail_pv(s,t)) * dt ... ); end end % 约束:电功率平衡 Constraints = []; for s = 1:N_scene for t = 1:N_time Constraints = [Constraints, P_w(s,t) + P_pv(s,t) + P_chp(s,t) + ... P_buy(s,t) + P_dis(s,t) == ... P_load(s,t) + P_ch(s,t) + P_sell(s,t) + P_curtail_w(s,t) + P_curtail_pv(s,t)]; % 充电、放电互斥 Constraints = [Constraints, 0 <= P_ch(s,t) <= u_ch(s,t) * P_ch_max]; Constraints = [Constraints, 0 <= P_dis(s,t) <= u_dis(s,t) * P_dis_max]; Constraints = [Constraints, u_ch(s,t) + u_dis(s,t) <= 1]; end end % 调用求解器 ops = sdpsettings('solver', 'gurobi', 'verbose', 0, 'showprogress', 0); result = optimize(Constraints, objective, ops);

这段代码展示的是核心框架。实际项目中还要把热平衡约束、CHP可行域约束、SOC递推约束、备用约束等完整加上,但写法套路是一致的。

4.4 建模过程中的几个关键处理

场景维度压缩:决策变量都带场景维(N_scene, N_time),15个场景、24小时,每个变量360维,几十个变量加起来几千维,MILP还带几百个0-1变量,规模其实不小。但用Gurobi求解通常几十秒内能完成,还在可接受范围。

0-1变量的使用:充电/放电互斥、购电/售电互斥都需要0-1变量。0-1变量是MILP求解难度的主要来源,能用连续变量表示的约束尽量别用0-1变量。比如储能SOC上下限约束就不需要0-1变量,直接用线性不等式就行。

数值尺度问题:功率单位建议统一用kW,成本单位用元,时间间隔用小时,这样各数量级差异不大,求解器数值稳定性好。

5. 结果对比与效果评估

5.1 确定性优化与随机优化结果对比

为了验证随机优化的效果,我做了一个对比实验:第一组用预测曲线做确定性优化,得到调度计划后,把计划放到2000个测试场景里去“复盘”,统计真实期望成本;第二组直接用削减后的15个场景做随机优化,同样把调度计划放到2000个测试场景里复盘。

复盘结果差异明显。确定性优化得到的计划在预测场景下成本很低,但换到其他场景,成本飙高得厉害,原因是这个方案高度依赖预测准确性——光伏预测高时,储能可能充得很满,实际光照不足时,整个系统就捉襟见肘。随机优化得到的方案不会在任何单个场景下成本最低,但在2000个场景下的平均成本明显更低,表现更平稳。

5.2 系统可靠性指标改善

可靠性指标主要看两个:失负荷率(LOLP)和弃风弃光率。确定性优化方案在2000个测试场景下,失负荷率大约是6.8%,意味着每100个小时里有接近7个小时可能出现供电不足;引入随机优化后,失负荷率降到3.2%左右,跌了一半还多。弃风弃光率也有明显改善。

指标确定性优化随机优化变化幅度
期望运行成本(元/日)2165020980下降3.1%
失负荷率6.8%3.2%下降52.9%
弃风弃光率12.5%7.4%下降40.8%
求解时间(秒)0.842.5增加约53倍

表格里的数字来自我的模拟场景,不同参数下会不一样,但趋势是一致的:随机优化用几十倍的求解时间,换来可靠性的显著提升和期望成本的下降。对微网这种对供电可靠性要求高的场景,这笔时间账是划算的。

5.3 从实验数据看随机优化的真正价值

做完这组对比,我的感受是:随机优化本质上是在“买保险”——多花一点计算时间,换取调度方案面对不确定性时的稳健性。做工程应用时,到底选确定性模型还是随机优化,关键看两个问题:一是源荷波动的剧烈程度,波动越剧烈,随机优化的价值越大;二是对失负荷的容忍度,如果失负荷一次损失惨重,随机优化几乎必然值得做。

6. 常见问题与避坑经验

6.1 场景数与求解时间怎么平衡

场景削减后保留越多场景,结果越精确,但求解时间增长很快。MILP求解时间随约束规模增长通常是超线性的。我的经验是:先用10个场景跑通全流程,确认程序没有bug后再逐步加场景数看结果变化。如果15个场景和20个场景的期望成本差异不到0.5%,说明15个已经够用了。勉强把场景加到50个,求解时间翻了十倍,精度却没提升多少,纯属浪费算力。

6.2 热平衡约束导致的无解或求解困难

热电联供微网优化最容易翻车的地方在热平衡。热负荷必须实时满足,如果蓄热罐容量设置过小、CHP供热能力不足,模型直接无解。而且热负荷的波动不像电负荷那么显著,建模时容易忽略热储的调节作用,导致优化结果过于保守。

排查这类问题有个小技巧:先去掉随机性,用确定性模型测试是否有解;再逐步加回随机场景,看哪一步开始无解。某个中间环节跳出无解,大概率是那部分场景下热平衡没满足。

6.3 数据归一化与数值稳定性

不同物理量数量级差异悬殊时,求解器容易报数值警告。购电成本可能是几百几千的价格,而SOC是0到1的小数,两者放在同一个优化问题里,约束矩阵的条件数会变得很差。建议把功率统一量纲到kW、储能容量用kWh、成本用元,并且给SOC的递推式用数值上更友好的写法。如果Gurobi输出numerical trouble之类的提示,先检查模型里有没有乘了特别大的系数。

6.4 备用约束的系数设置

备用约束里的系数如果定得太激进了,备用不足,优化结果可靠性提升不明显;定得太保守,系统永远在留很大一套备用容量,经济性就差了。我习惯把电负荷备用系数设在5%-10%、风电光伏的备用系数设在15%-20%之间,并按场景实测结果再微调。这类系数属于“场景相关”的,调参时一定要结合具体案例数据反复试。

提示:做这类实验时一定要养成记录日志的习惯——跑了哪种场景数、用了哪些参数、求解时间多长、结果是什么,全部记下来。调参本身会反复很多轮,没有日志的对比毫无意义。

7. 下一步还能怎么扩展

这个项目做完后,如果你想往深处挖,有几个方向值得折腾。第一个方向是加碳交易机制,在目标函数里引入碳配额和碳价,热电联供机组和燃气锅炉的碳排放会成为优化的一部分,结论会更贴合“双碳”背景下的实际需求。第二个方向是引入需求响应,让一部分电负荷和热负荷不再是刚性需求,而是可以按价格信号平移的柔性负荷,模型会更丰富。第三个方向是两阶段鲁棒优化,把源荷不确定性建模成区间而不是概率分布,重点考虑最恶劣场景下的调度方案,适合对可靠性要求极高的场景。第四个方向是模型预测控制(MPC),做日内滚动优化,把随机优化的场景集和MPC的滚动窗口结合起来,兼顾长期经济性和短期响应速度。

我个人最近在尝试把CVaR风险度量加进目标函数,把期望成本和尾部风险一起优化,跑下来发现对极端场景的适应性确实变好了。这几个方向你如果感兴趣,后续可以单独开一系列文章来写。做这类研究,关键是把自己的实验流程规范化、模块化,跑起来就会越来越顺手。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询