
1. 为什么楼宇微网要把需求侧负荷当成“储能电池”来用做楼宇微网优化调度的朋友应该都有同感光伏出力的波动性、负荷峰谷的刚性差异、电价的实时变化这三者凑在一起让微网调度变成一个既讲究经济性又讲究稳定性的复杂问题。以前大家一提到削峰填谷、平抑波动第一反应就是上储能电池但电池的度电成本、循环寿命、维护难度摆在那里很多楼宇项目算完经济账后还是犹豫再三。我这两年接触了不少楼宇微网的实际项目越来越觉得“需求侧虚拟储能”这条路被低估了。所谓虚拟储能通俗点说就是把楼宇里那些可以灵活调节的用电设备——中央空调、热水器、电动汽车充电桩、照明系统——当成一块“看不见的电池”来调度。空调温度往上调一度相当于少用了一部分电量这块“少用的电量”在系统层面看就跟电池放出了一部分电一样等电价低谷或者光伏大发的时候再把温度调回来相当于给这块“电池”充电。这个思路最吸引人的地方在于它不需要额外买电池不需要增加物理设备只需要把控制策略和调度算法做对就能在不影响用户舒适度的前提下撬动一块可观的调节容量。我在一个实际楼宇项目里粗略算过一栋两万平米的办公大楼中央空调群在舒适度允许的范围内能提供的虚拟储能容量大约相当于一个200~400 kWh的电池组而实现这个虚拟储能的成本几乎为零只是软件层面的事。从建模和优化的角度看楼宇微网优化调度如果把虚拟储能考虑进去问题的维度会拉高不少。传统微网调度只需要管物理电池的充放电状态现在还得同时管空调群的温度动态、热水器的储热状态、充电桩的错峰时序整件事就变成一个动态耦合的优化问题。这正是Matlab能发挥价值的地方Matlab处理矩阵运算、约束构建、求解器调用都很顺手配合Yalmip工具箱调用Gurobi或Cplex能够在可接受的时间内把这类中规模优化问题求到全局最优解。这篇文章我就把整套模型的建模思路、数学表达和Matlab代码实现完整梳理一遍。适合正在做微网优化、综合能源系统调度、需求响应方向研究的同学以及想在自己项目里落地虚拟储能策略的工程师参考。下面我会按“物理模型搭建 → 虚拟储能等效建模 → 优化数学模型 → Matlab代码实现 → 仿真结果解读 → 调试经验”这条线来讲尽量把每一步的逻辑闭环讲透。2. 楼宇微网的物理结构拆分哪些设备必须建模哪些可以简化设计优化调度模型的第一步不是急着写约束而是先把楼宇微网的物理拓扑理清楚。不同的设备类型在模型里的表达方式完全不同。如果把所有细节都建模进去非线性的、离散的变量会爆炸式增长求解难度直线上升如果简化过头调度结果又失去参考价值。这里面有一套权衡方法我讲讲自己在实践中沉淀下来的设备建模取舍标准。2.1 楼宇微网的典型设备构成与角色分层一栋楼宇微网从能量流动的视角看通常包含这几类核心单元设备类型功能角色调度自由度建模复杂度屋顶光伏清洁电源不可控按出力曲线给定低燃气轮机/柴油机可控电源可启停、可调出力中物理储能电池双向电源可充可放、有SOC约束中中央空调系统柔性负荷可调节设定温度/功率高电热水器柔性负荷可平移时段中电动汽车充电桩柔性负荷可延迟充电时段中基础照明与插座负荷刚性负荷不可调节低与配电网交互点PCC能源接口可买电/可售电、有功率上限低在建模之前我习惯先画一张功率平衡图——以母线为核心左侧是电源光伏、机组、电池放电、电网购电右侧是负荷刚性负荷、柔性负荷、电池充电。优化调度的本质就是在每个调度时段里决定可控设备之间的功率分配使得全局目标最优。2.2 光伏出力建模不要过度追求精细但要注意功率预测误差光伏出力在调度模型里通常作为已知参数输入因为调度决策是在日前day-ahead做出的光伏只能给预测曲线。我的处理方式是用一个简化的线性出力模型即给定每个时段的预测功率 P_pv(t)把它当作负的负荷直接放进功率平衡等式的一侧。之所以不建复杂的辐照-温度-效率非线性模型是因为优化时要的是数学上可解物理上的精细度交给光伏预测系统去完成即可。不过有一点要注意仿真验证阶段最好在预测出力上叠加一个小的误差扰动观察系统对光伏波动的响应。如果没有这层扰动整个模型会显得过于“完美”实际部署时会发现鲁棒性远不如仿真结果。这一点我在后面调试经验里会详细展开。2.3 物理储能电池SOE动态约束是模型的“锚点”物理储能的建模相对标准但还是有几个细节值得说。首先是用SOEState of Energy能量状态替代更常见的SOC概念因为调度关心的是能量进出SOE直接对应电池的可用电量单位统一为kWh。其次充放电约束里必须考虑同一时刻不能既充电又放电——这个约束看起来是废话但如果不显式添加很多求解器在松弛变量较多时确实会给出同时充放电的荒唐解。电池的SOE递推公式我习惯写成SOE(t1) SOE(t) η_ch * P_ch(t) * Δt - P_dis(t) * Δt / η_dis其中 η_ch 和 η_dis 分别代表充电和放电效率。这个公式里效率的位置很多人写反需要注意充电时电网送进电池的电要打折扣所以用乘法放电时电池送出去的电也要打折扣所以用除法。单位统一用kW和小时Δt取1小时这样能量单位就是kWh。2.4 哪些部分可以放心简化我在初期建模时也曾经试图把负荷里面的每个设备都细分出来结果发现模型复杂度飙升但调度结果的改善非常有限。后来总结出一条经验与调度自由度无关的设备全部并入刚性负荷有调节潜力的设备按“聚合体”来建模。所谓聚合体就是把楼宇里同类的柔性设备看作一个整体用集合层面的参数来描述比如“全部空调的聚合功率范围是80kW到120kW”而不是逐台描述。这样处理的好处显而易见变量数量从几十台设备降到几种资源类型优化模型的求解时间从几分钟降到几秒而决策结果的差别很小。对工程应用来说用精度换可解性是完全值得的。3. 虚拟储能的核心建模逻辑如何把“温度”翻译成“电量”虚拟储能建模是整个系统里最需要费心思的部分因为它不能像物理电池那样直接写充放电功率而是要通过温度、时间、用户舒适度这些间接变量来映射。我得把这部分讲细一点因为很多初学者在这里绕不过弯来。3.1 中央空调系统的蓄热特性楼宇天然存在的“热电池”先想一个物理事实一栋楼宇的墙体、家具、内部空气是一个很大的蓄热体。夏季空调在上午十点开始工作把室内温度从32℃降到26℃这些“冷量”不是瞬时消耗掉的而是储存在整个建筑结构里。如果中午把空调设定温度从26℃上调到28℃室温不会立刻跳到28℃而是缓慢上升——这个过程里空调压缩机的功率就降下来了相当于少用电也就是“放电”。反过来在电价便宜的时段提前把空调温度调低到24℃让整个建筑结构“存”进去更多冷量这部分冷量可以在后续温度回升时释放相当于“充电”。一模一样的热力学循环站在电网角度就是储能行为。为了把这个物理过程数学化我采用一阶等效热参数模型Equivalent Thermal ParameterETP这是建筑热动态建模最常用的方法C_eq * dT_room/dt (T_out - T_room) / R_eq Q_AC Q_other其中 C_eq 是楼宇等效热容kWh/℃R_eq 是等效热阻℃/kWQ_AC 是空调供给的冷量kW制冷时为负值Q_other 是人员、设备等内部产热kW。把上面的微分方程用一阶差分近似就能得到离散化的室内温度递推关系。每个调度时段直接算室温并把室温区间映射成空调功率约束。这个模型只有两个聚合参数C_eq 和 R_eq通过历史温变数据就能辨识出来工程上非常实用。3.2 温度区间换算成虚拟储能的功率上下限虚拟储能和物理电池的对应关系我整理成这张表建模的时候可以对照着用物理储能元素虚拟储能对应概念映射关系电池容量kWh室内温度允许波动范围内的蓄热量ΔQ C_eq * ΔT_max充电功率上限kW空调满功率制冷时的用电增量P_cool_max - P_base放电功率上限kW空调停机/最低功率时少用的电量P_base - P_cool_minSOC状态室内温度相对设定下限的水平T(t) 归一化到 [0,1]自放电率楼宇自然散热速率1/(R_eq * C_eq)室内温度允许的波动区间就是虚拟储能的“荷电状态”边界。比如某楼宇的舒适区是24℃到28℃目标温度26℃那这个虚拟储能的可调度范围就是正负2℃对应的蓄冷量。虚拟储能的调节功率上限是动态变化的——温度离边界越远空调能提供的调节功率越大离边界越近调节能力越小。这跟物理电池SOC不同物理电池的功率上限基本恒定虚拟储能则是状态相关的。建模时我把这个逻辑写成一个与温度相关的不等式约束而不是简单地设一个固定最大功率。3.3 热舒适度的惩罚机制免费储能不是真的免费虚拟储能能提供调节容量但不等于可以无限调用。如果把室内温度压到舒适区边缘甚至超出舒适区就会造成用户体验下降。为了在优化模型里体现这一点我给温度越界引入惩罚项放进目标函数。具体做法是引入两个非负松弛变量 ε_cold(t) 和 ε_hot(t)把室内温度约束从严格不等式放宽为软约束T_min - ε_cold(t) ≤ T_room(t) ≤ T_max ε_hot(t)目标函数里增加惩罚项λ_temp * [ε_cold(t) ε_hot(t)]。这个 λ_temp 的取值很关键——设置太小求解器会肆无忌惮地牺牲舒适度换经济性设置太大虚拟储能的调节能力几乎不会被使用优化退化成普通微网调度。实操中我一般从电价的2到5倍开始试然后根据舒适度越界时长迭代调整。这部分调参经验我放在后面专门讲。4. 优化调度模型的完整数学表达目标函数与约束体系的构建在设备模型和虚拟储能模型都准备好的基础上接下来就是组装完整的优化调度数学模型了。我这里采用的是混合整数线性规划MILP框架——把非线性的部分做线性化处理能确保用商业求解器在合理时间内求到全局最优解。4.1 目标函数设计不止是成本最小化楼宇微网调度的目标函数如果只写“购电成本最小”会显得过于单薄。在碳排放约束日益严格的背景下运行成本、电池老化成本、以及舒适度惩罚这三项需要同时放进目标函数。我的写法如下min Σ(t1→T) [ C_grid(t) * P_buy(t) - C_sell(t) * P_sell(t) ] Σ C_fuel(t) * P_gas(t) Σ C_bat * [P_ch(t) P_dis(t)] Σ λ_temp * [ε_cold(t) ε_hot(t)]每一项的含义分别是电网交互成本从电网买电的成本减去向电网卖电的收益。采用分时电价时C_grid(t) 是时间的函数这就天然驱动了负荷从高价时段向低价时段转移。燃气轮机燃料成本如果楼宇配备燃气轮机或微型燃气轮机燃料成本按出力比例折算。如果没有可控机组这一项可以删掉。电池老化成本充放电功率乘以单位老化成本系数目的是避免调度策略过于激进地使用电池影响寿命。这个系数的物理意义是“每充放1 kWh电池折损成本多少钱”需要根据电池的投资成本和循环寿命来估算。舒适度惩罚项这是虚拟储能建模的核心灵魂前面已经讲过。4.2 运行约束体系的完整清单整个约束体系我拆成六类每一类都有明确的物理含义写代码的时候也能一一对应功率平衡约束在任何时刻电源出力之和必须等于负荷消耗之和误差通过电网交互来平衡。这是微网调度最基本的等式约束包含了光伏出力、机组出力、电池充放电、电网买卖以及所有负荷。电网交互约束通过PCC点的交换功率有两个限制——从电网买电不能超过变压器容量上限向电网倒送电也不能超过允许的上限。并且同一时刻不能既买电又卖电。这个约束跟电池不能同时充放电在本质上是同一种逻辑。机组运行约束可控机组的出力上下限、爬坡速率、最小启停时间。MILP里爬坡约束用相邻时段出力差值的上限来实现。物理电池约束充放电功率上下限、充放电互斥约束、SOE递推方程、以及调度周期末的SOE恢复约束——调度结束时的电池电量必须回到与初始状态相同否则前一天“吃光”的电池电量会让后一天无电可用这在连续调度场景下会引发问题。虚拟储能也有类似的恢复逻辑我在后面展开。虚拟储能约束室内温度的递推方程、温度上下限、空调功率上下限。这里需要特别注意虚拟储能和物理电池最大的区别在于电池的SOE恢复可以精确写一个等式约束而虚拟储能要恢复的是室内温度——我设置为调度结束时室内温度回到初始设定值这样就能让系统在完整调度周期内“净蓄冷量为零”这等价于虚拟储能的能量守恒。刚性负荷约束刚性负荷是固定不可变的参数量不产生决策变量。但要注意在功率平衡等式里刚性负荷数值不能为负如果出现负值意味着这个楼宇在向电网供电这不符合刚性负荷的定义属于数据错误。4.3 求解策略选择与Yalmip集成模型写完之后接下来是把数学模型转换成Matlab可以调用的格式。我的首选工具组合是 Yalmip Gurobi。Yalmip的建模语言非常贴近数学表达能大幅度减少把行文公式翻译成代码的精力消耗Gurobi的MILP求解速度和数值稳定性在同类商业求解器里是公认的好。有些研究论文选择用Matlab自带的linprog或者intlinprog求解优点是环境要求低不用额外装工具箱但求解规模变大之后intlinprog的表现确实不如Gurobi稳定特别是面对包含大量二元变量和连续变量的混合整数问题时Gurobi的branch-and-cut实现效率明显更高。如果读者有Cplex或者SCIP经验替换起来也很容易因为Yalmip对不同求解器的调用方式是一致的。5. Matlab代码实现从零开始搭建调度框架这部分是全文的重头戏我直接把代码架构和关键片段拿出来逐段解释设计意图。完整的代码框架包括数据准备脚本、模型构建函数、求解与结果输出脚本三个部分。5.1 输入数据结构的组织方式我习惯把整个系统的参数封装成结构体数组这样调用起来逻辑清晰、不会在函数传参时出现漏传错传的问题% 系统基础参数定义模块 sys.T 24; % 调度时段数日前调度按小时计 sys.dt 1; % 时段时长单位小时 sys.pv [0,0,0,0,0,0,0.8,2.5,4.2,5.5,6.0,6.2,5.8,5.0,4.0,3.0,2.0,1.0,0,0,0,0,0,0]; % 光伏各时段出力预测kW sys.load_fixed [12,11,10,9,9,10,18,30,45,52,56,58,55,50,52,55,60,65,70,68,60,45,30,20]; % 刚性负荷kW sys.price_buy [0.35,0.35,0.35,0.35,0.35,0.35,0.5,0.8,0.8,0.8,0.8,0.8,0.5,0.5,0.8,0.8,0.8,0.8,0.8,0.8,0.5,0.35,0.35,0.35]; % 分时购电价元/kWh sys.price_sell 0.3 * ones(1,24); % 上网售电价元/kWh sys.PCC_max 100; % 与配电网交互功率上限kW实际项目中这些数据来自楼宇的能量管理系统历史数据库。一套真实的数值可以检验模型的有效性在验证阶段用一组虚构但量级合理的数据也足够预报求解器的表现。5.2 Yalmip模型构建的核心代码片段变量定义部分我特别注意把二进制变量与连续变量的作用范围圈清楚为的就是避免求解难度失控% 决策变量定义 P_buy sdpvar(1, sys.T, full); % 从电网购电功率连续变量 P_sell sdpvar(1, sys.T, full); % 向电网售电功率连续变量 P_ch sdpvar(1, sys.T, full); % 电池充电功率 P_dis sdpvar(1, sys.T, full); % 电池放电功率 SOE sdpvar(1, sys.T1, full); % 电池能量状态 T_room sdpvar(1, sys.T1, full); % 室内温度虚拟储能核心状态量 u_ch binvar(1, sys.T); % 电池充电状态指示二进制变量 u_dis binvar(1, sys.T); % 电池放电状态指示二进制变量 u_buy binvar(1, sys.T); % 电网购电状态指示 u_sell binvar(1, sys.T); % 电网售电状态指示这里二进制变量的数量决定了MILP问题的规模。24个时段 × 4组二进制变量总共96个对Gurobi来说相当轻松。如果把空调群的每台设备都用独立变量来建模二进制变量数量会上升到数百甚至上千个求解时间就不是秒级能描述的事了。约束构建部分我按类别用不同的代码块来添加这样调试哪个模块出问题一目了然% 功率平衡约束微网的核心等式约束 Constraints []; for t 1:sys.T Constraints [Constraints, ... P_buy(t) - P_sell(t) sys.pv(t) P_dis(t) P_gas(t) ... sys.load_fixed(t) P_ch(t) P_ac(t) P_flexible(t)]; end这里整个功率平衡对任何时刻都成立包括光伏不出的夜晚。P_ac是我给中央空调单独留的决策变量P_flexible是热水器充电桩这类可平移负荷的聚合变量。虚拟储能的温度递推约束是整段代码里最体现建模功力的一部分% 虚拟储能/室内温度动态约束 C_eq 120; % 楼宇等效热容单位kWh/℃ R_eq 0.8; % 楼宇等效热阻单位℃/kW T_out [26,25,24,23,22,21,23,26,28,30,31,32,33,34,34,33,32,31,30,29,28,27,26,25]; % 室外温度 T_room_init 26; % 初始室内温度 lambda_temp 5; % 舒适度越界惩罚系数 for t 1:sys.T Constraints [Constraints, ... C_eq * (T_room(t1) - T_room(t)) ... (T_out(t) - T_room(t)) / R_eq * sys.dt ... P_ac(t) * 2.5 * sys.dt 5 * sys.dt]; end这个递推式的物理含义是室内温度的变化量 围护结构传热量 空调供冷量 内部产热量。其中P_ac乘以2.5的系数是空调电功率到制冷量的能效比COPCoefficient of Performance一般空调COP在2.5到3.5之间。内部产热我按5kW固定值处理实际项目中可以用人员密度和照明功率密度估算。温度上下限和舒适度越界惩罚的代码% 虚拟储能温度边界约束含松弛变量 epsilon_cold sdpvar(1, sys.T, full); epsilon_hot sdpvar(1, sys.T, full); T_min 24; T_max 28; for t 1:sys.T Constraints [Constraints, ... T_min - epsilon_cold(t) T_room(t1) T_max epsilon_hot(t)]; Constraints [Constraints, epsilon_cold(t) 0, epsilon_hot(t) 0]; end % 空调功率上下限 P_ac_min 5; P_ac_max 30; for t 1:sys.T Constraints [Constraints, P_ac_min P_ac(t) P_ac_max]; end5.3 求解与结果输出的处理技巧求解调用前我给Yalmip设置了一个求解超时保护防止个别时段系统陷入长时间无解。这在批量跑仿真的时候非常有用不至于程序卡死options sdpsettings(solver, gurobi, verbose, 1, showprogress, 0); options.gurobi.MIPGap 0.01; % 松弛的最优性间隙至1% options.gurobi.TimeLimit 120; % 求解放置于120秒防卡死 optimize(Constraints, Objective, options);关于MIPGap这个参数值得单独解释一句。理论上当然是设0求精确最优但24时段的MILP问题在完全精确求解时可能需要数分钟到数小时不等工程上1%的间隙已经足够好而且调度决策的成本差异在这个精度下基本忽略不计。求解完的后续处理我的习惯是立刻做一致性校验防止出现物理上不可能的调度策略% 求解结果一致性校验 if value(sum(P_buy)) value(sum(P_dis)) 0 value(sum(P_ch)) 0 warning(功率平衡校验未通过请检查约束是否疏漏); end这个校验的含义是如果购电量和放电量都为零但充电功率有值那一定说明功率平衡约束被破坏系统凭空给电池充了电。这种低级错误在大型模型里其实并不少见多一层校验多一分保障。6. 仿真结果解读虚拟储能到底带来了多少价值模型建好后最关键的是回答一个问题引入虚拟储能后楼宇微网的运行成本和负荷曲线到底改善了多少我用三种场景做对比仿真这个对比设计也有讲究——不是简单有没有虚拟储能而是做三个递进式场景才说明问题。6.1 三种场景的对比设计场景配置说明对照目标场景A无储能、无虚拟储能刚性跟随负荷基准线反映最传统调度场景B仅物理储能电池容量300kWh反映传统储能方案场景C物理储能 虚拟储能联合调度反映本文方法的完整价值物理储能和虚拟储能并不是互斥的替代关系联合优化时虚拟储能可以平抑短时波动物理储能处理更长周期的能量搬移两者互补性其实很强。6.2 成本构成与削峰填谷效果分析跑完三种场景先把成本数据拉出来对比指标场景A场景B场景C全天运行成本元217318561721相比基准成本下降比例—14.6%20.8%峰值购电功率kW88.274.562.1峰谷差kW77.561.245.3可以从数据中看到几个信息增加物理储能后运行成本降了14.6%因为电价低谷充电、峰段放电能有效实现套利再加上虚拟储能成本在物理储能基础上又降了约8个百分点达到20.8%。这是因为虚拟储能分担了很大一部分削峰责任物理电池的充放电深度和老化损失都被温和地控制了。看峰值购电功率的数据场景A接近88kW几乎贴着PCC功率上限场景C峰值降到62kW意味着楼宇可以用更小的变压器容量完成同样的供电任务——这涉及容量费每月的电费账单上还能省下一笔不小的基本电费。这个间接收益在优化模型里体现不出来但实际项目中日积月累非常可观。6.3 虚拟储能的工作机理可视化解读把场景C的空调功率曲线和室内温度曲线拉出来能看到一个非常规律的联动现象下午14点到16点电价处于高峰段时空调功率被压低到5kW左右室内温度缓慢上升但始终低于28℃上限——这就是虚拟储能的“放电”过程它把上午“储”在建筑结构里的冷量释放出来傍晚电价回落、光伏几乎为零时空调功率上升室内温度回落到26℃附近——这就是虚拟储能的“充电”过程。换句话说虚拟储能在物理储能动作之前就先动了手用电价差驱动、以建筑热容为载体把系统最贵的电费时段给平滑过去了。我自己跑完这组仿真的感受是虚拟储能不是替代物理储能而是让物理储能的每次充放电都用在刀尖上。电池寿命和调度经济性之间的平衡也因此找到了一条更合理的路径。7. 我在调试这段代码时踩过的坑虚拟储能相关的四个高频问题Matlab里搭优化模型最痛苦的从来不是写代码而是调试——求解器报出来的错误提示有时候跟谜语一样。下面这四个坑是我反复踩过、花了不少时间绕出来的写下来供大家直接避开。7.1 温度递推的单位一致性错误初次建模时我把等效热容C_eq的单位弄成了kJ/℃而空调功率用的是kW结果求出来的温度振荡幅度异常大空调的调度曲线完全不符合物理规律。检查下来发现是单位没有统一1 kW 1 kJ/s1小时就是3600 kJ。如果C_eq用了kJ/℃功率用了kW两边差了一个3600的因子。最后我统一改成“kWh/℃”和“kW”配对递推方程才恢复正常。这是一类非常容易犯错误能量形式变量的单位与功率形式变量的单位之间差了时间量纲做前处理时一定要在数据初始化脚本里检查所有参数的物理单位。7.2 Yalmip求解器报“Infeasible problem”的排查思路模型一迭代约束一多求解器就会报不可行。这时候我以前写的一段“暴力排查法”非常管用先把所有带有二元变量或者状态变量之间的耦合约束注释掉只看功率平衡和上下限约束能不能求解。如果这样都不能解说明基本数据有误比如某个时段光伏出力超过了负荷加PCC上限的总和导致功率盈余无处可去。如果基线能求解、加耦合约束就不可行那大多是虚拟储能的状态变量出了问题要么初始温度设在了舒适区间外要么温度递推方程算出的温度范围超出了边界要么空调功率上下限设置过小导致无法维持温度。我曾在共享空间里看到不少类似的提问结论基本都是最后一个原因——空调功率上限30kW但根据递推方程维持26℃至少需要35kW的制冷功率那无论怎么调度都是不可行的。检查顺序先看边界、再看初始、最后看递推系数。7.3 舒适度惩罚系数的调参问题与优化策略λ_temp 这个参数合不合理判断标准是在极端电价场景下虚拟储能是否使用了全部的舒适度调节范围。如果温度曲线整条都在26℃附近纹丝不动说明 λ_temp 太大虚拟储能的潜力没有被挖掘出来如果温度频繁触及28℃上限或24℃下限说明 λ_temp 太小系统在用过度牺牲舒适度的方式换成本节约。实际操作中我会先用2倍最高电价的数值跑一遍观察温度越界时长如果越界时段占比超过10%就把 λ_temp 提高20%再跑一版如果温度几乎不变就降低20%再跑。这个闭环调试方法比一把一把瞎试要快得多。7.4 虚拟储能与物理储能联合调度时的收敛问题最后一个坑比较隐蔽当虚拟储能和物理储能在同一个优化框架下运行时二元变量数量翻倍MILP的支定界树深度随之增加。有一次我在24时段模型里加入了对电池健康度更细致的约束结果Gurobi在120秒内解出来的MIPGap一直停在8%左右不往下走。后来我检查了目标函数里的电池老化惩罚项系数发现它与其他成本项量级相差三个数量级导致求解器在这个次要目标上浪费了大量分支计算。修正是把老化惩罚系数调到与购电成本同一量级MIPGap很快就收敛到1%以内。这说明MILP问题中目标函数各项的量级均衡性直接影响求解器的收敛速度。这个经验对做大规模调度的朋友应该也有参考价值。8. 从单日调度扩展到实时控制的一些思考这篇博文里展示的模型是日前day-ahead调度框架时间段按小时划分。在实际项目中日前调度做完之后还需要一个日内intra-day滚动修正环节——光伏预测和负荷预测在实际运行中不可能完全与日前预测一致需要通过滚动优化来修正。在做滚动优化时我建议把模型作几个改动第一将时间尺度从小时改为15分钟温度递推方程里的系数△t要从1改成0.25C_eq 和室内温度的关系要重新校核时间分辨率变细后等效热容参数的辨识精度要求会提高。第二引入状态反馈把当前时刻的实际室内温度作为滚动优化的初始条件而不是沿用日前调度的预测温度。这一步是整个闭环控制的核心。第三日前调度得到的空调功率、电池功率作为参考轨迹滚动优化在参考轨迹附近小幅调整不推倒重来。这样既能保持调度策略的稳定性又不会让设备在短时间内频繁动作。关于MPC模型预测控制框架其实和本文的模型天然衔接本文的虚拟储能温度递推方程就是MPC的状态预测模型目标函数和约束可以原封不动搬过去只需要把优化周期从24小时缩短到4到6小时然后按15分钟滚动一次。在我参与过的项目里这种从MILP到MPC的过渡改造量大约是新增一个滚动循环和状态更新接口其余模型结构基本不用动。从纯科研角度本文这套建模方法也可以向两个方向做深度扩展一是把不确定性建模进来比如用场景法处理光伏出力和负荷预测误差做随机优化或鲁棒优化二是把碳流、绿电溯源这些指标放进目标函数实现低碳调度的显式优化。不过这两条路都会带来至少一倍的求解复杂度属于更进阶的话题了有兴趣的朋友可以顺着这篇文章的框架往这些方向推。