ARTICLE DETAIL

资讯详情

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

风光互补制氢合成氨系统容量-调度优化建模与Cplex求解实践

风光互补制氢合成氨系统容量-调度优化建模与Cplex求解实践 做能源系统优化的朋友应该都有同感论文复现最怕的不是模型本身复杂而是作者把边界条件、参数来源和求解细节写得含糊。我最近花了三周时间把一个“并/离网风光互补制氢合成氨系统容量-调度优化”的模型完整复现了一版求解器用Cplex代码环境是Matlab。这套模型既涉及容量配置的长期决策又涉及逐时调度的短期决策两层耦合在一起建模和求解都有不少讲究。这篇文章把系统架构、数学模型、代码实现和踩坑过程都整理出来了给打算做氢能系统优化、或者正在复现类似论文的朋友做个参考。1. 复现项目整体思路与系统设计1.1 系统架构与能流关系先说清楚这个系统里到底有什么。风光互补制氢合成氨系统简单说就是由风力发电和光伏发电提供电力电解水制氢得到绿氢再把氢气和从空气中分离出来的氮气在合成氨单元里反应生成氨。整个能量链条是“风光发电→电解制氢→储氢→合成氨”其中储氢罐是缓冲环节用来平抑风光波动和合成氨负荷之间的不匹配。从建模角度系统可以拆成几个关键单元风力发电机组Wind Turbine, WT光伏阵列Photovoltaic, PV电解水制氢设备Electrolyzer, EL储氢罐Hydrogen Storage Tank, HST合成氨单元Ammonia Synthesis Unit储能电池Battery Energy Storage System, BESS可选电网连接点并网模式下才有空分装置提供氮气通常简化处理能流关系可以用一个功率平衡母线来理解。风电和光伏出力汇入母线母线再分配给电解槽、储能电池充电并网模式下还可以卖给电网反过来离网模式下只能靠储能放电来补缺并网模式下可以从电网购电。氢气侧是一条独立的物料链电解槽产出的氢气进储氢罐储氢罐出氢供给合成氨单元合成氨单元消耗氢气并产出氨。合成氨还需要氮气氮气由空分装置提供空分装置本身要消耗电在建模时可以折算成合成氨单元的辅助电耗。这个系统之所以值得做容量-调度联合优化核心原因在于风电和光伏出力天然存在时间和空间上的不匹配。白天光伏大发但电解槽可能来不及把多余电力全部消纳夜间风力可能上来但光照为零。如果只配置容量而不做调度优化要么设备利用率很低要么系统经常出现功率不平衡。反过来如果只给定容量做调度又无法回答“到底装多少风机、多少光伏、多大电解槽”这个规划问题。所以容量和调度必须放到同一个优化框架里去解。1.2 并网与离网两种运行模式的建模差异标题里“并_离网”我理解为并网和离网两种模式都做了分析。两种模式在实际工程里对应完全不同的运行逻辑建模时约束的差别也很明显。并网模式下系统与外部电网存在能量交换。风、光出力不足时可以从电网购电出力过剩时余电可以上网出售。这种情况下系统对“供电可靠性”的要求压力会小很多因为电网实际上起到了无限容量的备用作用。但建模仿真时不能把这个约束写得过于宽松要结合实际电力市场和电网交互规则比如购售电功率上限、不允许同时购电和售电、分时电价信号等。并网模式下最优容量配置往往偏向于可再生能源装机稍大一些因为多余的绿电可以直接卖钱或者用于制氢后通过氨产品获利。离网模式下系统必须完全自平衡。风光出力加上储能放电必须刚好等于电解槽、合成氨以及辅助设备的用电需求。这个约束看似简单实际上对储氢罐的缓冲能力要求极高。因为合成氨单元作为化工装置负荷调节范围通常在50%-100%额定负荷之间不能像电解槽那样随意启停。如果连续几天阴雨天导致光伏出力骤降氢气管网和储氢罐必须要有足够的存量来维持合成氨单元的连续运行。否则整个系统可能面临“风光大发时氢气存不下风光低迷时氢气不够用”的尴尬局面。建模差异具体体现在并网模式需要在功率平衡方程里加入购电量和售电量两个变量并且给购售电行为设置合理的逻辑约束离网模式则把这两个变量删掉功率方程变成“风光出力和储能净放电等于系统负荷”。离网模式下的可行域更紧求解难度反而可能更大因为决策变量之间的耦合关系更强容易出现不可行的情况。1.3 容量与调度协同优化的核心思路容量优化和调度优化属于不同时间尺度的决策问题。容量配置是“建设期决策”决定风机装多少台、光伏装多少千瓦、电解槽额定功率多大、储氢罐容积多大、合成氨规模多大这些决策的周期是二十年甚至三十年调度优化是“运行期决策”决定每一个小时风电出力怎么用、电解槽功率设定多少、储氢罐充放氢量多少、合成氨负荷怎么调整这些决策是以小时甚至分钟为粒度进行的。两个问题之间又是强耦合的容量配置决定了调度优化的可行域调度优化的结果决定了系统全年运行成本和产量而运行成本和产量又反过来影响容量配置的经济性评估。处理这种耦合行业里有两种主流做法第一种是嵌套迭代求解。外层做容量优化的遗传算法或智能算法内层对每一组候选容量做一次调度优化返回运行成本。这种做法灵活但计算量巨大而且外层用启发式算法不能保证全局最优。第二种是单层建模法也就是把容量变量和调度变量全部放进同一个混合整数线性规划模型里一次性交给Cplex求解。我用的是第二种。原因很简单——Cplex对MILP的全局求解能力很强只要能把非线性环节线性化这个模型在可接受的时间内可以拿到全局最优解。论文复现阶段最需要的其实就是“结果可复现、可解释”单层模型输出的最优容量的物理意义非常清晰。单层模型的实际规模取决于典型日的选取。为了让计算量可控我采用冬夏两个典型日、每个典型日24小时、每个时段扩充成对应天数的处理方式这样既保留了季节差异又不需要把一整年8760小时全部建模求解效率高很多。如果后续对精度要求更高可以扩展到四季典型日代价是模型规模线性增长。2. 数学模型构建与关键公式解析2.1 目标函数设计这个优化问题的目标函数本质上回答的是“投资者到底想优化什么”。我采用最常见的口径最小化系统年化总成本同时考虑氨销售收入作为收益项。目标函数可以写成成本项 年化投资成本 运维成本 购电成本 − 售电收入 − 氨销售收入投资成本采用年化方式处理。设备投资是建设期一次性投入但运行寿命长达15-25年不能简单地把全部投资压到一年里。需要用等额年值系数折算CRF r × (1r)^n / ((1r)^n − 1)其中r是贴现率n是设备寿命。不同设备的寿命不一样风机通常20年光伏板25年电解槽10-15年所以要做分设备计算。复现时这里最容易出错的是单位统一投资成本单位往往混着用kW、MW、kWh、Nm³/h稍不注意就差了一个数量级。运维成本按设备初始投资的一定比例估算通常在2%到5%之间为了简化可以直接按“比例系数 × 设备额定容量”或者“比例系数 × 投资额”计算。并网模式下的购电成本和售电收入通过分时电价乘以对应时段的购售电量得到。氨销售收入则是优先生成氨产品的产量乘以市场氨价。如果论文里用的是另一个口径比如“收益最大化”或者“平准化制氢成本最小化”复现时的改动还是集中在目标函数这一层约束条件基本不用大改。这恰恰说明目标函数和约束在代码架构里要分离后面写程序时会强调这一点。2.2 核心约束条件拆解约束条件是这个模型里最费心思的部分。我按功能分为几组复现时逐组对照容易排查问题。首先是功率平衡约束。并网模式任意时段t系统必须满足风电出力 光伏出力 储能放电 — 储能充电 购电 — 售电 电解槽用电 空分/辅助设备用电离网模式把购电和售电两项去掉。注意这里的等式右侧有一个常被忽略的“空分/辅助设备用电”。合成氨过程需要压缩氮气和维持反应压力空分装置和压缩机要持续耗电大约占合成氨单元总电耗的10%左右。忽略这个辅助负荷会导致电解槽和合成氨容量配置结果偏差较大。第二是风电机组出力约束。风机出力不是自由变量由风资源和机组功率特性曲线决定。理论上每台风机的出力可以由切入风速、额定风速、切除风速和额定功率查功率曲线得到。模型里如果风机台数是待优化的整数变量风电出力表示为单机出力和台数的乘积。第三是光伏出力约束。光伏出力由光照辐照度和温度决定简化模型直接用额定容量乘以一个折算系数。第四是电解槽运行约束。电解槽不是从0到额定功率之间随便跑的碱性电解槽通常要求最低运行负荷在20%到40%之间PEM电解槽范围更宽一些。建模时必须加一个最小负荷约束否则优化器会让电解槽在过低的功率下长期运行结果虽然数字好看物理上根本跑不出来。第五是储氢罐动态平衡约束。储氢罐是系统里承上启下的关键缓冲环节约束写成逐时状态转移方程储氢量(t1) 储氢量(t) 产氢量(t) − 耗氢量(t)同时储氢量有上下限约束初始储氢量和终止储氢量根据论文设定比如设定一个周期开始时满罐、结束时回到同一状态可以保证全年的调度具有可持续性。第六是合成氨单元约束。合成氨负荷与耗氢量直接相关现代Haber-Bosch工艺的合成单元负荷可以在50%到110%之间调节但不能无限下降。负荷越低能耗越高经济性越差所以模型里通常给一个最小负荷率。产氨量与耗氢量之间按照化学计量系数折算这个系数在2.2节单独说。第七是储能电池约束如果模型里包含。电池的荷电状态、充放电功率上限、充放电效率都和储氢罐的状态方程类似。需要特别注意的是充电和放电不能同时发生否则会出现“一边充电一边放电”的荒谬解。类似的问题也出现在并网模式的购电和售电上两者也不能同时为正值。第八是并网交互约束。购售电上限可以设定购电功率不超过电网可接入容量售电功率不超过线路反向输送能力。购售电互斥的逻辑可以用一个二进制变量加两个不等式实现。2.3 非线性环节的线性化处理风光互补制氢合成氨系统里存在多个非线性关系直接扔给Cplex求解不了必须做线性化处理。第一个非线性来自合成氨产量与耗氢量的化学计量关系。好在这一步相对简单氨产量与耗氢量在恒定工艺条件下按线性比例对应。实际计算里就是用合成氨单元每个时段消耗的氢质量乘以一个产氨系数得到氨产量。这里的系数就是按照化学反应式的分子量之比折算出来的。第二个非线性来自电解槽的功率-产量特性。严格说电解槽的效率随运行功率变化不是一条直线同时电解槽的额定功率作为决策变量和运行功率相乘会产生变量乘积项。处理办法有几种一是忽略效率变化用恒定效率近似论文里多数也是这么做的二是用分段线性效率曲线通过分段线性插值表示效率与功率的关系这种方式会引入额外的辅助变量但精度更高三是额定功率和运行功率耦合时用大M法加人工变量把非线性约束线性化。第三个麻烦来自“容量变量 × 调度变量”这种双线性项。比如电解槽额定功率是容量变量实际功率是调度变量约束里出现二者相乘就不能直接求解。复现时我采用MILP建模直接用大M法处理。比如某台设备“若额定容量大于零则运行功率上下限受限”这种逻辑关系用二进制状态变量表示启停再用大M把状态变量和运行功率的耦合关系扩展开。这里分享一个经验在做线性化时不要贪多能用简单约束逼近的坚决不引入额外变量。每增加一个二进制变量Cplex的搜索空间都会显著增大。比如购售电互斥其实不需要二进制变量只要让售电价格低于购电价格优化器在最小化成本的目标下天然不会同时买卖。多思考几步可以减少大量不必要的整数变量。3. MatlabCplex代码实现全过程3.1 开发环境配置与初始验证先说我用的环境Matlab R2022aIBM ILOG CPLEX Optimization Studio 12.10Windows 11系统。Cplex安装完成后Matlab并不能直接用需要在Matlab里加载Cplex的Matlab API。具体做法是在Matlab命令行执行addpath(C:\Program Files\IBM\ILOG\CPLEX_Studio1210\cplex\matlab\x64_win64);注意路径里的x64_win64要根据Matlab位数选择64位Matlab必须匹配64位Cplex。配置完成后用一个小测试验证连通性cplex Cplex(test); cplex.Model.sense minimize; cplex.addCols(1, [], [], 0, 10, x); cplex.solve(); cplex.Solution.status如果状态显示为1最优解说明Cplex和Matlab的接口打通了。这一步看起来简单实际上是复现过程中最容易卡壳的地方我遇到过好几种不同的环境问题后面在问题排查章节展开。3.2 代码框架与模块划分复现项目不能把几百行程序全塞进一个脚本里否则后面修改参数、排查错误时会非常痛苦。我按功能把代码分成六个模块main.m 主程序入口控制整个求解流程 dataInput.m 读取风速、辐照、电价、氨价等外部数据 initializeParams.m 定义设备经济参数和运行参数 buildModel.m 建立决策变量、目标函数和约束条件 solveModel.m 调用Cplex求解并保存结果 plotResults.m 绘制调度结果和容量配置结果main.m的职责就是按顺序调用其他模块并把求解状态打印出来% 数据导入 [windData, pvData, priceData] dataInput(input_data.xlsx); % 参数初始化 params initializeParams(); % 构建优化模型 [model, varIdx] buildModel(windData, pvData, priceData, params); % 调用Cplex求解 solution solveModel(model, params); % 结果输出 plotResults(solution, params);dataInput负责把原始的风速、辐照和电价表格读入Matlab并转换成模型所需的矩阵。initializeParams把所有的设备参数集中在一个结构体里方便统一管理和修改。buildModel是整个代码最核心的部分Cplex的对象、决策变量、约束矩阵都在这个函数里组装。solveModel封装了Cplex的求解调用包括MIP gap设置、时间限制、求解状态判断。plotResults根据求解结果画图。模块化的好处很明显论文里参数稍有调整只改initializeParams一处想换一套求解器只需要改solveModel想加入第四种典型日只需要改dataInput和buildModel里的维度声明。3.3 数据准备与参数表复现时最耗时的一步其实是整理输入数据。根据我复现的经验至少需要准备以下几类数据第一类是资源时序数据。风速和辐照数据通常是典型日的逐时序列。风速单位是m/s辐照单位是W/m²。如果论文没有直接给出数据可以从公开的典型气象年数据中提取冬夏两季的典型日。这里要提醒一下许多论文里的“典型日”是经过聚类算法比如K-means挑选出来的不代表某一天的实际数据而是多个日期的合成代表。第二类是设备参数。我把常用参数整理成一张表设备投资成本单位运维成本比例寿命关键运行参数风电机组元/kW3%20年切入风速、额定风速、切除风速光伏阵列元/kW2%25年光电转换系数、温度系数电解槽元/kW4%12年最低负荷率、电耗率kWh/Nm³储氢罐元/Nm³或元/kg2%20年最大储氢压力、初始储量合成氨单元元/(t/d)3%20年最小负荷率、氨氢转化系数第三类是经济参数。贴现率、上网电价、购电电价、氨的销售价格每个参数对结果的影响都可能非常大。复现时一定要对照论文正文和附录确认这些参数的取值单位。我遇到过一篇论文的投资成本单位写的是“元/kW”但附录表格里实际上是“万元/kW”差了一个数量级照着复现出来的容量配置完全对不上。第四类是模型参数。包括典型日数量、每个典型日包含的小时数通常是24以及每个典型日代表的“权重天数”比如冬季典型日代表120天夏季典型日代表100天。权重天数的选取会直接影响年化成本和产量核算。3.4 Cplex求解核心代码实现构建模型有两种常用方式一种是用YALMIP这种建模语言包Cplex另一种是直接用Cplex原生API。我一开始图省事用YALMIP确实写起来快但后来发现原生API对模型调试更友好尤其是导出lp文件排查不可行问题时很方便。这里两种都介绍一下。YALMIP版本的代码骨架大致是这样% 定义决策变量 P_wt sdpvar(T, 1); % 风电出力 P_pv sdpvar(T, 1); % 光伏出力 P_el sdpvar(T, 1); % 电解槽功率 P_buy sdpvar(T, 1); % 购电 P_sell sdpvar(T, 1); % 售电 S_h2 sdpvar(T1, 1); % 储氢量 cap_wt intvar(1, 1); % 风机台数整数变量 cap_pv sdpvar(1, 1); % 光伏容量 cap_el sdpvar(1, 1); % 电解槽额定功率 cap_h2 sdpvar(1, 1); % 储氢容量 % 定义约束 Constraints []; for t 1:T Constraints [Constraints, P_wt(t) cap_wt * single_wt_power(t)]; Constraints [Constraints, P_pv(t) cap_pv * pv_output_factor(t)]; Constraints [Constraints, P_el(t) 0.2 * cap_el]; Constraints [Constraints, P_wt(t) P_pv(t) P_buy(t) P_el(t) P_sell(t)]; Constraints [Constraints, S_h2(t1) S_h2(t) hydrogen_produce(P_el(t)) - hydrogen_consume(t)]; end % 目标函数 Objective sum(investment_cost) sum(operation_cost) sum(price_buy .* P_buy) - sum(price_sell .* P_sell) - ammonia_revenue; % 求解 options sdpsettings(solver, cplex, verbose, 2, debug, 1); optimize(Constraints, Objective, options);YALMIP的优势是代码可读性高适合快速搭建模型。但缺点也很明显当模型规模变大时YALMIP的符号运算会拖慢构建速度而且有时候诊断信息不够直接。原生Cplex API版本的建模思路是逐列添加决策变量、逐行添加约束。比如给Cplex添加决策变量cplex Cplex(hydrogen_ammonia); cplex.Model.sense minimize; cplex.addCols(f, [], [], lb, ub);其中f是目标函数系数向量lb和ub是变量上下界。添加约束用cplex.addRows(lhs, coeffs, rhs)每一行就是一个线性不等式或等式。原生API代码比较冗长但好处是导出的lp文件清晰可以精准定位错误。我的最终实现采用了原生API因为复现调试阶段需要频繁查看模型结构。3.5 结果输出与可视化求解完成后除了输出容量配置和调度结果之外我还会额外计算几个关键指标设备年利用小时数、电解槽满负荷小时数、氨年产量、单位氨生产成本、自供电率离网模式下。这些指标是判断结果是否合理的重要依据。可视化部分我画了三张图。第一张是典型日电力平衡图用堆叠面积图展示风电、光伏、购电和储能放电如何满足电解槽和辅助负荷第二张是氢流量图展示电解槽产氢量、储氢罐充放量和合成氨耗氢量的逐时变化第三张是容量配置的经济性占比图直观地呈现各设备的投资占比。画图代码不复杂但要注意单位和标签的清晰度。调度结果图不要做成一张密集到看不清的曲线图分日绘制效果更好。Cplex求解结束后要养成检查gap的习惯如果MIP gap超过1%说明模型里可能存在数值病态或者整数变量过多这时候盲目信任求解结果会很危险。4. 复现过程中踩过的坑与排查技巧4.1 求解器连接与版本兼容问题Cplex和Matlab的版本兼容性是个老生常谈但永远有人踩的坑。Cplex 12.10官方支持Matlab R2019a到R2022a附近的版本新版Matlab很可能不兼容旧版Cplex的Matlab接口。我自己遇到的一个实际问题是Matlab加载Cplex后执行Cplex构造函数直接报“未定义函数或变量”。排查后发现是环境变量没有配置好Windows的PATH里缺少Cplex的bin目录导致 Matlab 找不到 Cplex 的动态链接库。解决方法是把...\CPLEX_Studio1210\cplex\bin\x64_win64加到系统PATH重启Matlab后再试。另一个常见问题是许可证服务没有启动。Cplex是商业求解器需要有效的许可证。如果出现“No valid CPLEX license found”这类报错检查许可证环境变量和许可证服务状态。有些复现教程会用学术许可证或者社区版要注意版本限制避免在模型规模较大时出现求解中断。4.2 模型不可行的系统性排查复现过程中最崩溃的时刻是Cplex返回“infeasible”。离网模式很容易出现系统无解因为约束太紧风光资源不足时储氢罐容量又不够合成氨单元的负荷下限又降不下来整个方程组找不到可行解。我的排查经验是不要直接去“猜”哪条约束出问题而是系统性地处理。第一步打开Cplex的诊断信息或者用cplex.conflict()方法提取不可行约束集合。Cplex原生API提供了冲突辨识功能可以自动定位一组不可行的约束这比人肉逐条排除高效得多。第二步在容易出问题的平衡约束里加一个非负松弛变量让约束“松”一些然后看松弛变量的最优值出现在哪里。松弛变量在哪个时段取值大说明那个时段的约束最紧。这种方法能快速定位到“离网夜间的氢量不足”还是“冬季典型日里合成氨负荷下限太高”这类问题。第三步检查储氢罐的初始状态。很多论文在离网运行时会假设初始时刻储氢罐已经充满从而保证前几个时段有氢可用。如果我把初始储氢量设成0离网模式下大概率会不可行。这一点需要在建模时严格对照论文假设。4.3 求解时间过长与MIP gap设置模型里如果风机台数是整数变量每个典型日又包含24个时段整数变量的数量和约束数都会成倍增加。Cplex默认的MIP gap是1e-4对这类工程问题来说过于严格导致求解时间白白翻了几倍。我处理的办法是把MIP gap放宽到1%cplex.Param.mip.tolerances.mipgap.Cur 0.01;这样求解时间可以从几小时缩短到几分钟而最优性损失通常在工程可接受范围内。容量优化这类问题的决策变量对目标函数的敏感度并不高1%的gap对最终容量配置结果影响很小。如果求解时间还是太长还有一种思路是先把整数变量松弛成连续变量求解一次线性松弛问题看看下界是多少用来判断整数解的次优性。这个方法对评价结果质量很有用。4.4 复现结果与论文数值对不上的原因复现论文时最常遇到的问题就是“容量和论文差距很大”。不要急着怀疑自己代码写错了先检查这些差异来源第一输入资源数据不同。论文里的风资源和光资源数据来自特定地点典型年甚至可能来自商业数据库复现者用公开数据替代结果肯定有偏差。这种情况只要趋势一致、量级合理就可以接受。第二设备参数来源不同。尤其是电解槽投资成本近几年成本下降非常快老论文用1万元/kW新论文可能只有5000元/kW最优容量配置自然差异很大。第三典型日选取方式不同。用单一典型日代表一整年结果必然粗糙用四个季节典型日容量结果通常更接近论文。复现前先确认论文用了几个典型日。第四年化因子计算方法不同。贴现率取5%还是8%年化系数差异很大直接影响投资分摊到每年的成本进而影响最优容量。排查时把这些因素逐一对齐通常能把大部分差异解释掉。如果全部对齐后还差很多那就要回头检查建模逻辑本身了。4.5 复现中的几个细节技巧我在编码过程中总结了一些值得分享的细节技巧。一是变量上下界要合理设置。别把风机组数上限设成无穷大否则Cplex在初始筛选候选解时会浪费时间搜索无意义的区域。根据项目土地面积和投资预算给出一个合理的上限比如风机最多20台光伏最多5MW能显著加速求解。二是所有输入数据的单位统一转换为国际单位制。我习惯把电功率统一为MW电量统一为MWh氢气量为kg氨量为t并在代码里用常量标注单位换算系数。这样可以减少错误也更方便结果展示。三是善用Cplex的写模型函数。模型构建完成后用cplex.writeModel(model.lp)导出一个文本格式的模型文件用文本编辑器打开检查。很多肉眼看不见的建模错误比如某一行的系数写错、约束方向反了都能通过这个操作发现。四是把论文的目标函数拆开记录每一项的数值。求解完成后分别输出投资成本、运维成本、购售电成本、氨销售收入的各项值对照论文表格里的经济性分析数据进行逐项核对。如果只有总成本和论文对得上、分项对不上说明目标函数内部存在相互抵消的错误。5. 从复现到迁移这套框架还能怎么用复现完这套风光互补制氢合成氨系统之后我最大的感受是这套“容量-调度联合优化Cplex求解”的框架并不只适用于这一个场景。把它抽象出来本质上是一类“可再生能源化工负荷储能的集成优化”问题稍微改一改就迁移到其他领域。如果你做的是绿氢制备可以把合成氨单元换成甲醇合成单元目标函数里的氨价改成甲醇价物料平衡换成CO₂加氢制甲醇的计量关系如果你做的是氢储能电站可以把合成氨单元去掉目标函数改成“系统净收益最大化”新增对售氢收入或冷热电联供收益的刻画如果你关注的是纯离网微电网可以把制氢和合成氨模块去掉只保留风、光、储和常规负荷模型框架完全兼容。扩展方向上值得尝试的有几个。第一是多目标优化把“总成本最小”和“碳排放最小”同时纳入目标函数用加权求和或者ε约束法求解得到Pareto前沿这在双碳背景下很受关注。第二是引入不确定性风光出力的随机性可以用鲁棒优化或者两阶段随机规划处理Cplex对两阶段模型的求解支持也比较成熟。第三是考虑更精细的设备运行特性比如电解槽的动态响应特性、尾气循环对合成氨工艺的影响这些内容会让模型更贴近工程实际但也会显著增加求解难度。最后再说一个我复现完才意识到的工程问题模型优化出来的容量配置只是一个理论上的“最优解”真正落地时还要考虑电网接入容量限制、土地面积约束、当地环保政策、电价机制的动态变化等因素。优化模型给出的不是唯一答案而是一个在给定假设下表现最优的参考方案。做系统规划时把Cplex的输出当作起点在周边做灵敏度分析观察容量方案对关键参数变化的响应比死盯一个最优解更有工程价值。写在后面。复现这篇论文的过程中我踩过不少坑也收获了很多。最大的体会是做能源系统优化模型和代码只是工具对物理过程的深刻理解才是真正决定结果质量的根基。你只有理解了电解槽为什么不能长期在低负荷下运行、合成氨单元为什么需要连续稳定的氢源供给你才能写出有物理意义的约束条件也才能判断Cplex给出的“最优解”到底合不合理。这套框架后续的扩展空间很大我近期在尝试把时序运行的精细化程度提升用8760小时全年数据替代典型日近似同时引入更细致的电解槽效率曲线求解规模会上一个台阶但模型的可解释性和实际参考价值也会更高。如果你也在做类似的方向欢迎一起交流复现过程中的细节体验。
返回列表