PyOmo/Ipopt 失败 "can't evaluate pow"
PyOmo/Ipopt fails with "can't evaluate pow"
我正在使用 PyOmo 生成非线性模型,最终将使用 Ipopt 求解。型号如下:
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
m.t = ContinuousSet(bounds=(0,100))
m.T = Param(default=100,mutable=True)
m.a = Param(default=0.1)
m.kP = Param(default=20)
m.P = Var(m.t, bounds=(0,None))
m.S = Var(m.t, bounds=(0,None))
m.u = Var(m.t, bounds=(0,1), initialize=0.5)
m.Pdot = DerivativeVar(m.P)
m.Sdot = DerivativeVar(m.S)
m.obj = Objective(expr=m.S[100],sense=maximize)
def _Pdot(M,i):
if i == 0:
return Constraint.Skip
return M.Pdot[i] == (1-M.u[i])*(M.P[i]**0.75)
def _Sdot(M,i):
if i == 0:
return Constraint.Skip
return M.Sdot[i] == M.u[i]*0.2*(M.P[i]**0.75)
def _init(M):
yield M.P[0] == 2
yield M.S[0] == 0
yield ConstraintList.End
m.Pdotcon = Constraint(m.t, rule=_Pdot)
m.Sdotcon = Constraint(m.t, rule=_Sdot)
m.init_conditions = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(m,nfe=100,ncp=3,scheme='LAGRANGE-RADAU')
discretizer.reduce_collocation_points(m,var=m.u,ncp=1,contset=m.t)
solver = SolverFactory('ipopt')
results = solver.solve(m,tee=False)
运行 模型导致以下错误:
Error evaluating constraint 1: can't evaluate pow'(0,0.75).
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/pyomo/opt/base/solvers.py", line 577, in solve
"Solver (%s) did not exit normally" % self.name)
pyutilib.common._exceptions.ApplicationError: Solver (asl) did not exit normally
错误的第一部分来自 Ipopt,而第二部分来自 PyOmo。显然这个问题与约束中的术语 M.P[i]**0.75
没有关系,但是改变功率并不能解决问题(尽管 2.0
确实有效)。
我该如何解决这个问题?
错误消息指出无法计算 pow'(0,0.75)
。此函数中的 '
字符表示一阶导数(''
表示二阶导数)。该消息实际上是说一阶导数不存在或导致无穷大为零。
解决这个问题很简单:将您的变量绑定到一个非零值,如下所示:
m.P = Var(m.t, bounds=(1e-20,None))
m.S = Var(m.t, bounds=(1e-20,None))
我想补充理查德的回答:
您可能还需要更新变量的初始值,因为如果未指定,ipopt 会假定为 0,因此它会在第一次迭代时评估变量的初始值。
因此:
m.P = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
m.S = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
您可以使用与您的问题更相关的值而不是 1e-20 作为初始化值
我正在使用 PyOmo 生成非线性模型,最终将使用 Ipopt 求解。型号如下:
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
m.t = ContinuousSet(bounds=(0,100))
m.T = Param(default=100,mutable=True)
m.a = Param(default=0.1)
m.kP = Param(default=20)
m.P = Var(m.t, bounds=(0,None))
m.S = Var(m.t, bounds=(0,None))
m.u = Var(m.t, bounds=(0,1), initialize=0.5)
m.Pdot = DerivativeVar(m.P)
m.Sdot = DerivativeVar(m.S)
m.obj = Objective(expr=m.S[100],sense=maximize)
def _Pdot(M,i):
if i == 0:
return Constraint.Skip
return M.Pdot[i] == (1-M.u[i])*(M.P[i]**0.75)
def _Sdot(M,i):
if i == 0:
return Constraint.Skip
return M.Sdot[i] == M.u[i]*0.2*(M.P[i]**0.75)
def _init(M):
yield M.P[0] == 2
yield M.S[0] == 0
yield ConstraintList.End
m.Pdotcon = Constraint(m.t, rule=_Pdot)
m.Sdotcon = Constraint(m.t, rule=_Sdot)
m.init_conditions = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(m,nfe=100,ncp=3,scheme='LAGRANGE-RADAU')
discretizer.reduce_collocation_points(m,var=m.u,ncp=1,contset=m.t)
solver = SolverFactory('ipopt')
results = solver.solve(m,tee=False)
运行 模型导致以下错误:
Error evaluating constraint 1: can't evaluate pow'(0,0.75).
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/pyomo/opt/base/solvers.py", line 577, in solve
"Solver (%s) did not exit normally" % self.name)
pyutilib.common._exceptions.ApplicationError: Solver (asl) did not exit normally
错误的第一部分来自 Ipopt,而第二部分来自 PyOmo。显然这个问题与约束中的术语 M.P[i]**0.75
没有关系,但是改变功率并不能解决问题(尽管 2.0
确实有效)。
我该如何解决这个问题?
错误消息指出无法计算 pow'(0,0.75)
。此函数中的 '
字符表示一阶导数(''
表示二阶导数)。该消息实际上是说一阶导数不存在或导致无穷大为零。
解决这个问题很简单:将您的变量绑定到一个非零值,如下所示:
m.P = Var(m.t, bounds=(1e-20,None))
m.S = Var(m.t, bounds=(1e-20,None))
我想补充理查德的回答:
您可能还需要更新变量的初始值,因为如果未指定,ipopt 会假定为 0,因此它会在第一次迭代时评估变量的初始值。
因此:
m.P = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
m.S = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
您可以使用与您的问题更相关的值而不是 1e-20 作为初始化值