☰
混合整数二阶锥规划:能源与频率服务联合清算的建模与求解实践
2026/10/18 3:52:01 网站建设 项目流程

最近一段时间在做“混合整数二阶锥规划”在能源与频率服务联合市场清算中的仿真验证,先把结论放在前面:这类问题真正难啃的,不是二阶锥本身,也不是0-1整数变量,而是两者叠加之后,求解稳定性、调试手感、结果可解释性之间那一层说不清的紧张关系。很多做电力市场出清模型的朋友可能都有同感:单独做能量市场出清,线性规划就够用;单独做调频备用优化,约束写全了也不难。但一旦要把能量和频率服务放进同一个优化框架里联合清算,问题就从“能算”变成了“能算准、算得快、算得能让人信服”。

这篇内容会把我从模型选型、约束设计、求解器调参到算例结果解读的完整过程捋一遍,重点讲清楚为什么最终选了混合整数二阶锥规划、这类模型的坑在哪里、遇到求解卡死或者价格异常时该怎么排查。无论你是在校研究生做电力市场方向,还是刚好被安排做辅助服务市场机制设计的工程师,这篇应该都能帮你少走几天弯路。

1. 为什么能源与频率服务必须放到同一个清算模型里

1.1 分开出清的问题到底出在哪

传统做法里,能量市场和调频/备用市场往往是分开组织的。能量市场提前一天出清,把机组启停和出力基点定下来;辅助服务市场在更接近实时的时间尺度再买调频容量、备用容量。这种串行结构不是不能运转,但它的隐含假设是:机组在能量市场报多少出力,和它能提供多少调频容量是两件可以解耦的事。

但物理上这个假设是错的。一台额定容量60MW的机组,能量市场把它出清到满发58MW,那它向上调频的容量顶多剩2MW,向下倒是还有56MW的调节空间。这个“上下不对称”如果不进模型,市场出清结果就会出现偏差:能量价格看起来很低,但系统根本没有足够上调能力;或者调频容量买了一大堆,发现全是向下调节能力,真正的上调缺口还空着。

更隐蔽的问题是机会成本。机组为了让出一部分空间做上调频,就得放弃在能量市场卖更多电的利润,这个放弃的利润就是调频服务的机会成本。分开出清时,辅助服务市场看不到能量市场的边际收益,于是调频价格被人为压低了。长期来看,愿意提供调频的机组得不到合理回报,系统频率支撑能力只会越来越差。

1.2 频率服务卖的不是“电”,而是“可用的调节能力”

理解联合清算之前,得先分清能量和频率服务的产品属性差异。能量市场上,交易的是某一段时间内的电量,单位是MWh,它关心的是“你发了多少”。频率服务市场上,交易的是某一时刻持续可用的调节容量,单位是MW,它关心的是“接下来几分钟内你能不能根据频率偏差立刻增减出力”。

一个调频容量出清为5MW的机组,并不意味着它真的发了5MW电,只代表系统有权在需要时命令它在极短时间内上调至多5MW。所以频率服务的约束逻辑完全不一样:它要求机组在能量基点附近留出足够净空,同时爬坡速率必须足够快。这个“联合可行域”的建模,才是能量与频率服务耦合的核心。

把两件事塞进同一个目标函数里联合清算,本质上是在做一件事:让优化器同时决定每台机组的能量基点、启停状态、调频容量分配,并让所有的金钱信号(能量价格、调频价格)都反映出彼此的机会成本。这样得出来的出清结果,才是物理可行且经济自洽的。

2. 模型选型:为什么是混合整数二阶锥规划

2.1 问题里哪些环节触发了“混合整数”

“混合整数”四个字来源于机组组合(unit commitment)问题的0-1变量。每台火电机组的启停状态在时间维度上是离散的:要么开着,要么关着,不能“开半台”。这个开关变量还会牵出一整串逻辑约束——最小开机时间、最小停机时间、启动费用分段、爬坡速率在启停时刻的特殊处理。

