是否可以使用“Ipopt”求解器在 Pyomo 中定义非线性分段目标函数?

问题描述 投票:0回答:1

在带有“Ipopt”求解器的 Pyomo 中,我试图定义一个分段的非线性目标函数,这样当决策变量 q_i < 1, it is a quadratic function; otherwise it is a log function. As suggested by the answer here 时,使用“Expr_If”表达式应该可以完成这项工作。但是,当我运行代码(如下)时,求解器指示它达到了最优解,我可以通过运行打印最优决策变量的值:

for x in model.q: print(model.q[x].value)
但是我运行时无法打印目标函数的最优值:
model.total_cost()
这样我得到这个错误“数学域错误”。此错误可能表明正在以负值评估对数函数,但根据我定义的目标函数,这不应该发生。此外,我可以通过运行代码直接使用最优解的值重写目标函数的值(在获得最优解之后)来计算目标函数的值:

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

你知道为什么我在运行时出现“数学域错误”

model.total_cost()
吗?

我的代码:

model = ConcreteModel()

#Define the set
model.P = Set(initialize=['P1','P2','P3','P4'])

#Parameters
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})

#Variables
model.q = Var(model.P)

#Objective
def Total_Cost(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.total_cost = Objective(expr = Total_Cost, sense = maximize)

#Constraints
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.pprint()

model.total_cost()
python pyomo ipopt
1个回答
0
投票

在运筹学 SE 中发布此消息会更幸运。

© www.soinside.com 2019 - 2024. All rights reserved.