You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pyomo调用Ipopt求解燃气管网优化时v_dot下界低于30收敛失败怎么办

问题根因分析

核心bug:压降约束符号不匹配

你当前的压降等式存在逻辑漏洞:

# 原错误写法
return ((model.pi[i] - model.pi[j]) * model.d[i, j] ** 5) == (a * model.v_dot[i, j]**2 * model.lengths[i, j])

等式右侧的v_dot[i,j]**2永远是非负数,因此左侧model.pi[i] - model.pi[j]必须也为非负数,等于强制所有管线只能从i节点流向j节点、流量必须为正。

  • 当v_dot下界设为30时,所有管线强制有正向流量,求解器可以通过构造循环流量满足节点守恒,因此能得到局部可行解,但非主路径管线因为必须过30的流量,管径无法收敛到最小值
  • 当v_dot下界低于30时,会出现流量为负/零的场景,此时右侧为正、左侧可能为负/零,等式完全无法成立,Ipopt找不到任何可行点,直接报Restoration Failed错误。
修复方案

1. 修正压降约束的符号逻辑

将v_dot的平方改为带符号的绝对值乘积,匹配流向和压降的对应关系:

def flow_rule(model, i, j):
    return (model.pi[i] - model.pi[j]) * model.d[i, j] ** 5 == a * model.v_dot[i,j] * abs(model.v_dot[i,j]) * model.lengths[i,j]

修改后流量为负时右侧也为负,对应pi[i] < pi[j]的反向流动场景,逻辑自洽。

2. 调整变量边界

将v_dot的边界调整为允许反向流动,或者根据你的管网需求设为非负:

# 允许反向流
model.v_dot = pyo.Var(model.edges, bounds=(-1500, 1500), within=pyo.Reals)
# 仅允许正向流就设为(0, 1500)

3. 优化求解器配置

开启Ipopt自适应缩放解决变量尺度差异过大的问题(你当前pi是压力平方,数值范围百万级,和d、v_dot的尺度差超过6个数量级,极易导致收敛失败):

solver = SolverFactory("ipopt")
# 开梯度缩放适配多尺度变量
solver.options["nlp_scaling_method"] = "gradient-based"
# 放松边界容忍度避免数值奇异
solver.options["bound_relax_factor"] = 1e-8
results = solver.solve(model, tee=True)

4. 可选优化:避免零值数值奇异

如果设v_dot下界为0时仍有收敛问题,可以将下界调整为极小的正数(如1e-6),对最终结果的影响可以忽略。

预期效果

修复后非主路径的管线流量会收敛到0,对应管径自动取到0.01的最小值,目标函数值会低于之前的1091.8,且不会再出现可行域不存在的报错。

内容的提问来源于stack exchange,提问作者Khalilbs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:15:03