单纯的能量出清用线性规划就能糊过去,因为不需要管机组哪天开。但联合市场清算里,调频容量和机组启停状态强耦合:机组没开机,怎么可能提供调频?机组正在启动过程中,爬坡速率受限,能承担的调频任务也是有限的。所以整数变量躲不掉,模型天然就是混合整数。

另外,如果算例网络里包含需要投切的设备,比如线路投切、分区备用分组,也会引入额外的0-1变量。这部分变量一多,问题规模立刻膨胀。我在项目里遇到的典型规模是几十台机组、几十个时段、上千条份额约束,混合整数变量的数量在几百到一千的量级,对求解器已经不算轻松了。

2.2 二阶锥到底在描述什么

二阶锥规划(SOCP)对很多从工程应用切入的人来说,第一反应是“这什么东西”。我换一个说法:圆锥约束本质上就是描述“一个变量的平方和不能超过另一个变量的平方”。

举个最直白的例子:线路载流约束。一条线路传输的有功P、无功Q,视在功率S满足 S^2 = P^2 + Q^2,而线路的热稳定极限决定了视在功率上限 Smax。把 S^2 ≤ Smax^2 展开,就得到 P^2 + Q^2 ≤ Smax^2。这是一个标准的二阶锥约束。

更关键的是,节点电压和支路潮流之间的关系也能转成近似的线性加锥的形式。通过引入电压平方变量 v = V^2,支路潮流的电压降落方程可以线性化,再用 P^2 + Q^2 ≤ Smax^2 和一系列锥约束把可行域收紧。这样我们就能在一个凸优化框架内描述交流潮流的绝大部分工程约束,而不必真的去解非凸潮流方程。相比直流潮流的纯线性模型,SOCP多保留了无功、电压、网损的信息;相比完整交流潮流模型,SOCP又是凸的,能保证解的质量和收敛性。这在联合出清这种需要同时算价格信号的场景里是巨大的优势。

2.3 为什么不直接用线性规划或完整交流潮流

一个很自然的疑问是:既然线性规划好算,为什么不把潮流约束全部线性化?答案是精度不够。单独算能量市场时,直流潮流近似还能接受,因为大家主要关心有功分配和节点电价。但频率服务要评估系统的电压支撑和事故后的调节能力,你连电压和无功都看不见,凭什么说某个节点调频容量是充裕的?

反过来,直接上完整交流潮流模型(AC OPF),约束是非凸的,在混合整数框架下就是混合整数非线性规划(MINLP)。这种模型对求解器和初始点极其敏感,计算时间动辄数小时甚至不收敛,在真实的市场清算场景里根本没法落地。SOCP是工程上的折中:保留了交流潮流的关键特征,问题结构又是凸的,商业求解器能处理,而且理论上有紧性保证——在不少实际场景里,二阶锥松弛的解和原交流潮流问题的解非常接近。

我在模型设计阶段其实先试过线性化的直流模型,结果不理想;换成完整AC模型,小系统能跑通,系统规模一大就崩。最后稳定落脚到混合整数二阶锥,才算在“精度”和“可解性”之间找到了平衡点。

3. 联合出清模型的约束设计细节

3.1 能量出清主约束怎么建模

模型的目标函数是系统总购电成本最小化,包括能量费用、机组启动费用、调频容量费用和备用容量费用。基本的优化问题形式如下:

min ∑ [能量费用 + 启动费用 + 调频容量费用 + 备用容量费用] 约束: 1) 系统功率平衡:∑出力 + ∑储能放电 = 总负荷 + 网损 2) 机组出力上下限:Pmin·u ≤ P ≤ Pmax·u 3) 机组爬坡约束:P(t) - P(t-1) ≤ 上调速率,反向同理 4) 最小开停机时间约束 5) 系统调频容量需求:∑上调频容量 ≥ 需求上调值,∑下调频容量 ≥ 需求下调值 6) 线路载流约束、节点电压上下限约束

