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

Pyomo+Ipopt定义分段非线性目标函数时遇数学域错误

问题描述

在Pyomo中使用Ipopt求解器定义分段非线性目标函数:当决策变量q_i ≥ 1时采用对数函数,q_i < 1时采用二次函数。用Expr_If实现后,求解器返回最优解,能正常打印q_i的最优值,但调用model.payoff()时触发“math domain error”,提示对数函数代入负值。手动代入变量值计算目标函数则可正常得到结果。

相关代码如下:

from pyomo.environ import ConcreteModel, Set, Param, Var, Expr_if, Objective, Constraint, summation, SolverFactory, log

model = ConcreteModel()

# 定义集合
model.P = Set(initialize=['P1','P2','P3','P4'])

# 参数
model.Beta = Param(model.P, initialize = {'P1':1,'P2':1.2,'P3':1.4,'P4':1.6})
model.Alpha = Param(model.P, initialize = {'P1':0.1,'P2':0.2,'P3':0.3,'P4':0.4})

# 变量
model.q = Var(model.P)

# 目标函数
def Payoff(model):
    return sum(Expr_if(IF=model.q[i]>=1, THEN=model.Beta[i] * log(model.q[i]),
              ELSE=(-0.5)*model.Alpha[i] * (model.q[i]-1)**2) for i in model.P)
model.payoff = Objective(expr = Payoff, sense = maximize)

# 约束
def limit(model, i):
    return -1.1<= model.q[i]
model.limit = Constraint(model.P, rule = limit)

def balance(model):
    return summation(model.q) == 0
model.balance = Constraint(rule = balance)

solver = SolverFactory('ipopt')
solver.solve(model)

model.payoff()  # 此行触发错误
原因分析

Pyomo的Expr_If并非像Python原生if-else那样仅执行符合条件的分支,而是会同时计算两个分支的表达式。即使最优解中q_i满足分支条件(比如q_i<1时不会触发对数分支逻辑),调用model.payoff()时仍会尝试计算log(model.q[i])。而你的约束允许q_i ≥ -1.1,当q_i为负数时,log(q_i)就会触发数学域错误。

解决方法

方法1:使用Pyomo内置value()函数

直接调用value()函数获取目标函数最优值,该函数会正确处理Expr_If的分支逻辑,仅计算符合条件的表达式:

from pyomo.environ import value

print(value(model.payoff))

方法2:优化手动计算逻辑

保留手动计算方式时,需先获取变量的数值再判断分支,避免直接对Pyomo变量执行对数运算:

import math

payoff_ = 0
for i in model.P:
    q_val = value(model.q[i])
    if q_val >= 1:
        payoff_ += model.Beta[i] * math.log(q_val)
    else:
        payoff_ += (-0.5)*model.Alpha[i] * (q_val - 1)**2
print(payoff_)

方法3:添加变量下界约束(可选)

若问题允许,可给model.q添加正实数下界,从根源避免对数分支出现负值,但此操作会改变原问题的可行域,需根据实际需求判断:

from pyomo.environ import PositiveReals

model.q = Var(model.P, domain=PositiveReals)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:25:43