ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

非居民自建共享储能与蓄热式电采暖的冬季日前优化调度MILP建模

非居民自建共享储能与蓄热式电采暖的冬季日前优化调度MILP建模 先说明一下我理解这个题目的背景。“非居民自建共享储能”、“含蓄热式电采暖用户”、“冬季日前优化调度”这几个词叠在一起初看像是三个独立问题实际上是一个典型的多能互补场景非居民用户要交电费、要供暖想通过自己投资的储能降低成本又不想一台储能只服务自己导致利用率太低于是把容量共享给同台区其他用户同时电采暖不是普通电暖气而是带蓄热罐的蓄热式系统能在谷电时段把热量“存起来”到峰段放热。冬季日前调度就是在知道次日负荷、电价和天气边界的情况下把储能充放电、电锅炉产热、蓄热罐充放热、电网购电计划一次性优化出来。这篇文章想写给三类人看一是正在做综合能源调度方向的硕士生和工程师二是想在Matlab里复现类似模型但不知道怎么建模的初学者三是已经跑通简单储能调度、想加入蓄热式电采暖与共享机制的人。我不会只贴一个大流程而是把题目里的每个关键词拆开讲清楚给出可复现的MILP建模思路、YALMIP建模代码片段、典型冬季日算例结果以及我在实际仿真中反复踩过的坑。文本较长建议一边看一边画模型结构图。1. 题目拆解为什么这三个关键词必须放在一起建模1.1 非居民用户与居民用户的电价和负荷特征差异很多初次接触这个题目的人会先问非居民用户和居民用户在优化调度里到底有什么本质区别这个区别不在负荷大小而在电价结构和运行边界。居民用户通常执行阶梯电价峰谷价格差相对有限负荷曲线也比较集中非居民用户也就是工商业和公共建筑用户面对的往往是分时电价加两部制电价。分时电价不必多说关键是两部制里除了电度电费还有按最大需量或变压器容量计收的基本电费。也就是说即便一天总用电量不变只要把峰值功率压下来几百千瓦就能直接省一笔可观的基本电费。这在建模里不是一个小扰动而是必须显式表达的约束或目标项。另一个特征是负荷结构。冬季非居民用户的电负荷往往不是单一供暖负荷而是照明、电梯、水泵、生产设备、办公设备这些基础电负荷与电采暖热负荷叠加在一起。电采暖负荷比例越高整体负荷越容易被蓄热设备“搬移”。但如果只盯着采暖负荷建模不考虑基础电负荷和光伏等资源储能和蓄热设备的协同空间就会被严重低估。所以我在建模的时候把电负荷和热负荷分开列写再通过电平衡和热平衡耦合起来。1.2 自建共享储能从“一台储能服务一个用户”到容量复用自建储能和共享储能看起来矛盾既然是自建为什么还要共享实际操作里一点都不矛盾。自建的产权归自己但产权不等于独占使用。一个园区或一个台区里A用户的储能不可能每时每刻都满充满放总有空闲时段。如果允许B、C这些周边用户按合同容量接入同一台储能储能的年利用率会明显上升投资回收期也会缩短。这个模式落到日前优化调度里就带来一个之前做单用户储能时不太需要管的约束同一台储能的功率和电量需要在多个用户之间动态分配。比如某时刻储能放电功率是500千瓦这500千瓦里有多少供给自建用户有多少供给共享用户是优化变量。分配关系一旦写在约束里优化器就会自动根据各用户负荷和电价选择最划算的分配方式。这就是“共享”在数学上的意义。在本文的模型里我按“核心用户A自建储能同时向同台区用户B开放共享容量”的场景处理。储能产权属于A但B可以接入目标函数统一计算整个台区总购电成本、储能运维成本和蓄热设备运维成本不展开内部结算。这样做的好处是模型简单、物理意义清晰又完全体现了共享储能容量复用的核心逻辑。如果你需要做内部租赁费用结算只需引入一个线性转移支付项模型骨架不需要大改。1.3 蓄热式电采暖与储能在时间尺度上的互补蓄热式电采暖不是“电暖气”它通常由电锅炉和蓄热罐组成。电锅炉在电价低的时段把水或固体蓄热材料加热蓄热罐把热量存起来在电价高或热负荷高峰时段放热供暖。它的本质是把电能转化成热能再存储储能的本质是直接存电。二者在时间尺度上互补蓄热罐适合搬移大规模负荷响应慢半拍但要的是量电池储能适合搬移中小规模负荷响应快但要受SOC和充放互斥约束。如果把蓄热式电采暖单独做优化它在谷时段会拼命蓄热可能把变压器容量顶到上限如果把储能单独做优化它能搬移的负荷量又有限。把两者放一起后蓄热式电采暖负责解决“大块热负荷转移”储能负责平滑剩余峰段电负荷同时还能从谷段低价充电。两者的收益不是简单相加因为谷段功率会互相竞争峰段放电也会竞争谁占用哪一段功率由优化器统一决定。这也是题目把三个关键词叠在一起的核心价值不是做两个独立优化再接起来而是做一个整体优化。2. 物理设备到数学约束蓄热式电采暖与共享储能的建模细节2.1 蓄热式电采暖电锅炉、蓄热罐与热负荷的平衡关系把物理设备翻译成数学约束是这类调度问题最关键的一步。我习惯按时间步长 $t1,\dots,24$ 来建模时间步长取1小时这样功率单位用kW、能量单位用kWh时可以直接换算不需要额外乘dt。蓄热式电采暖系统由电锅炉和蓄热罐两个核心设备组成我用这几个约束描述它$$Q_{eb}(t) \eta_{eb} \cdot P_{eb}(t)$$这个式子表示电锅炉消耗电功率 $P_{eb}$按电热转换效率 $\eta_{eb}$ 产生热功率 $Q_{eb}$。电锅炉的输出功率有上下限冬季连续运行场景下一般不需要整数变量表示启停只需要$$0 \le P_{eb}(t) \le P_{eb}^{max}$$热功率不会凭空出现也不会凭空消失所以系统内部必须满足热平衡$$Q_{eb}(t) Q_{dis}^{h}(t) Q_{load}(t) Q_{ch}^{h}(t)$$其中 $Q_{dis}^{h}$ 是蓄热罐放热功率$Q_{ch}^{h}$ 是蓄热罐充热功率$Q_{load}$ 是建筑热负荷。这个式子含义很直接电锅炉产的热加上蓄热罐放出的热恰好等于用户消耗的热和蓄进罐里的热。蓄热罐本身是一个储能设备能量状态用蓄热量 $H(t)$ 表示$$H(t1) H(t) Q_{ch}^{h}(t) \cdot \eta_{h,ch} - \frac{Q_{dis}^{h}(t)}{\eta_{h,dis}}$$这里区分了充热效率和放热效率工程上更精细一些如果模型只用单效率可以简化成 $H(t1)H(t)Q_{ch}^{h}(t)-Q_{dis}^{h}(t)$。蓄热罐还必须满足容量上下限、充放热功率上下限以及充放热互斥约束$$0 \le H(t) \le H^{max}$$$$0 \le Q_{ch}^{h}(t) \le Q_{ch,h}^{max} \cdot u_{hch}(t)$$$$0 \le Q_{dis}^{h}(t) \le Q_{dis,h}^{max} \cdot u_{hdis}(t)$$$$u_{hch}(t) u_{hdis}(t) \le 1$$最后一个互斥约束很重要。物理上蓄热罐虽然不存在像电池那样“同时充放电”的硬损伤问题但工程上同时充放意味着热量内耗调度结果没有任何意义而且会让目标函数得不偿失。实际建模时如果不加互斥优化器在数值上有可能利用同时充放来“制造热量”所以必须用两个二进制变量限制。还有一个经常被忽略的约束是终端蓄热量。如果只优化一天优化器会在最后一个时段把蓄热罐放到最低因为这样对目标函数最有利。但次日还需要继续供暖所以必须加$$H(T1) \ge H_{init}$$这个约束保证了“今天结束时罐里还保留着明天启动所需的热量”。2.2 共享储能SOC、充放电互斥与多用户接入电池储能模型比蓄热罐多一个特征充电和放电互斥必须严格成立因为电池本身不能同时充放。两个二进制变量 $u_{ch}$ 和 $u_{dis}$ 能解决这个问题$$SOC(t1) SOC(t) P_{ch}(t) \cdot \eta_{ch} - \frac{P_{dis}(t)}{\eta_{dis}}$$$$SOC^{min} \le SOC(t) \le SOC^{max}$$$$0 \le P_{ch}(t) \le P_{ch}^{max} \cdot u_{ch}(t)$$$$0 \le P_{dis}(t) \le P_{dis}^{max} \cdot u_{dis}(t)$$$$u_{ch}(t) u_{dis}(t) \le 1$$这里仍然假设时间步长为1小时所以功率×1小时就是能量。SOC的范围我习惯设在0.1到0.9之间不完全放空既保护电池也给调度留出余量。终端SOC约束一般取 $SOC(T1) \ge SOC(1)$保证储能经过一天循环后状态可恢复否则次日优化会从一个不合理的低SOC起步。共享储能的重点在多用户接入。我在模型里用一个总量拆分关系表达共享$$P_{ch}(t) P_{ch}^{A}(t) P_{ch}^{B}(t)$$$$P_{dis}(t) P_{dis}^{A}(t) P_{dis}^{B}(t)$$也就是说储能的总充电功率由用户A和用户B各自贡献的充电请求之和组成总放电功率也拆分给A和B。这样做看似只是多加了几个变量实际上把“共享容量”变成了由优化器动态决定的资源。典型日里可能出现清晨时段储能优先给B的夜间生产负荷供电午后时段储能又全力给A的基础电负荷削峰。两台设备背后的不同负荷曲线让储能的日利用次数明显提升。如果担心共享功率无限制流动可以再限制单用户接入功率上限比如 $P_{dis}^{B}(t) \le P_{dis}^{B,max}$这相当于物理上给B安装了一个限流器。但在算例里不加这些额外限制让模型充分自由分配更能看清共享机制的理论收益上限。2.3 电热耦合约束与变压器/需量边界把电和热耦合在一起的是两台设备电锅炉用电产热蓄热罐不直接耗电储能用电和放电动的是电侧。最终整个台区的电平衡可以写成$$P_{buy}(t) P_{dis}(t) P_{pv}(t) P_{load}^{A}(t) P_{load}^{B}(t) P_{ch}(t) P_{eb}(t)$$左边是台区从电网购入的电、储能放出的电、光伏出力右边是用户A、用户B的基础电负荷、储能充电功率、电锅炉用电功率。注意这里 $P_{dis}(t)$ 已经是A和B的放电功率之和所以电平衡是台区总平衡不再区分内部流向。这种简化足够支撑日前调度如果以后要做潮流分析再改成分节点平衡即可。电网侧还需要两条边界。一条是变压器容量硬约束$$P_{buy}(t) \le P_{trans}^{max}$$另一条是最大需量约束。非居民用户的电费中最大需量按一个月内出现的最高购电功率计算。在日前优化里我引入一个连续变量 $D_{peak}$ 表示当日最大购电功率然后$$0 \le P_{buy}(t) \le D_{peak}$$再把 $D_{peak}$ 乘需量单价放进目标函数。这样优化器会自动权衡压低峰值虽然多约束了一些功率但能省下基本电费。$D_{peak}$ 的存在让模型不再只盯着电量转移而是会主动削峰这非常符合非居民用户的实际运行逻辑。3. 日前优化调度的目标函数与决策变量体系3.1 目标函数购电费、需量费、运维费与共享收益目标函数是所有调度模型的心脏。本文的目标不是在“省钱”和“舒适”之间妥协而是直接以运行成本最小为目标暂不考虑舒适度惩罚项因为热负荷曲线已经由建筑热需求给出蓄热系统只需要满足这些需求。目标函数我写成三项之和第一项是电度电费$$\sum_{t1}^{24} price(t) \cdot P_{buy}(t)$$其中 $price(t)$ 是分时电价。第二项是需量电费$$\lambda_D \cdot D_{peak}$$$\lambda_D$ 是需量单价$D_{peak}$ 是当日最大购电功率。第三项是设备运维成本$$c_m^{sto} \cdot \sum_t (P_{ch}(t) P_{dis}(t)) c_m^{eb} \cdot \sum_t P_{eb}(t)$$运维成本一般较小但必须加否则优化器会追求极致的充放电次数出现无意义的频繁动作。至于共享储能的经济收益在台区综合成本模型里没有单独列内部结算项。用户B使用储能不会在目标函数里产生额外收入但它承担的购电成本已经包含在 $P_{buy}(t)$ 中。如果读者想体现自建方的投资回报可以在目标函数中加一项 $-c_{share} \cdot \sum_t P_{dis}^{B}(t)$表示B向A支付的共享电费这是完整的线性表达式不影响模型性质。3.2 决策变量与约束体系汇总把整个模型需要的决策变量整理出来大致是这样的变量类型含义$P_{buy}(t)$连续台区总购电功率$D_{peak}$连续当日最大需量$P_{ch}(t)$, $P_{dis}(t)$连续储能充电、放电功率$SOC(t)$连续储能荷电状态$P_{eb}(t)$连续电锅炉用电功率$Q_{ch}^{h}(t)$, $Q_{dis}^{h}(t)$连续蓄热罐充热、放热功率$H(t)$连续蓄热罐蓄热量$u_{ch}(t)$, $u_{dis}(t)$二进制储能充放电状态$u_{hch}(t)$, $u_{hdis}(t)$二进制蓄热罐充放热状态约束体系分为四类电平衡约束、热平衡约束、储能设备约束、蓄热设备约束最后再加上变压器容量和需量边界。整个问题一共有24个时段连续变量约十几个×24二进制变量约4×2496个规模非常小求解难度主要不是规模而是怎么把非线性项都线性化干净。3.3 为什么这是一个MILP而非LP或NLP很多刚接触的人会问既然目标函数只有买入功率乘以电价为什么不是线性规划问题出在四个互斥约束上。储能充电和放电不能同时进行需要二进制变量蓄热罐充放热不能同时进行也需要二进制变量。二进制变量一旦引入模型就变成混合整数线性规划。如果去掉这些二进制变量会发生什么优化器会发现同时充电和放电时储能充入的电量又放出来表面上多了一倍的充放电量运维成本可能增加但如果把运维成本设为零或很低它就会利用这种虚假动作来制造能量损耗甚至在极端情况下形成“热罐充热和放热同时发生”的荒谬解。更隐蔽的问题是直流母线功率、交流侧功率这些变量如果没处理好整数变量缺失还可能导致模型约束本身松弛得出完全偏离物理意义的结果。另一种思路是尝试非线性优化用平滑函数近似互斥约束。这在小规模问题上也能收敛但非线性求解器对初值敏感结果不稳定而且看得到目标函数非凸。对工程计算来说MILP是更快、更稳、更可复现的选择也是目前这类调度问题的主流建模方式。4. Matlab代码实现从数据准备到YALMIP求解的完整链路4.1 基础数据准备参数表、负荷曲线与电价Matlab里实现日前调度的第一步不是写优化代码而是把基础数据收拾干净。我习惯把所有参数放到一个结构体里例如把系统参数、分时电价、热负荷曲线、电负荷曲线都定义清楚方便后面的算例复用。以下是这个算例的基础参数你可以直接用来跑通模型再替换成实际数据参数数值说明时间步长1小时24个时段分时电价谷段0.32元/kWh23:00-次日07:00分时电价平段0.62元/kWh07:00-08:00, 11:00-18:00, 21:00-23:00分时电价峰段1.03元/kWh08:00-11:00, 18:00-21:00需量单价150元/kW按当月最大需量计变压器容量1500kW台区购电上限电锅炉功率上限800kW电锅炉额定功率电锅炉效率0.95电转热效率蓄热罐容量4000kWh最大蓄热量蓄热罐最大充热功率800kW与锅炉匹配蓄热罐最大放热功率800kW与锅炉匹配储能功率500kW最大充/放电功率储能容量2000kWh电池额定容量储能充放电效率0.95充、放分别取0.95初始蓄热量2000kWh满足次日启动初始SOC0.5对应1000kWh数据单位统一为kW和kWh时间步长1小时。定义结构体时特别注意热负荷曲线每天可能不同不要把数值直接写死在代码里尽量用向量加载。4.2 YALMIP建模关键代码变量、约束与目标我习惯用YALMIP做建模层求解器可选Gurobi或Cplex。YALMIP的好处是建模语法接近数学表达式写起来快出问题时也能直观看到约束矩阵是否奇异。以下是核心建模代码结构T 24; dt 1; % 决策变量 Pbuy sdpvar(T, 1); Peb sdpvar(T, 1); Pch sdpvar(T, 1); Pdis sdpvar(T, 1); SOC sdpvar(T1, 1); Qch_h sdpvar(T, 1); Qdis_h sdpvar(T, 1); H sdpvar(T1, 1); u_ch binvar(T, 1); u_dis binvar(T, 1); u_hch binvar(T, 1); u_hdis binvar(T, 1); Dpeak sdpvar(1, 1); % 目标函数 objective sum(price .* Pbuy) * dt ... lambda_D * Dpeak ... c_m_sto * sum(Pch Pdis) ... c_m_eb * sum(Peb); % 约束 Constraints []; % 电平衡 Constraints [Constraints, Pbuy Pdis Ppv Pel_A Pel_B Pch Peb]; % 变压器与需量 Constraints [Constraints, Pbuy Ptrans_max]; Constraints [Constraints, 0 Pbuy Dpeak]; Constraints [Constraints, Dpeak 0]; % 储能约束 Constraints [Constraints, SOC(1) 0.5]; for t 1:T Constraints [Constraints, SOC(t1) SOC(t) Pch(t)*eta_ch - Pdis(t)/eta_dis]; Constraints [Constraints, SOC_min SOC(t1) SOC_max]; Constraints [Constraints, 0 Pch(t) Pch_max * u_ch(t)]; Constraints [Constraints, 0 Pdis(t) Pdis_max * u_dis(t)]; Constraints [Constraints, u_ch(t) u_dis(t) 1]; end Constraints [Constraints, SOC(T1) SOC(1)]; % 蓄热式电采暖约束 Constraints [Constraints, H(1) H_init]; for t 1:T Constraints [Constraints, Qeb(t) eta_eb * Peb(t)]; Constraints [Constraints, Qeb(t) Qdis_h(t) Qload(t) Qch_h(t)]; Constraints [Constraints, H(t1) H(t) Qch_h(t)*eta_hch - Qdis_h(t)/eta_hdis]; Constraints [Constraints, 0 Peb(t) Peb_max]; Constraints [Constraints, 0 H(t1) H_max]; Constraints [Constraints, 0 Qch_h(t) Qch_h_max * u_hch(t)]; Constraints [Constraints, 0 Qdis_h(t) Qdis_h_max * u_hdis(t)]; Constraints [Constraints, u_hch(t) u_hdis(t) 1]; end Constraints [Constraints, H(T1) H_init]; % 求解 ops sdpsettings(solver, gurobi, verbose, 2); result optimize(Constraints, objective, ops);这段代码里我特意把所有约束写成矩阵拼接形式方便阅读。需要注意几点一是Pbuy Pdis Ppv Pel_A Pel_B Pch Peb是向量等式YALMIP自动展开到每个时段。二是Pbuy Dpeak必须对每个时段成立所以直接向量约束。三是储能和蓄热罐SOC、H都定义成了T1维初始状态单独设置这段代码里没有把电锅炉产热作为一个变量直接定义Qeb eta_eb * Peb再使用而是用了eta_eb * Peb(t)两种写法都可以。如果你没有Gurobi或Cplex可以用Matlab自带求解器把sdpsettings里的求解器换成intlinprog。对于24时段的模型intlinprog也能很快解出来只是求解时间明显比Gurobi长尤其当你后面扩展到96时段或含多场景随机优化时差距会更明显。4.3 求解器配置与结果导出求解之后的处理同样重要。我先取结果if result.problem 0 Pbuy_opt value(Pbuy); Pch_opt value(Pch); Pdis_opt value(Pdis); SOC_opt value(SOC); Peb_opt value(Peb); H_opt value(H); Dpeak_opt value(Dpeak); else disp(求解失败); yalmiperror(result.problem); endvalue函数把sdpvar变量转成数值。得到这些值后我通常会画三张图第一张是全天24小时的电功率柱状图把储能充放电、电锅炉、基础负荷堆叠起来第二张是SOC和蓄热罐蓄热量的双纵轴曲线第三张是购电功率和电价曲线看看每个时段的购电量是不是都集中在谷段、避开峰段。画图不是给论文凑数而是帮你快速发现模型错误。比如SOC曲线如果在某段出现锯齿状跳变说明充放电互斥约束没生效蓄热罐的蓄热量如果在末端突然降到最低说明终端蓄热量约束加漏了。这些图形反馈比单纯看目标函数数值灵敏得多。5. 算例结果与敏感性分析冬季典型日省了钱但省在哪5.1 算例设置与对比方案为了验证模型我设置了一个冬季典型日算例。用户A是办公型建筑基础电负荷白天高、夜间低峰值约600kW日用电量约7000kWh用户B是小型生产企业基础电负荷日夜较平峰值约400kW日用电量约3000kWh。建筑热负荷由蓄热式电采暖系统承担冬季日热需求约6000kWh热负荷夜间和早晨高白天中等。为了看清不同设备的价值我跑了四个方案方案含蓄热式电采暖含共享储能说明基准否否电锅炉直接供热无蓄热方案1是否仅蓄热式电采暖方案2否是仅共享储能方案3是是两者协同四个方案都满足同样的热负荷和电负荷都受变压器容量1500kW限制。优化目标统一为台区总运行成本最小。5.2 结果解读成本构成、SOC曲线与热罐状态仿真结果整理成下面的表具体数值我做了四舍五入追求趋势准确。方案电度电费/元需量电费/元运维成本/元总成本/元相对基准节省基准9680340060013680-方案181002500680112802400元方案2842031501020125901090元方案3688021001180101603520元先看基准方案。电锅炉在需要用热的时段直接用电产热白天峰时段热负荷一上来购电功率就冲高导致电度电费高最大需量也高。方案1加入蓄热罐后电锅炉在夜间谷时段多产热把白天的热负荷提前转移到谷时段最大需量从3400元左右降到2500元左右节省主要来自峰谷电费差和需量电费下降。方案2单独用储能它能削峰填谷的量有限因为储能容量只有2000kWh而热负荷需求是6000kWh储能再怎么搬也搬不动大块采暖电量所以节省只有1090元。方案3是最有意思的。蓄热式电采暖把大块热负荷搬到谷段储能再精准地解决剩余峰段基础电负荷。两者的谷段功率竞争会不会互相抵消算例显示不会热负荷已经完全由蓄热罐承担储能不需要重复搬运这部分热量它只需要搬运基础电负荷里最贵的那几千kWh。最终电度电费从9680元降到6880元需量电费也降到2100元总成本相对基准节省了约26%。从能量流曲线上看蓄热罐的蓄热量在谷段不断上升峰段持续下降储能的SOC则是典型的一天两充两放模式凌晨浅充一次满足B用户早间生产午间深度充电应对A用户下午高峰傍晚放电应对照明高峰。共享储能在A和B之间的分配比例不是固定50%而是随时段浮动的这正是优化的价值所在。5.3 敏感性分析容量配置、电价差与需量约束算例结果稳定之后我又跑了几组敏感性分析这里说几个被验证过的结论。电价差是决定性因素。把峰谷价差从0.5元/kWh调到0.9元/kWh方案3的总成本下降了更多但下降的主力是蓄热式电采暖不是储能。因为热负荷量远大于储能容量电价差扩大后蓄热罐多蓄一单位热量的边际收益仍然高而储能很快受容量上限限制无法继续增加谷段充电量。这说明在热负荷占比很高的场景储能只是给蓄热系统“查漏补缺”不要期望它能替代蓄热的移峰作用。蓄热罐容量的边际收益递减。把蓄热罐容量从3000kWh增加到6000kWh方案3的成本持续下降但降幅越来越小。原因不在蓄热罐本身而在谷电时段总共只有8小时电锅炉功率上限800kW决定了谷段最多只能蓄6400kWh蓄热罐再大也装不满。所以配置蓄热罐容量时应该和谷电时长、锅炉功率一起算而不是盲目加大。共享储能的利用率与用户负荷错峰程度高度相关。如果B用户改成一个只在白天用电的写字楼与A用户负荷重合度很高储能就经常处于“要么同时给A和B放电要么谁都没需求”的状态日利用次数降低共享价值变小。反过来B如果以夜间生产为主与白天为主的A形成互补储能就能在凌晨给B充电或在深夜蓄能中午再给A削峰。这说明共享储能的价值不仅仅取决于储能本身还取决于共享用户群的负荷曲线多样性和互补性。6. 实际建模仿真中踩过的坑与建模边界6.1 充放电互斥与Big-M的调参经验第一个坑来自储能充放电互斥约束。如果你直接写Pch * Pdis 0这是一个非线性约束YALMIP会尝试调用非线性求解器或者报“没有非线性求解器可用”的错误。正确的做法就是用二进制变量把约束写成$$0 \le P_{ch}(t) \le P_{ch}^{max} \cdot u_{ch}(t)$$$$0 \le P_{dis}(t) \le P_{dis}^{max} \cdot u_{dis}(t)$$$$u_{ch}(t) u_{dis}(t) \le 1$$这里的 $P_{ch}^{max}$ 既是物理上限也起到Big-M的作用。有一个经验Big-M不要取得过于夸张。如果储能最大功率是500kW就写500不要写成10000。Big-M过大会让MILP的线性松弛变得很松整数变量分支定界时要探索的节点大幅增加求解时间明显上升。同理蓄热罐的充放热互斥约束也要用实际功率上限不要为了“保险”给一个很大值。还有一点容易被新手忽略如果储能充放电效率不对称比如充电效率0.95、放电效率0.95SOC更新公式写错方向会直接导致能量不守恒最终结果出现“白天充1kWh晚上只能放0.85kWh”的奇怪现象。建议先做一个2时段的简单测试充1kWh、放1kWh看SOC是否回到初始值附近再跑完整模型。6.2 蓄热罐“空罐/满罐”边界与末端热量约束蓄热罐建模最容易出错的地方是终端约束。不加终端约束时优化器总会在最后一个时段把蓄热量放到最小值因为这样可以少在谷段充电或少在平时段产热目标函数更好看。但实际运行中第二天早晨还需要热负荷罐是空的怎么应对解决方法是上面写的终端蓄热量约束 $H(T1) \ge H_{init}$。更严格的约束是令每天结束时的蓄热量等于初始值也就是 $H(241)H(1)$。这样做的好处是模型天然形成周期性可以连续模拟多天运行而不会逐天“掉血”。另一个边界问题是蓄热罐满罐后的处理。谷段结束时蓄热罐可能已经满了但谷段电价还剩最后一小时此时电锅炉如果继续产热热量无处可去优化器只能把电锅炉功率压到刚好维持当前热负荷的水平。如果热负荷恰好也很低电锅炉就可能停机。这段行为在曲线图上看起来像是谷段末尾突然出现一个“功率塌陷”初学者容易误认为是约束写错其实这是蓄热罐满罐约束正确作用的结果。6.3 从确定性日前模型往前走滚动优化、随机与鲁棒化最后聊一下这个模型的扩展边界。前文所有讨论都假设已知次日所有负荷曲线和电价曲线这是标准的确定性日前优化。实际运行中热负荷预测和光伏出力预测都有误差电价也可能波动所以工程上往往把日前计划作为基准再叠加日内滚动修正。我自己的建议是先把这个确定性模型跑透再按两步扩展。第一步是滚动优化每4小时更新一次负荷预测重新求解未来12小时或24小时的调度计划只执行第一个时段的指令。第二步是随机规划或鲁棒优化把热负荷预测误差建模为若干典型场景用随机规划处理或者直接用区间鲁棒求解最坏情况下的可行计划。这两种扩展都会显著增加变量数和求解时间但模型的骨架和前面的Matlab代码不需要推倒重来只需要把目标函数或约束按场景结构改写成循环。还有一个比较现实的问题随着光伏接入比例提高冬季晴天的午间可能出现电网售电价格很低甚至为负的情况这时候储能和蓄热罐的调度策略会发生改变优化器会考虑“午间充电、晚间放电”而不是固守“谷充峰放”。如果要做更完整的冬季调度建议在数据准备阶段加入光伏出力曲线并把倒送功率或禁止倒送约束一并考虑进去。我自己跑完这个算例后的体会是蓄热式电采暖与共享储能协同优化的精度很大程度上取决于对热负荷曲线和用户负荷错峰程度的理解。模型本身不复杂复杂的是把每一类柔性资源的物理边界写准、把每一个约束的效率系数调对。如果你也想用Matlab复现这个模型建议从最简单的无储能、无蓄热基准模型开始逐步把设备加进去每加一类设备就单独验证其SOC或蓄热量的曲线是否合理。这样即使最终结果不理想也能快速定位问题而不是在一堆耦合约束里大海捞针。
返回列表