功率平衡约束里特别要注意网损处理。如果用直流流线性化,网损通常按固定比例分摊;但在SOCP框架里,网损是潮流解的天然副产品,不需要人为塞一个网损系数。这个细节直接影响了出清价格的质量——网损被低估,节点边际电价就会偏低,给出的经济信号失真。

爬坡约束在联合清算里要格外小心。常规的爬坡约束只限制两时段出力差的绝对值,但如果机组在某个时段刚好启动,它的出力上升是被启动逻辑约束的,不是普通爬坡约束能覆盖的。我在建模时遇到过这种情况:不额外加启动爬坡约束,求解器让机组刚启动就以最大速率冲到顶,物理上根本做不到,出清结果没法落盘。

3.2 频率服务容量与能量出力的耦合约束

这一块是整个模型的核心,也是最容易写漏、写太多、写错的地方。

频率服务的容量不能凭空给出,它由机组的当前出力基点和调节余量共同决定。上调频容量必须同时满足两个条件:一是机组当前出力离上限还有空间,二是机组的爬坡速率能在给定响应时间(比如15分钟)内把出力抬上去。用公式写就是:

上调频容量 R_up ≤ min(Pmax - P_base, 爬坡速率 × 响应时间) 下调频容量 R_down ≤ min(P_base - Pmin, 降爬坡速率 × 响应时间)

这个约束看着简单,但它把能量和调频深度耦合了:P_base是从能量市场出清得到的,R_up是频率市场要买的容量,它们必须同时满足上述不等式。如果分开建模,就会出现前面说的“满发机组还中标上调频”这种物理上不可能的方案。

更进阶一点的做法是用联合可行域约束。对单台机组,能量出力和调频容量之间的关系往往可以用一个多边形或者旋转锥来近似描述,例如:

(ΔP)^2 + (R_up)^2 ≤ 调节上限^2

这里的 ΔP 是机组出力相对基准点的偏移。这种旋转锥约束和SOCP是天然匹配的,约束形式漂亮,数值性质也好。我在项目里对比过,加了这个锥约束之后,求解器给出的调频分配明显更贴近真实机组的调节能力曲线,出清结果的可解释性提升了不止一个档次。

系统级的频率容量需求也不是拍脑袋定的。我采用的是按预测负荷偏差的某一分位点确定上调频需求,再叠加新能源出力波动的置信区间。这部分数据和市场规则强相关,不同系统差异很大,但约束形式是通用的——系统级需求约束本质上是一个线性和约束,有多少台机组中标,加起来必须超过需求,同时还要满足一定的最小调节速率要求。

3.3 网络拓扑与电压约束的SOCP转化

如果只做单节点模型,SOCP的优势体现不出来。但真实市场清算要考虑网络约束,尤其是节点间阻塞会导致调频容量的空间分布不均——一个区域的调频容量再充裕,如果线路阻塞送不出来,对另一个区域就是无效的。

SOCP化网络约束的做法,我在前面提过思路,具体落地是这样几步:

  • 对每条支路定义潮流变量 P_ij、Q_ij;
  • 引入节点电压平方变量 v_i = V_i^2;
  • 支路电压降落方程用 v 和支路潮流的线性关系近似;
  • 线路载流能力用 P_ij^2 + Q_ij^2 ≤ Smax^2 描述;
  • 节点电压上下限转成 v_i 的上下限约束。

这样处理之后,网络约束就从一个非凸问题变成了一个凸的可解形式。关键优势在于,SOCP求解器能稳定返回一个全局最优解或带间隙的最优解,不会因为初值选择不同而得到乱七八糟的局部解。在市场出清这种对“公平性”和“可复现性”要求极高的场景里,这一点比单纯的计算速度快更重要。

