做微网调度优化这个方向也有好几年了。最近不少同行和研究生在问“含冰蓄冷空调的冷热电联供型微网多时间尺度优化调度”这个题目怎么做,尤其是蓄冰槽怎么建模、怎么用Matlab落地。这个题目看似复杂,但拆开来看,其实就是“一个CCHP微网”加上“一台冰蓄冷空调”再套上“日前+日内两阶段调度”的组合。难的不是单个环节,而是怎么把冷、热、电三种能量流统一到同一个优化框架里,还要让Ice Storage这种“隐性储能”真正发挥作用。这篇文章我就以自己做过的某园区冷热电联供微网项目为基础,把物理结构、数学模型、多时间尺度调度逻辑以及Matlab代码实现的关键点完整拆一遍,给想复现这个方向的同学一条可以直接走的路。
1. 项目全貌与需求拆解
1.1 这个项目到底在解决什么问题
常规微网调度只考虑电功率平衡,但冷热电联供型微网要同时处理三条能量母线:电负荷、热负荷和冷负荷。燃气轮机发电时有大量余热排出,这部分热可以回收用于供暖,也可以驱动吸收式制冷机制冷。问题在于,供电和供冷/供热并不是同步的——白天冷负荷拉满的时候,电价通常也是最高的;而夜里冷负荷低、谷电便宜,燃气轮机却不可能为了“蓄冷”单独满负荷跑一晚上。
这时候冰蓄冷空调就派上了用场。它本质上是一种“电转冷”的时间平移装置:夜间用低谷电驱动制冷机组制冰,把冷量以冰的形式存起来;白天用电高峰时段融冰供冷,少开或者不开电制冷机。这样一来,微网里的冷负荷不再是刚性的,而是变成了一个可以被调度安排的能量项。把这个思路放到整个CCHP系统里,就不只是空调省钱的问题了,而是能让燃气轮机的运行策略、蓄电池的充放策略、购售电策略全部跟着联动起来,运行成本才能整体降下来。
1.2 冰蓄冷空调在微网中的角色定位
很多第一次接触冰蓄冷的人会把它当成“一个大冰箱”,其实它的本质更像一个“冷量水库”。夜间蓄冰就相当于往水库里蓄水,白天融冰供冷就相当于开闸放水。在优化模型里,它的角色和蓄电池非常类似,都有一个荷电状态(SOC),有储/放功率上下限,有能量转换效率,唯独不同的是它的“能量”是冷量而不是电量。
但要注意,冰蓄冷和蓄电池在建模上有一个关键差异:蓄电池是双向的,既可以充电也可以放电,充放可以在同一时刻二选一;而蓄冰槽的输入是“电制冷产生的冷量”,输出是“融冰释放的冷量”,输入和输出在物理上也是互斥的。蓄冰工况下COP约3左右,也就是说消耗1份电可以存进3份冷量;融冰工况下释放冷量的效率接近1,基本没有太大损耗,但融冰速率受冰槽结构和换热条件限制。
我在第一次建模时犯过一个典型错误:直接把蓄冰槽当成普通电池,用充放电状态变量去表达,结果优化结果特别离谱——白天一边用电制冷一边融冰,晚上一边蓄冰一边放冷,看着完全反逻辑。后来重构模型时才想明白,蓄冰槽一定要在“冷功率平衡”里用冷量表达:蓄冰是在冷负荷侧增加了一个冷量吸收项,融冰是在冷负荷侧增加了一个冷量供应项,二者之间只通过SOC状态变量建立联系。这一步想通了,整个模型才顺起来。
1.3 为什么非要“多时间尺度”调度
如果只靠一个单阶段的日前调度,预测误差会直接吃掉调度方案的可行性。光伏出力受天气影响大,冷负荷受气温和人员活动影响大,日前预测的偏差到20%是很常见的事情。例如某天下午实际冷负荷比预测高出一截,日前计划里分配的吸收式制冷和融冰供冷就不够了,这时候如果不做日内修正,只能现场紧急购电开电制冷机,成本一下子就上去了。
多时间尺度调度的思路,用大白话说就是“走一步看一步、看一步修正一步”。日前调度先根据未来24小时的预测数据,制定一个全局性的运行计划,确定燃气轮机启停组合、蓄冰槽蓄放冰框架、蓄电池充放框架;日内滚动调度再根据超短期预测,以15分钟为周期对未来的1~4小时重新求解,在尽量不偏离日前框架的前提下,修正各设备的出力。这个思想和模型预测控制(MPC)的滚动优化本质上是同一套逻辑。
时间尺度划分的比较关系可以看下面这个表:
| 调度层级 | 更新周期 | 预测窗口 | 决策内容 | 主要作用 |
|---|---|---|---|---|
| 日前调度 | 每日一次 | 未来24h | 机组启停、蓄冰/融冰计划、储能基准轨迹 | 全局经济性最优 |
| 日内滚动 | 15min一次 | 未来1~4h | 各设备出力修正、购售电调整 | 应对预测偏差 |
| 实时控制 | 秒级 | 瞬时 | 就地频率/功率控制 | 兜底功率平衡 |
这篇文章后面重点讲的,就是前两个尺度怎么建模、怎么在Matlab里实现,以及两个尺度之间如何通过“基准轨迹+偏差惩罚”协调起来。
2. 系统建模与优化模型拆解
2.1 物理系统结构与能量流
建模之前,先把系统的物理结构捋清楚。我采用的典型CCHP微网拓扑包含以下设备:
- 燃气轮机(GT):燃天然气发电,同时产生可回收余热
- 余热回收装置:把燃气轮机排烟余热转换为热站可用热功率
- 吸收式制冷机(溴化锂机组):利用余热制冷
- 电制冷机:常规压缩式制冷,直接用电力制冷
- 冰蓄冷装置:包含蓄冰机组和蓄冰槽,谷电时段蓄冰、峰电时段融冰
- 蓄电池:电储能,平抑电功率波动
- 光伏(PV):可再生能源发电
- 燃气锅炉:余热不足时补充供热
- 与配电网的交换接口:可购电售电
整个系统的能量流是这样的。燃气轮机烧天然气发电,发出的电并入微网母线,和光伏、蓄电池、购电一起共同满足电负荷;电负荷包括普通电负荷、电制冷机耗电、蓄冰机组耗电、蓄电池充电功率。燃气轮机排烟余热进入余热回收装置,变成热功率,一部分直接供给热负荷,另一部分驱动吸收式制冷机。冷负荷则由吸收式制冷机、电制冷机、蓄冰槽融冰三方共同供给。如果某个时刻余热不足,燃气锅炉补燃供热。
这样一个系统的调度逻辑,本质上是在每一小时(日前)或每15分钟(日内)里,决定燃气轮机发多少电、余热怎么分配、电制冷与冰蓄冷怎么配合、蓄电池怎么充放、电网交互多少电量。每一次决策都要让成本最小,同时保证所有能量平衡和设备运行在安全边界内。
2.2 主要设备建模要点
燃气轮机是系统的核心动力源。建模时我用两个关键参数:发电效率η_gt和热电比r_chp。燃气轮机输入燃料功率F_gt,发电功率P_gt = η_gt * F_gt,可回收余热功率Q_heat_rec = r_chp * P_gt,燃料成本按燃气耗量乘以气价计算。启停成本用0-1变量表达,只要机组从停机转为运行,就记一次启动费用。此外还要加爬坡约束,防止前后时段出力变化过于剧烈。
余热回收****装置的效率η_hrec一般在0.8左右,它把排烟余热转换为热站可用热功率。吸收式制冷机再把这个热功率转换成冷功率,制冷系数COP_ab可以取1.3左右。注意,吸收式制冷机的COP大于1是因为它利用的是热驱动,能量品位低但数量大,这一点跟电制冷机有本质区别。
电制冷机建模最简单,消耗电功率P_ec,输出冷功率Q_ec = COP_ec * P_ec,COP_ec取4.5。电制冷机的启停也可以做成连续调节,避免额外引入0-1变量增加求解复杂度。
冰蓄冷装置需要单独建立SOC状态方程。蓄冰机组蓄冰时消耗电功率P_ice,以蓄冰工况COP_ice(约3.2)转换为冷量存入蓄冰槽;融冰时释放冷量Q_melt。SOC状态转移可以写成:
S_soc(t+1) = S_soc(t) - Q_melt(t) / η_melt + η_ch * Q_ch_ice(t)
其中Q_ch_ice = COP_ice * P_ice,表示蓄冰过程存入槽内的冷量;η_melt和η_ch分别代表放冷和蓄冷过程的效率。蓄冰和融冰在同一个时段内不能同时进行,这个互斥关系用两个0-1变量加上一个大M约束实现。最后再加一个调度周期末的SOC约束,保证蓄冰槽跨日出清的一致性,不允许第二天“白嫖”前一天剩下的冰。
蓄电池的建模相对标准。SOC状态转移、充放功率上下限、充放互斥、初末SOC相等这些约束都要带上,充放电效率我取0.92。注意蓄电池和蓄冰槽在功率平衡方程里的位置完全不同,蓄电池直接进出电功率,而蓄冰槽是“电功率-冷功率”的跨能转换,这个区别在组装约束时千万别搞混。
2.3 目标函数与约束条件
目标函数是综合运行成本最小,包括五部分:燃气轮机和燃气锅炉的燃料成本、从电网购电的费用、设备启停成本、运行维护成本、弃光惩罚。用一个式子表达就是:
min Σ (C_fuel + C_buy - C_sell + C_start + C_om)
购电成本和售电收益按分时电价计算,燃气成本按气价和热值折算。弃光惩罚项用于保证系统优先消纳光伏,但惩罚系数不要设太大,避免数值病态。
约束条件分六类,我在代码里也是按这个顺序组的:
- 电功率平衡:燃气轮机出力+光伏+蓄电池放电+购电 = 电负荷+电制冷耗电+蓄冰耗电+蓄电池充电+售电
- 热功率平衡:余热回收输出+燃气锅炉供热 = 热负荷+吸收式制冷机耗热
- 冷功率平衡:吸收式制冷+电制冷+融冰供冷 = 冷负荷+蓄冰槽蓄冰冷量
- 设备容量约束:各类设备出力上下限
- 储能状态约束:SOC动态、容量上下限、充放互斥
- 电网交互约束:购售电功率上限,以及购电和售电的互斥关系
值得一提的是冷功率平衡式里“蓄冰槽蓄冰冷量”这一项,它代表蓄冰机组把冷量“灌”进冰槽,形式上跟冷负荷一样都是冷量的消耗方。把蓄冰看作冷负荷、把融冰看作冷源,这个角度很重要,直接决定了后面的代码怎么写。
3. 多时间尺度调度策略与实现逻辑
3.1 日前调度的决策内容
日前调度在每天零点前运行一次,以1小时为步长、24小时为优化区间,输入是未来24小时的电负荷、冷负荷、热负荷、光伏出力、分时电价的预测曲线。它要输出的决策包括:
- 燃气轮机每小时启停状态和发电功率
- 燃气锅炉的供热功率
- 吸收式制冷机和电制冷机的制冷功率分配
- 蓄冰槽每小时的蓄冰/融冰功率及SOC轨迹
- 蓄电池每小时充放电功率
- 每小时购电/售电功率
日前调度的目标是把全局成本压到最低,所以它会在谷电时段尽量多购电蓄冰、给蓄电池充电,在峰电时段让燃气轮机多发、融冰供冷,减少高价购电。从结果看,蓄冰槽的SOC曲线会呈现典型的“夜间攀升、白天下降”的形态,这个曲线就是日内滚动调度要跟踪的基准轨迹。
这里有一个工程经验:日前调度的步长不一定要设成1小时。如果冷负荷变化比较快,或者你所在地区的分时电价时段边界比较复杂,建议把步长缩短到30分钟甚至15分钟。代价是决策变量数量成倍增加,但对目前的主流求解器来说,几十个0-1变量的MILP问题依然很快。
3.2 日内滚动修正的设计思路
日内滚动调度是应对不确定性的关键环节。我自己做项目时用的是15分钟触发一次、滚动优化未来4个时段(即1小时)的窗口设置。为什么选15分钟而不是5分钟?因为超短期预测的更新频率通常是15分钟一个周期,而且5分钟粒度的优化会让求解次数翻倍,实际执行时也没必要做到那么精细。
日内滚动的决策变量跟日前调度基本一致,区别在于:它只关心窗口内的决策,并且必须考虑“当前系统状态”作为初始条件。比如当前时刻蓄冰槽的SOC是多少、蓄电池SOC是多少、燃气轮机是否处于开机状态,这些状态直接来自实时监测或日前计划的执行结果。窗口内第一时段的决策会被真正下发执行,后面几个时段的决策只是为后续滚动做准备。
日内优化与日前优化最大的区别在目标函数里多了一个偏差惩罚项。如果不加这个惩罚,日内滚动会完全按照最新预测重新算一个“最优轨迹”,很可能跟日前计划的机组启停、蓄冰策略完全拧着来,反倒造成运行混乱。加了惩罚之后,日内调度会尽量贴着日前计划走,只有当预测偏差确实大到需要修正时,它才会主动偏离基准轨迹。
3.3 时间尺度之间的信息传递与协调
两阶段调度之间传递的信息主要有三类:燃气轮机的启停状态序列、蓄冰槽的基准SOC轨迹、蓄电池的基准充放电轨迹。我采用的惩罚系数是单位燃料成本的15%~20%。这个权重很关键,小了日内就完全放飞自我,日前等于白做;大了日内就失去修正能力,滚不滚动就没意义了。
另外,日内滚动求解时还可以加一个边界约束,例如“燃气轮机出力与日前计划的偏差不超过±20%”。这类约束能从硬约束层面防止日内结果跑偏,比单纯加软惩罚更可靠。实际项目中我是“软惩罚+硬边界”一起用的:软惩罚保证趋势一致,硬边界保证可执行性。
日内滚动执行完当前时段后,结果会反馈给实时控制层。这一层我通常不放到优化模型里,而是用简单的AGC逻辑或就地控制器处理秒级功率波动。换句话说,多时间尺度调度解决的是“分钟/小时级的经济调度”问题,秒级的功率平衡交给底层控制去兜底,这样层次分明,模型复杂度可控,工程上也更合理。
4. Matlab代码实现的核心环节
4.1 求解工具与建模套路
Matlab实现这类调度模型,我推荐用YALMIP工具箱加商用MILP求解器(比如Gurobi或Cplex)的组合。YALMIP最大的好处是可以用符号化的方式写约束和目标函数,不用自己去拼稀疏系数矩阵,这对于约束多、耦合复杂的CCHP模型来说极其重要。Matlab自带的optimproblem框架也能做,但遇到大M约束、SOC状态转移这种跨时段耦合约束时,写起来远不如YALMIP顺手。
代码整体框架分六步:清空环境并定义参数 → 读取负荷、光伏、电价数据 → 定义决策变量和状态变量 → 组装约束 → 写目标函数 → 调用求解器并处理结果。为了调试方便,我习惯把参数集中放到一个结构体里,例如para.gt_up、para.gt_down,这样不同算例之间切换只需要改动参数文件,不需要碰模型主体。
4.2 关键代码片段解析
先看变量定义部分。这里用到sdpvar定义连续变量、binvar定义0-1变量。以日前调度为例,假设T=24:
T = 24; P_gt = sdpvar(1, T); % 燃气轮机出力 on_gt = binvar(1, T); % 燃气轮机启停状态 P_ec = sdpvar(1, T); % 电制冷机耗电功率 Q_ab = sdpvar(1, T); % 吸收式制冷输出冷量 Q_melt = sdpvar(1, T); % 融冰供冷量 P_ice = sdpvar(1, T); % 蓄冰耗电功率 z_ch = binvar(1, T); % 蓄冰状态,1为蓄冰 z_melt = binvar(1, T); % 融冰状态,1为融冰 S_soc = sdpvar(1, T+1); % 蓄冰槽SOC,含末状态 P_buy = sdpvar(1, T); % 购电功率 P_sell = sdpvar(1, T); % 售电功率 SOC_bat = sdpvar(1, T+1); % 蓄电池SOC P_ch = sdpvar(1, T); % 蓄电池充电功率 P_dis = sdpvar(1, T); % 蓄电池放电功率接下来是电功率平衡约束。蓄冰耗电P_ice、电制冷耗电P_ec、蓄电池充电P_ch都作为负荷项放到等式右边:
Constraints = []; for t = 1:T Constraints = [Constraints, ... P_gt(t) + P_pv(t) + P_dis(t) + P_buy(t) == ... L_elec(t) + P_ec(t) + P_ice(t) + P_ch(t) + P_sell(t)]; end冷功率平衡约束里,把蓄冰冷量Q_ch_ice作为冷负荷项,把融冰Q_melt作为冷源项:
% 蓄冰冷量 = COP_ice * P_ice Q_ch_ice = para.cop_ice * P_ice; for t = 1:T Constraints = [Constraints, ... Q_ab(t) + P_ec(t) * para.cop_ec + Q_melt(t) == ... L_cold(t) + Q_ch_ice(t)]; end这里P_ec(t) * para.cop_ec就是电制冷机的输出冷量,吸收式制冷输出Q_ab直接是冷量变量,避免单位混乱。
蓄冰槽的SOC状态转移和蓄放互斥约束是关键:
% SOC初值 Constraints = [Constraints, S_soc(1) == para.soc_ice_0]; for t = 1:T % SOC状态转移 Constraints = [Constraints, ... S_soc(t+1) == S_soc(t) * (1 - para.ice_loss) - Q_melt(t)/para.melt_eff + para.ch_eff * Q_ch_ice(t)]; % 容量上下限 Constraints = [Constraints, 0 <= S_soc(t+1) <= para.ice_cap]; % 蓄冰与融冰互斥 Constraints = [Constraints, Q_ch_ice(t) <= para.ice_ch_max * z_ch(t)]; Constraints = [Constraints, Q_melt(t) <= para.ice_melt_max * z_melt(t)]; Constraints = [Constraints, z_ch(t) + z_melt(t) <= 1]; end % 日末SOC约束,保证跨日一致 Constraints = [Constraints, S_soc(T+1) >= para.soc_ice_0];注意融冰功率Q_melt的取值上限不是固定值,有些冰槽的融冰速率会随冰层厚度变化,但工程上做线性近似完全够用。把互斥约束写成两个0-1变量的大M形式,会比用单个三态变量方便得多,YALMIP对这种写法非常友好。
4.3 日内滚动循环的实现思路
日内滚动调度的主循环是个经典的MPC结构。我的实现框架如下:
for k = 1 : 96-3 % 当前时刻索引k,滚动窗口长度H=4 H = 4; idx = k : k+H-1; % 读取超短期预测数据 L_pred = load_pred(idx); P_pv_pred = pv_pred(idx); price_pred = price_pred(idx); % 初始化窗口问题 Constraints = []; Objective = 0; % 定义窗口内变量(维度改成H) % ... 变量定义与约束组装,与日前模型基本一致 ... % 加入对日前计划的偏差惩罚项 beta = para.beta * para.price_gas; for h = 1:H Objective = Objective + beta * abs(P_gt_win(h) - P_gt_da(idx(h))); end % 求解并执行当前时段 optimize(Constraints, Objective, options); P_gt_execute(k) = value(P_gt_win(1)); % 其余设备类似 end这里有一个实际操作中的坑:每天都跑一次完整滚动循环,求解次数非常多。如果每个窗口都从头构建YALMIP模型,代码运行速度会慢得让人怀疑人生。我在项目里把“模型构建”部分封装成了一个函数,输入是预测数据和基准轨迹,输出为优化后的调度结果,循环里只调用这个函数。实测下来,96个滚动窗口全部跑完不到两分钟,完全在可接受范围内。
4.4 数据准备与算例设置
没有好的数据,模型再漂亮都是白搭。做算例时数据至少包含四部分:负荷曲线(电、冷、热)、光伏出力曲线、分时电价曲线、设备参数表。负荷和光伏数据可以用历史数据加预测误差的方式生成。比如取某个夏季典型日的历史冷负荷曲线,乘以一个0.9~1.1的随机扰动模拟预测偏差,这样生成的算例既能体现日前/日内差异,又不脱离实际。
设备参数可以按我下面的典型值设置,方便你快速复现:
| 设备/参数 | 数值 |
|---|---|
| 燃气轮机额定功率 | 500 kW |
| 发电效率 | 0.30 |
| 热电比 | 1.2 |
| 余热回收效率 | 0.85 |
| 吸收式制冷COP | 1.3 |
| 电制冷机COP | 4.5 |
| 蓄冰工况COP | 3.2 |
| 蓄冰槽容量 | 1000 kWh |
| 最大蓄冰功率 | 250 kW |
| 最大融冰功率 | 250 kW |
| 蓄电池容量 | 300 kWh |
| 蓄电池最大充放功率 | 100 kW |
| 光伏装机 | 300 kW |
分时电价如果手头没有真实数据,可以用典型峰平谷电价:谷段0.3元/kWh,平时段0.7元/kWh,峰段1.1元/kWh。天然气价格2.8元/m³,低热值按9.7 kWh/m³折算。
结果处理部分,我习惯把燃气轮机出力、电制冷功率、蓄冰SOC、购售电功率这些关键曲线画在一起对比,再用sum统计总成本。画图时注意把X轴时间对齐到真实时刻,否则日出和日没位置都会错位,看起来就别扭。
5. 调试过程中的常见问题与避坑记录
5.1 模型“死活算不出可行解”
这个问题在前期建模阶段出现得最频繁。我刚把这个项目的约束全部组装完毕之后第一次求解,YALMIP直接报无解。排查思路很简单,先把目标函数全部置零,只求可行解;如果仍然无解,再用松弛变量逐个平衡等式,看松弛量落在哪条约束上。
实际项目中最常见的原因有两个。一是冷负荷峰值超过了吸收式制冷、电制冷和融冰三者最大供冷能力之和。这种情况属于设备容量配置不足,不是模型写错了。二是蓄冰槽的日末SOC约束设置不合理。如果前一天蓄冰量被大量消耗,日末SOC小于初值,强行要求SOC(T+1)>=SOC_0就会导致傍晚时段无法满足冷负荷。处理办法是把日末约束改成SOC(T+1)>= 0.7*SOC_0这类松弛形式,或者干脆只在蓄冰策略本身就要求跨日平衡时用严格等式。
5.2 蓄冰槽“蓄不满”或者“用不完”
优化结果里蓄冰槽经常只用了不到一半容量,这说明冰蓄冷的经济性没有被模型体现出来。原因通常是峰谷电价差太小,导致谷电蓄冰省下的钱覆盖不了设备损耗和运维成本。如果算例里电价差确实小,那就不是模型问题,是商业模式问题。
但如果你确信电价差足够大,结果还是蓄不满,就要检查蓄冰和融冰的互斥约束是不是误伤了。我踩过一次坑:融冰工况下允许吸收式制冷和电制冷同时停运只靠融冰供冷,但融冰功率上限设得太低,导致白天能放出来的冷量有限,冰槽自然用不彻底。调试时把Q_melt的上限调到蓄冰功率的1.5倍,并用表格列出峰值冷负荷时各冷源供冷量,一眼就能看出问题在哪。
5.3 日前计划和日内计划偏差很大
如果日内滚动结果跟日前计划差得很远,说明偏差惩罚权重太小,或者日内模型里没有继承日前关键决策。有一个检查技巧:把燃气轮机的启停序列取出来,对比日前和日内结果,如果大部分时段的开/停机状态都对不上,那就说明日内没有收到“启停状态必须继承日前结果”的信息。
解决办法是在日内模型的目标函数中对启停状态加硬约束:on_gt_win(h) == on_gt_da(idx(h))。这样日内滚动只修正出力大小,不改变启停组合,运行逻辑就会稳定很多。只有在超短期预测显示负荷发生剧烈变化时,才允许修改启停状态,这部分可以通过松弛变量实现。
5.4 求解器数值问题与性能优化
MILP模型经常遇到数值条件差的问题。最常见的原因是SOC量纲跟功率量纲差的太大。比如蓄冰槽SOC上限设成10000 kWh,而电功率是几百kW级别,目标函数里又多了一个数量级的惩罚系数,求解器跑起来矩阵条件数就难看了,容易出现“Optimal,但结果明显不合理”或者求解极慢的情况。
我的建议是所有能量单位统一成kWh、功率统一成kW,SOC做归一化处理,上限直接写成1,约束里SOC乘以容量再参与运算。另外,大M系数不要盲目取1e5,能取100就取100,够约束生效就行。数值条件越好,求解速度越快。
| 现象 | 可能原因 | 排查与处理 |
|---|---|---|
| 无可行解 | 容量不足/日末SOC约束过严 | 松弛等式约束、放宽容限 |
| 蓄冰量利用率低 | 融冰上限低/电价差小 | 调大融冰上限、检查峰谷价差 |
| 日前日内偏差大 | 惩罚系数小/未继承启停 | 加大偏差惩罚、硬约束启停状态 |
| 求解很慢 | 变量量纲混乱/M过大 | 归一化SOC、缩小M系数 |
此外,如果用的求解器支持多线程参数,记得在options里开起来;日内滚动场景下每个窗口的问题规模不大,但循环次数多,单窗口求解时间每缩短0.1秒,整体都能明显感知到。
写到最后,我最大的一个体会是,这种调度模型猛一看是个数学优化问题,做到后面才发现真正的门槛是工程理解。设备参数是你自己定的,预测数据是你自己给的,但结果能不能在现场落地,全靠你对物理逻辑有没有想透。冰蓄冷这东西,我在实际项目中把它的自损率从0改成每天1%之后,整个SOC曲线立刻合理了,这种参数你在论文附录里永远找不到,但工程里天天遇到。如果你也在复现类似题目,建议先别急着钻代码,先把能量流图画明白,把蓄冰槽是“冷量水库”这个直觉建立起来,后面的一切都会顺很多。