1. 为什么多能互补系统的优化,不能靠“拍脑袋定权重”
真正把多能互补综合能源系统跑起来之后,你会发现一个问题:那些发表在论文里的调度策略,拿到实际工厂或园区里往往推不下去。原因不复杂——工程项目里几乎没有单一指标说了算的场景。你要控制运行成本,又要盯着碳排放量,还要保证冷热电供应的可靠率,甚至电网侧还会考核联络线功率波动。这些目标之间的冲突是天然存在且不可完全调和的。夏季午后光伏大发、园区冷负荷同时飙高:你让电制冷机全功率吃多余的光伏电,经济性和清洁性都好看,但热泵和吸收式制冷的联动约束可能撑不住;你为了压低运行成本让燃气轮机贴近最小出力运行,碳排放倒是下去了,但余热回收导致的热、冷联供出力又不满足热用户的温度需求。这种相互制约,决定了“把所有目标乘上权重,加成一个数”这种贪快写法,很容易得到一个理论上最优、实际上运行不了的调度表。
这里就是目标规划(Goal Programming)发挥作用的地方。目标规划的核心逻辑不是“找一个唯一的路走到黑”,而是“先把约束和系统底线守住,再在实现在优先级目标的前提下,逐级往理想目标靠拢”。我第一次在综合能源系统里彻底跑通这套逻辑,就是基于一个包含电、热、冷三种母线,融合了光伏、风电、燃气轮机、电锅炉、吸收式制冷机和蓄电池的程序。求解器选的IBM CPLEX,模型用Python搭,核心采用的是典型的目标规划框架。这套程序解决了我之前一直头疼的问题:怎么在一个优化模型里同时处理经济性、环保性和供能可靠性,并且让结果能直接给调度人员用。
这篇文章不打算复述教材公式,我把建模里那些容易绕晕的目标优先级设置、偏差变量处理、CPLEX落地细节,以及调试时遇到的几个典型陷阱都整理出来。如果你也在做综合能源系统的调度优化,或者刚下载好CPLEX准备开始写目标规划,这篇文章应该能让你少走一段我走过的弯路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 程序背后的系统边界与设备模型,必须先理清楚
2.1 我建模时的系统组成与母线架构
我当时做的这个综合能源系统,不是那种复杂到有几十条母线的省级大电网,而是一个典型的园区级多能互补系统,结构上完全可以看作一个微网与外网互联的全面提升版。系统内包含四条核心母线:电力母线、热力母线、冷力母线,以及天然气输入端口。电力母线连接光伏阵列、风力发电机、燃气轮机发电侧、电锅炉、电制冷机、蓄电池,同时通过一台变压器与外网做买电和卖电交互。热力母线主要是燃气轮机余热回收、燃气锅炉和储能水罐的汇合点,承担冬季暖通和生活热水的热负荷。冷力母线则连接电制冷机组和吸收式制冷机,用来满足空调冷冻水供应。
为什么先从母线架构说起?因为在实际建模时,绝大多数约束都围绕母线展开。你只要把母线上的设备进出功率都列全,能量平衡约束反而变成了最简单的线性等式,剩下的就是每台设备的独立运行约束。这套思路的优点是扩展性极强——想在系统里加一台氢燃料电池,直接在电力母线和氢气端口之间加一个组成模块就行,不需要动其他部分。
2.2 设备模型与参数选择上的基本简化原则
综合能源系统的设备模型如果写得太精细,求解复杂度会急剧上升。在工程级分析里,我普遍采用以下简化方式:
- 燃气轮机(CHP机组):用定效率模型描述,给定输入天然气功率,按电效率和热效率同时产出电和热,并设置最小开机出力与爬坡限制。
- 燃气锅炉:不考虑启停细节的连续调节模型,输出热功率在零到额定值之间连续变化。
- 吸收式制冷机:以热力母线的热功率为输入、冷力母线的冷功率为输出,引入一个固定的制冷系数(COP)来描述转换关系。
- 电制冷机、电锅炉:同样用COP或热效率简化建模。
- 光伏与风电:按典型日场景曲线给定预测出力上限,调度程序只能在预测范围之内削减,不能超出。
- 蓄电池与储热水罐:采用能量状态(SOC)递推方程,考虑充放互斥约束。
这些模型在目标规划框架里全部转化为线性约束,CPLEX处理起来非常轻松。不要一上来就把机组启停的启停成本、开停机时间连锁、非线性的效率曲线全部塞进去。先跑通一个线性模型,再逐步优雅地加入复杂度,这个顺序能帮你避免前期就在调试维度上“爆炸”。
2.3 数据的时间尺度与场景处理
我选用的是典型日24小时调度,时间分辨率为1小时。光伏和风电出力数据采用某一典型夏日的归一化曲线,热、电、冷负荷取自园区实测数据。之所以不用随机场景或全年8760小时数据做初始验证,是因为这阶段的首要目的是把目标规划的数学结构、求解流程和优先级逻辑跑通。全年数据的处理一样样的,我用的是一个24小时的母线拓扑不变的确定性场景,这样每次求解都在几秒内连续返回,效率很高,非常适合反复调参。
3. 目标规划建模里的关键决策:优先级怎么设,偏差变量怎么放
3.1 为什么我选了目标规划而不是统一加权
在早期的版本里,我也试过把运行成本、碳排放量、联络线波动用一个加权和目标表达式写在一起,顺手给三个目标分别设置为0.6、0.3、0.1。结果确实很“快”,但有问题:当系统内部约束稍微一变化,比如燃气轮机检修停机,模型给出的解会突然变得非常激进——为了在不平衡时保住经济性,宁可大幅增加外网购电,导致碳排放量飙升,而碳排放目标原本设了0.3的权重,却几乎没有发挥约束作用。
加权目标规划的根本问题在于,权重的设定带有强主观性,而且在量纲差异巨大的目标之间,权重数值本身比目标实际重要程度更难以拿捏。比如运行成本可能是几万元量级,碳排放量是吨量级,联络线偏差是兆瓦量级,你很难让一个权重组合在所有工况下都自然合理。而目标规划的处理方式是分层次:系统必须先满足绝对约束,再向第一优先级目标靠拢,然后在此基础上向第二优先级靠拢,以此类推。这意味着低优先级的目标再理想,也不能以牺牲高优先级目标为代价。
3.2 系统绝对约束与三个目标优先级的设定逻辑
在这套程序里,硬性约束主要包括各母线的功率平衡、设备出力的上下限、储能装置的SOC更新与容量限制、与外网购售电的容量限制、燃机与锅炉的热出力上下限等。这些约束不可妥协。如果目标规划求解结果不可行,那一定是这些硬约束之间存在逻辑冲突。
在硬约束之上,我按实际运营逻辑设定了三级目标:
- 第一优先级:满足用户冷热电负荷需求,并且储能SOC在调度周期结束时回到初始值。这个优先级本质上是为了防止模型“耍小聪明”——比如把储能全部放空来搏经济性,到了周期末却没电可用。
- 第二优先级:运行成本最小化。燃料消耗费用、外网购电费用、可再生能源削减惩罚成本,统一折算成经济指标。
- 第三优先级:碳排放量尽可能低,同时联络线购电功率尽量平稳,避免频繁大幅波动。
这样设定之后,模型的求解结果非常稳定:即使第二优先级的成本目标因参数改变而出现退化,解空间也会通过第三优先级目标做进一步选择,而不是像加权法那样可能出现一个完全离谱的极端工况点。
3.3 偏差变量的处理细节,才是目标规划的灵魂
目标规划的核心是引入偏差变量,把目标函数转成偏差最小化问题。以成本目标为例,如果理想目标成本为C_target,那么我定义:
C + d_minus - d_plus = C_target,其中d_minus和d_plus都是非负连续变量,分别表示实际成本低于目标值的量和高出目标值的量。对于第一优先级目标,需要确保最终偏差为0,所以我写成d_plus = 0的约束形式(或设置一个极高的惩罚系数)。
不过值得强调的是,目标规划并不等于一定要求某个目标精确等于设定值,而是根据优先级依次最小化相应偏差变量。优先级排序在CPLEX里的落地方式有几种,我在程序里采用的是先求解第一优先级目标,然后把该目标中最优偏差值作为附加约束固定下来,再求解第二优先级,以此类推。这种方式在数学上非常严谨,配合CPLEX的指示约束实现非常方便。下一章我会具体展示这部分的代码框架。
4. CPLEX的落地实操:从环境准备到分层求解的代码骨架
4.1 环境准备与学术版安装注意点
如果你的身份是高校学生或科研人员,CPLEX学术版是可以免费使用的。下载途径是IBM Academic Initiative官网,安装包包含优化引擎和Python接口。特别注意:很多人安装完成后会因为Python接口缺失而无法在Anaconda里import cplex。实际上,从较新的版本看,pip安装的方式比我早期从源代码编译更稳定。建议在创建好的conda环境中直接执行:
bash复制pip install cplex
然后在Python里验证一下:
python复制import cplex
print(cplex.__version__)
我踩过的坑是:系统里如果有多个Python环境,pip install容易装到默认环境而非你的项目环境。所以建议先激活conda目标环境,确认which python指向正确路径后再安装。另外,新版CPLEX接口对Python 3.10以上支持的优化程度逐渐提升,但如果你还在使用老版本CPLEX,务必确认Python版本兼容性,否则会报一大堆莫名其妙的头文件错误。
4.2 用docplex还是cplex原生API
在这个项目里,我用的是docplex——CPLEX的官方Python建模库,底层调用cplex求解器。相比原生cplex API,docplex在变量索引、约束管理、模型诊断这些方面的表达更直观,更接近PuLP或Pyomo的建模体验。如果你已有原生API经验,用起来也毫无冲突,因为docplex模型可以直接获取Cplex对象去调整求解参数。
建议的建模流程:
- 创建Model实例。
- 按设备定义连续决策变量和二进制变量,用字典结构存储,方便后续统一定义目标与约束。
- 通过
model.add_constraints批量添加约束,避免循环append造成的性能损失。 - 分层求解时,每层都用
model.solve(),再将求得的偏差值取整后作为常数约束固定下来。
4.3 分层目标规划的求解循环代码示例
假设两个优先级的偏差变量目标是偏差优先值obj1和次级成本值obj2,可以按下面框架逐级求解。注意这种逐级求解方式的本质是把问题求解多遍,因此总耗时等于各层耗时之和。好在CPLEX对这种小规模线规划解得非常快,24小时的场景在秒级内就能完成三层求解。
以下是核心骨架,我可以精简地写出来供你参考:
python复制from docplex.mp.model import Model
model = Model(name="multi_energy_goal_programming")
# 决策变量定义,这里只展示核心偏差变量
d1_minus = model.continuous_var(name="d1_minus", lb=0)
d1_plus = model.continuous_var(name="d1_plus", lb=0)
d2_minus = model.continuous_var(name="d2_minus", lb=0)
d2_plus = model.continuous_var(name="d2_plus", lb=0)
# 第一优先级:负荷平衡偏差为0
model.add_constraint(d1_minus + d1_plus == 0, "P1_balance")
model.minimize(d1_minus + d1_plus)
model.solve()
fixed_d1 = model.objective_value # 理论上应为0
# 将第一值固定,转入第二优先级
model.add_constraint(d1_minus + d1_plus <= fixed_d1, "fix_P1")
model.minimize(d2_minus + d2_plus)
model.solve()
实际完整模型里,d1、d2不是单独一个变量,而是按时段与母线拆分出的几组偏差变量。这个骨架想说明的分层逻辑是通用的:每一层都以某一目标为目标函数,并以前一层求得的最优偏差作为硬约束。
4.4 CPLEX求解参数的实践经验
- gap设置:默认gap是0(对线性规划而言是0,对混合整数规划默认相对MIP gap为0),但如果模型被升格为混合整数问题,求解时间与问题规模会同步膨胀。我习惯设置
model.parameters.mip.tolerances.absmipgap = 1e-3,避免无意义的精度追求。 - 时间限制:调试阶段一定设置
model.set_time_limit(120),防止因约束冲突导致长时间计算挂起。 - 输出日志:用
model.parameters.mip.display = 2查看每一层的求解状态,方便判断哪一层约束过紧导致不可行。 - 数值容忍度:综合能源系统各目标量纲差异很大,成本上万元而碳排放只有几十吨,求解器数值误差容易被放大。最好在建模时把成本目标换算成万元单位,碳排放量保持吨,这样目标值范围更接近,数值稳定性明显更好。
5. 运行时不可行、目标退化与联络线功率失稳的排查链
5.1 不可行问题:最头疼的“需求是不可再平衡的吗”
我早期遇到的一个典型不可行案例是:程序完成从冬季场景切换到夏季场景后,模型直接报不可行。我第一反应是检查目标函数有没有变号错误,查了半天没有。随后我逐条打印模型约束才发现问题出在冷负荷平衡上。夏季冷负荷全部由电制冷和吸收式制冷承担,而吸收式制冷的输入热功率来自燃气轮机的余热回收。燃气轮机为了满足电力母线的低负荷需求,最小出力已经很低,余热回收功率相应很小,进而导致吸收式制冷出力不足,无法同时满足冷负荷约束。
如果想在白天光伏大发时让燃气轮机压到最低出力,同时保住冷负荷,就必须把短板补上。我的解决方案是在夏季场景中上调燃气轮机的最低技术出力,并让电制冷机承担更多冷负荷。这个改变虽然会增加一些成本,但系统从结构上就是可行的,也符合实际运行逻辑。调试时别忘了多做一步:查看CPLEX返回的不可行约束导出文件。在docplex中你可以用model.export_as_lp("debug.lp")导出模型,再在文档中搜索标为不可行的约束组,很多问题一眼就能定位。
5.2 目标退化的威胁:当第二优先级成本目标被高优先级“锁死”
分层求解的好处是优先级清晰,但代价同样存在——高优先级目标的约束会直接挤压低优先级目标的可行域。即使系统完全可行,低层目标也可能在高层约束下退化为只能接受某一点的值而没有任何优化余量。
我在冬季场景遇到过这种事:第一优先级要求SOC回到初始值,但24小时周期内电负荷太高,储能基本没有多余放电空间,所以SOC轨迹被压得死死的。进入第二优先级求解时,成本目标的可行域已经退化成一条线,偏差变量的下界很高,优化变得没有任何余地。
应对这种问题有两种常用策略。一种是调整第一优先级设置,例如把SOC初末相等改成SOC在一天结束时不低于初始值的95%,给低优先级目标留出一点回旋空间。另一种是调低高优先级目标的“硬性”程度,把偏差变量的上限放宽到一个极小但非零的范围,类似软约束的思想。我在最终程序中选了第一种,因为它更符合电池储能日常运维的真实需求——偶尔稍低于初始SOC是可接受的,只要不过度损耗。
5.3 联络线功率失稳:当目标规划顺滑输出“锯齿波”
第三优先级目标里我加了联络线购电功率平稳性,但最初这个目标只写了购电成本的负向偏差,没有显式控制波动。结果输出的调度曲线在数值上非常漂亮,但联络线功率呈现大量频繁跳变:待优化目标为最小化成本,模型在光伏出力的每个小时之间开关外网购电,丝毫不关心实际电网调度机构对大波动曲线的容忍度。
解决思路是在第三优先级目标中增加相邻时段购电功率差值的绝对值之和,作为另一个偏差变量组。为了让CPLEX处理绝对值,引入了辅助变量delta_t,并添加两个不等式约束:
python复制p_buy[t] - p_buy[t-1] <= delta_t
p_buy[t-1] - p_buy[t] <= delta_t
再把所有delta_t的累加值放入第三优先级的目标函数。这样模型想要降低联络线波动,必须平滑购电轨迹,给出的调度计划在工程上就具备可执行性了。
5.4 结果合理性验证的兜底检查
很多程序跑完就宣告胜利,结果拿给运行人员一看就露馅。我习惯在结果输出之后,加一道“指标体检”的流程:校验每个时段的电荷平衡是否有微小误差(模型应精确满足,如误差超过1e-4MW就要排查);检查储能SOC序列是否始终在容量上下界之间;逐条查看所有二进制互斥约束是否出现同时为1的数值解;校验外网购电功率是否越限。最后再对照典型日负荷曲线,人工扫一眼调度结果是否符合季节性运行直觉。
这套兜底检查不会增加多少编码量,但对调试阶段的帮助极大。因为CPLEX即使求解成功,也不代表你的模型定义就是合理的,很多物理上的不可能在程序层面只是数学上的“可行解”。
6. 电-热-冷耦合约束与蓄能设备的建模细节
6.1 热电联产与制冷耦合约束,这部分最容易被忽略
多能互补系统的迷人之处在于各能源形式之间的深度耦合,建模上的“迷人之处”也往往变成“麻烦之处”。燃气轮机既要发电又要产热,这本身就意味着电出力和热出力不是两个独立可控变量,而是受同一个燃料输入决定的。我在模型里用了定效率模型:
发电功率 P_gt = eta_e * F_gt
热回收功率 H_hrs = eta_h * F_gt
这里的F_gt是输入燃料功率,eta_e和eta_h为机电转化效率与热回收效率。因为二者共享同一个燃料变量,等效于在P_gt和H_hrs之间建立了一个固定的比例系数。如果直接将P_gt和H_hrs都定义为独立变量,求解器就会得到很多数学上可行但物理上荒谬的组合。
吸收式制冷机与热母线之间也有类似的耦合关系:C_abs = COP_abs * H_abs_input,其中H_abs_input是制冷机从热母线取得的热功率。如果热母线同时还承担供暖负荷,就会出现热力竞争:多给制冷机供热,热水供暖可能不足;强行同时满足两侧需求,则必须由燃气锅炉补充更多热量,成本随之上升。这些竞争关系如果不显式建模,目标规划就无法在优先级目标之间真正做取舍。
6.2 储能SOC和充放互斥处理的经验
蓄电池和储热水罐在建模上有一个通病:如果不声明充放互斥,求解器非常乐意让蓄电池同时充电和放电,从而产生“模型套利”的怪异结果。你还不能简单把功率设定成连续变量并期望求解器自觉,它没有这个自觉。
处理方式最可靠的是引入二进制变量b_ch和b_dis,建立互斥约束:
python复制b_ch[t] + b_dis[t] <= 1
P_ch[t] <= b_ch[t] * P_ch_max
P_dis[t] <= b_dis[t] * P_dis_max
这组约束会引入整数变量,模型规模涨一点但完全可接受。如果系统时段特别多(比如全年8760小时),可能就要考虑用特殊顺序集或滚动时域方法来压缩规模。对于24小时综合能源系统,二进制变量数量完全不是瓶颈。
SOC递推方程建议这样写:
SOC[t+1] = SOC[t] + eta_ch * P_ch[t] * delta_t - P_dis[t] / eta_dis * delta_t
这里的eta_ch和eta_dis分别是充电效率和放电效率,直接影响储能参与调度的总体收益。很多初学者把充放电效率合二为一,虽然简化了模型,但会低估储能运行损耗,导致调度结果在实际执行时出现偏差。
6.3 多能耦合如何影响层级目标的可实现性
这里有一个重要的调度经验:高优先级目标在多能耦合系统里的“独占性”会直接塑造整体运行方式。例如你设置第一优先级确保热负荷完全满足且储热罐初末SOC一致,这在冬季场景很容易导致燃气锅炉长期承担基荷,燃气轮机即使经济性差也得跟着启动,因为热负荷兜不住。你本想通过目标规划优化“经济性”,实际却被硬性的热能需求带着走,这是该领域建模无法回避的权衡。
7. 从可运行到可交付:结果输出与决策支持界面
7.1 调度结果的可视化与关键指标统计
程序跑完一批数据后,光有一个最小化目标值远远不够。我在程序输出模块里生成了一张包含各设备逐时出力、母线供需平衡、购电功率、SOC曲线、碳排放量和运行成本的综合结果表。画图推荐使用Matplotlib定制一张堆叠面积图:横轴为24小时时间,纵轴为各设备的电出力与电负荷。热、冷母线的平衡表同样用类似方案展示。这样所有关键交互能在一张图上全景呈现,判断模型行为是否合乎预期,比看密密麻麻的数字高效得多。
7.2 目标规划内部指标的输出对调试有重大价值
除了调度计划,程序还应输出每一层级目标的主要偏差值。例如第一层级的负荷失配量、第二层级的成本超出量、第三层级的碳排放偏差与联络线波动量。这些数值能够告诉你:当前方案离理想目标到底差了多少,以及这个“差”是由哪条硬约束造成的。我习惯在每次求解后把各优先级偏差打印成一份简报,这成为判断是否需要调整约束边界条件和参数的关键依据。
7.3 从技术程序到决策工具,还需要补充什么
单纯一个调度程序离直接应用还有距离。实际园区运行中面临大量随机性,光伏出力和负荷预测不会精准;求解一次性强依赖预测数据质量。我在该程序基础上扩展过一个滚动优化的版本:每15分钟滚动一次,每次使用最新预测数据和实时SOC状态重新求解未来4小时调度计划。目标规划的结构保持不变,变化仅在于时间窗滚动更新,这样程序的实用性一下子提升不少。如果你打算把程序推向工程应用,滚动优化是个必然方向。
8. 模型规模和数据管理上的几个体会
8.1 变量与约束的量级梳理
这个24小时的园区级场景,最终模型包含约几百个连续变量、几十个二进制变量、上千条约束,CPLEX求解时间按毫秒到秒级计算。真正让模型变重的地方是对全年四季典型日的批量计算。我在程序里用循环方式依次对每个典型日建模并求解,每一日单独输出优化方案,再把四个季节结果汇总成年度能耗与成本指标。这种分日建模的方式在调试阶段更友好,也方便在运行过程中加入按日的计划检修约束。
8.2 数据文件组织与参数集中管理
建议所有设备参数不要散落在代码中,而是通过配置文件或Excel表格统一管理。这样团队内的工程师都能在不改动程序逻辑的前提下调整设备容量、效率、燃料价格和分时电价。我自己踩过这样的坑:直接把参数写在代码变量中,后来换一个园区场景,改参数时忘记在某一个关联约束里同步更新,导致模型跑出了一个明显违背物理直觉的解,排查了半天才意识到是参数不同步的问题。
合理的做法是把系统分为“设备参数表”“负荷曲线表”“可再生能源出力场景表”“能源价格表”四个模块,程序启动时统一读取并注册到模型中。目标规划的优先级设置也可以作为配置项,方便在不同运行策略之间灵活切换。
9. 一段数据的小型复现:验证程序时我用过的检测方法
9.1 检测方法一:极端场景验证
这不算常规优化,但我几乎每次搭建完一个目标规划模型后都要跑一遍极端场景。比如设定光伏预测出力为0,观察模型是否自动提高燃气轮机出力和外网购电量以维持平衡;再比如设定所有负荷同时降低到零(工厂停产状态),系统是否进入最低出力的“休眠”模式。如果这些极端场景的结果符合物理直觉,说明模型主框架基本可靠。
9.2 检测方法二:优先级顺序对抗验证
为了确认目标规划的优先级真的在起作用,我做了一个反向测试:故意在第一优先级目标中加入一个不可能完全满足的约束(比如要求某时段热负荷满足率达到120%),观察求解结果是否会因为这条伪高优先级目标而完全放弃成本与碳排放优化。如果你看到结果几乎不为成本目标做任何让步,说明优先级的实现逻辑是正确的。注意,测试完记得移除这条伪约束。
9.3 检测方法三:与单目标优化结果对照
按最朴素的想法,如果把目标规划的某一优先级目标单独作为唯一目标函数求解,其结果应当不劣于目标规划方案中该目标的最终值(因为在分层求解中,低优先级目标可能被高优先级挤压)。我用线性规划单目标结果与目标规划结果进行对比,计算两者的目标值差距,以此判断约束冲突造成的效益损失有多大。这个对比结果也可以用来向决策者解释“可靠性优先策略”和“纯经济最优策略”之间的成本差异,给方案选择提供量化依据。
10. 与CPLEX打交道时,值得记住的两个“反直觉”经验
第一个经验是:别太相信默认求解器选项。对纯线性规划问题,CPLEX默认设置通常够用;但模型一旦引入二进制变量做充放互斥,变成混合整数问题之后,默认求解策略可能不是针对这种“时间耦合紧密、设备耦合密集”的模型最优的选择。我会把MIP emphasis设置为可行性优先(feasibility over optimality)来应对储能调度这种时间关联问题。在求解器看来,找到一个质量尚可的可行解比慢悠悠搜索全局最优解更有工程价值。
第二个经验是:用LP文件记录模型状态。我在调试不可行问题时,不只看错误信息,更习惯把模型导出到LP文件再做文本分析。docplex的model.export_as_lp()非常实用,我建议每个综合能源优化模型的开发流程中,强制保留这一步。很多时候问题来自你根本没想到的设备耦合约束,而LP文件的逐行审视能比查代码更快暴露问题。
从另外的角度说,目标规划方法本身不复杂,复杂的是把系统各能源设备的物理约束、运行人员的实际优先级和多目标之间的冲突关系,转译为CPLEX能够理解和接受的一组线性约束。建模过程中的每一次简化,都要不断追问自己的问题:这个简化会不会破坏关键物理约束?会不会让低优先级目标永远没有机会实现?会不会让最终调度结果在实际运行中被调度员当场否决?这套程序从初版到最终稳定版,迭代的核心其实不是在调求解器参数,而是在反复修正对“什么才是一个可落地的运行方案”的理解。