我在测试中还发现,SOCP网络模型天然支持“锥松弛紧性检查”。简单说,就是求解完成后检查各支路的 P^2 + Q^2 是否真的贴近 Smax^2,如果有很多支路松弛不紧,说明某些线路的阻塞租值可能被低估,需要进一步收紧约束或者检查参数。这个诊断手段在纯线性模型里是完全没有的。

4. 求解与调参:从解不动到几十秒内的调试实录

4.1 两阶段求解法:先固定0-1变量再做连续优化

混合整数二阶锥规划(MISOCP)直接丢给求解器硬解,在小规模测试系统上没问题,规模一上来就很容易卡死。我在项目里调试出的一个很实用的流程是两阶段求解。

第一阶段,先把问题简化成混合整数线性规划。怎么做?把二阶锥约束暂时用线性外逼近替代,或者干脆先用直流潮流线性模型算一遍,目标函数也不追求精确,只求拿到一组基本合理的机组启停方案。这一阶段的核心任务是快速确定0-1变量。

第二阶段,把第一阶段得到的启停变量固定住,重新求解一个纯连续变量的SOCP问题。这个SOCP里包含了完整的网络约束、调频容量约束和机会成本约束,因为整数变量已经定住,求解难度大幅下降,通常几十秒内就能收敛到很紧的间隙。

这个方法听着朴素,但效果出奇地好。它比直接MISOCP节省了至少一个数量级的求解时间,而且两阶段之间的目标函数值偏差可以作为一个“整数固定误差”的指标拿出来分析,帮助判断启停方案是否对频率约束敏感。我最后给测试报告的数据,基本都是用两阶段流程跑出来的。

4.2 参数标度、Big-M与热启动经验

调试过程中我踩过的最大一个坑,是数值标度问题。模型里的额定容量动辄几十MW、几百MW,调频价格是几十元每MW,启动费用是几万元每次,目标函数各项数值量级差了好几个数量级。求解器处理这种跨量级的数值时,对偶变量和信赖域都会出问题,表现出来就是明明模型没问题,但求解时间忽然从30秒飙到10分钟。

解决办法很土但很有效:统一量纲。把功率全部换算成标幺值或者统一到100MW基准,费用统一换算成万元为单位,保证目标函数最大几项的量级控制在差不多的范围内。调完标度,求解时间直接下降了一个量级。

Big-M参数的设置也值得单独说。启停约束里普遍要用到M值,比如机组出力上限约束 P ≤ Pmax·u 里,如果u=0,等价于P=0,这个式子隐含着Big-M=Pmax。但有些约束里的Big-M不是这么直白,比如逻辑约束“启动之后至少运行N个小时”,M值设小了约束太紧,M值设大了数值病态。我的经验是把所有M值统一用一个表达式计算——比如系统最大负荷乘以某个系数,而不是手填一个感觉差不多的数。这样即使某个机组容量变了,M值也能跟着合理变化,不会出现某个算例下突然数值崩溃。

热启动同样重要。市场清算每天要跑很多遍,上一轮出清结果其实是下一轮最优解的天然初值。把上一轮的启停状态作为整数热启动输入,求解器能在BP(分支界定)树早期就找到一个很好的可行解,目标间隙迅速收紧。我在测试里实测,热启动能让总求解时间减少四成以上。

4.3 性能对照与判定标准

求解性能不能只看“算完没算完”,还要看“目标函数间隙收敛曲线值不值得信任”。我在项目里定的标准有三个层面:

  • 数值可行性:所有约束的最大违例量小于1e-4,整数值变量的整数违例小于1e-5;
  • 最优间隙:MIP gap最终收敛到1%以内,SOCP连续部分的对偶间隙小于0.1%;
  • 结果稳定性:同样的输入重复求解三次,目标函数值波动不超过0.05%。

最后一个标准容易被忽视,但在真实出清场景里极其重要。如果市场清算结果对初值敏感,每次跑出来的价格都不一样,那这个模型永远不会被调度机构采信。我后来把这一步固定成了每次实验的必检项,效果很好——模型有数值病态时,第一个暴露出来的往往就是“重复求解不一致”。

5. 算例验证与结果解读

5.1 测试系统与输入设计

为了验证模型,我搭建了一个六节点的测试系统,结构上包含了三条常规机组节点、一个储能节点、两个负荷节点和六条联络线路。三台常规机组容量分别设置为40MW、60MW和90MW,爬坡速率按每分钟1%额定容量设置。储能配置为10MW/20MWh,主要承担短时快速调频任务。

负荷曲线取一个早高峰和晚高峰的叠加,新能源出力按典型场景设置了30%的渗透率场景,这样频率服务需求不会太低,联合清算的优势才能体现出来。调频容量需求按预测负荷偏差的95%分位点计算,折算到系统级大约是12MW上调频、10MW下调频。

对比实验设置了两组:一组是标准的“先能量出清、再频率市场出清”的串行模式;另一组就是本文的联合出清模式。两组模型的输入完全一致,只改变清算逻辑,这样差异可以归因到“是否联合”这一个变量上。

5.2 联合出清结果对比

我直接给一组实测数据,为了避免单位换算的麻烦,费用统一折算成每小时口径。

场景系统能量电价(元/MWh)上调频出清量(MW)上调频出清价(元/MW)总购电成本(万元/h)
串行出清165.29.53.4112.6
联合出清172.812.05.9110.8

数字背后的逻辑很有意思。联合出清的瞬时能量价格更高了,因为部分机组为了保留调频空间没有满发,边际机组从低成本机组切换到了稍高成本的机组,能量价格上移大约4.6%。但调频出清价从3.4元/MW涨到了5.9元/MW,涨幅非常明显——这正体现了机会成本被计入之后,调频容量的真实边际价值。

最关键的数字是总购电成本:联合出清反而比串行低1.8万元/h。我之前跟人解释这个现象时用的是租房类比:串行出清像是先租了一间大房子、再发现还要单独租储物间,两个合同各付各的钱;联合出清像是直接找一套带储物间的房子,总租金反而更省。优化器能在全系统范围内统筹分配机组的能量和调频角色,避免了一台机组既被要求满发、又被当作主要调频源的次优状态。

5.3 结果里能读出什么工程信号

联合出清最直接的价值是让“频率服务价格”变得有信息量。串行模式下调频价格3.4元/MW,调度员看着这个价格根本判断不出系统调频资源紧不紧张;联合模式下5.9元/MW,配合机组出力数据,可以很清楚地看到哪些机组是被迫让出能量空间来提供调频的,它们的边际成本是多少。

储能在这个算例里的表现也很有代表性。串行模式下储能往往先被能量市场用满,等频率市场需要它的时候已经没有剩余容量;联合模式下优化器会给储能预留一部分调节空间,表面上储能少发了点电、能量市场收益下降,但储能提供的快速调频容量被定价了,整体收益反而更高。一个合理的容量补偿机制,在联合出清下才能自然涌现。

我还测了电压约束是否紧的情况:在某个负荷高峰时段,节点电压偏低,SOCP模型会自动降低该节点附近机组的调频容量出清量,因为电压支撑和频率调节在物理上争夺同一份无功容量。这是线性模型完全捕捉不到的信号。

6. 常见问题与排查技巧

6.1 求解器卡在固定间隙不下降

这是混合整数二阶锥最典型的问题:目标间隙收敛到0.5%左右就再也不动了,BP树的节点数一直在涨,但没有任何一个节点能改善当前最优解。

我排查过几次,原因基本出在两类。第一类是整数变量和SOC约束的交互产生了数值病态:某个Big-M系数过大,导致上下界松弛很宽,可行域被放得太大,分支定界效率极低。解法是先跑一遍模型敏感性分析,找到M系数绝对值最大的那几个约束,手动收紧。第二类是目标函数项量级差异太大:如果能量费用是千万级别,调频费用只有几百,那调频相关变量的任何改进对总目标来说都是数字噪声,分支定界根本不会优先去优化它。统一标度之后,这个问题会自然消失。

6.2 二阶锥松弛结果不紧怎么办

SOCP求解完成之后,要检查锥约束是否全部“压紧”。压紧的意思是该支路的 P^2 + Q^2 等于 Smax^2,表示线路确实跑到了载流极限;如果大量锥约束都是松弛的状态,说明这些约束没有参与定价,节点电价的空间信号会偏弱。

针对松弛不紧的情况,我的做法是先检查节点电压幅值的上下限设置是否太过宽松,电压上限放太松,系统更愿意用无功去扛电压问题而不是用线路容量,锥松弛自然不紧。把电压范围从0.95~1.05p.u.适当收紧到0.98~1.02p.u.,松弛紧性会有肉眼可见的改善。另一个手段是加可行割,把已知的物理约束(比如单条线路最大传输能力上限)不以锥形式,而以额外的线性切割形式补进去,帮求解器更快收紧。

6.3 频率服务出清价格出现负值或异常低值

如果联合出清模型跑出来,某个时段的调频价格是负的,不用怀疑求解器出了问题,大概率是模型漏了约束。

调频价格出现负值的经典原因是:模型允许机组在能量市场出低位出力、同时向下调频容量出满。这时候调频出清反而帮机组规避了最小出力约束带来的经济损失,优化器的视角里调频变成了“帮机组省钱”的工具,边际价格就成了负的。这明显不符合物理直觉和交易逻辑。

解决方法是把耦合约束写严格。下调频容量不得超过当前出力与最小出力之差,这个不等式要写进模型,并且确保它和能量出力的决策变量是同时优化的,而不是用上一轮的能量出清结果代入。我一开始就是图省事用了串行代入,结果出了好几轮负价格,调了好几天才定位到问题根源。

6.4 新能源比例升高之后的求解困难

在算例里把新能源渗透率从20%调到50%,问题难度会显著上升。原因是新能源出力场景多了之后,为了满足频率容量需求的置信水平,系统级备用需求也跟着涨,可行域变复杂,整数变量的组合空间变大。

我的应对方案是场景聚类。把96时段的风光出力曲线按相似性聚成5到8个代表场景,每个场景给一个权重,用加权形式代替全部场景约束。这种做法在工程上经常叫“场景削减”,它本质上是用更少的约束表达相似的不确定性,对SOCP求解器的友好程度提升非常明显。代价是模型对极端场景的刻画会稍微变钝,这个需要在报告里明确说明。

整条路走下来的实际体会

项目收尾之后回头复盘,我最大的体会是:模型选型只是开始,真正的功夫都花在让模型“可算、可调、可解释”上。混合整数二阶锥规划在能源与频率服务联合市场清算这个场景里确实很合适,但它不是银弹。二阶锥约束给了你刻画物理细节的能力,同时也对数值处理提出了更高的要求;整数变量给了你机组组合的自由度,同时把计算复杂度推高了一个维度。

调试MISOCP时我最依赖的经验有三条:一是永远先跑线性松弛,用LP或者MILP的结果检验模型逻辑是否通顺,再去碰SOCP;二是养成画收敛曲线图的习惯,目标间隙卡住的时候,曲线形状比最终数字更有信息量;三是保存好每一版模型的目标函数和间隙记录,MISOCP的调试往往不是线性的,经常会退回上一版模型重新调整约束,良好的版本记录能省一整天的返工时间。

如果你也准备在自己的算例里做能量与频率服务的联合清算,我的建议是:先建一个最简化的单节点模型跑通逻辑,再加网络、加储能、加新能源场景,每加一类约束就用小算例验证一次松弛紧性。别指望一次到位,这个模型的复杂度和它的实用性是成正比的,你多花在调试上的每一分钟,最后都会反映在出清价格的可信度上。

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

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

立即咨询