我在一个简单的MINLP模型中有以下约束:
model.cm2=Constraint(expr = model.xB2 == log(1.0+model.xA2))
当我调用bonmin(来自AMPL的windows64二进制发行版)时,这种方法有效
当切换到couenne求解器时,我需要转换为log10 base
model.cm2=Constraint(expr = model.xB2 == 2.3*log10(1.0+model.xA2))
否则我得到错误:
ApplicationError: Solver (asl) did not exit normally.
model.pprint() gives in the first case:
cm2 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : 0.0 : xB2 - log( 1.0 + xA2 ) : 0.0 : True
我使用anaconda python安装并使用spyder .
有没有人知道这种行为的原因?
我已经阅读了jsiirola的评论,但我认为问题不在于评估负数的日志 . 这是一个完整的测试问题,行为方式相同 . 如果我用bonmin解决,我可以使用log()如果我使用cuonne我必须使用ln(10)* log10() .
from pyomo.environ import *
solverpathb="..\\solversAMPL\\bonmin\\bonmin"
solverpathc="..\\solversAMPL\\couenne\\couenne"
model=ConcreteModel()
model.x = Var(within=NonNegativeReals,bounds=(1,2),doc='Nonnegative')
model.y = Var(within=NonNegativeReals,doc='Nonnegative')
model.obj = Objective(expr= model.x+model.y, sense=maximize)
model.c1=Constraint(expr = model.y == log(1.0+model.x))
#model.c2=Constraint(expr = model.y == 2.3*log10(1.0+model.x))
#Works with version c1 and c2 of the constraint
#solver = pyomo.opt.SolverFactory("bonmin", executable=solverpathb)
#only constraint c2 works with this solver
solver = pyomo.opt.SolverFactory("couenne", executable=solverpathc)
results = solver.solve(model, tee = True)
model.display()
应包含错误的日志文件仅包含模型 . 这是错误的最后一部分 . ...文件“C:/../ testproblem.py”,第24行,结果= solver.solve(model,tee = True)
文件“C:\ Users .. \ Python \ Python36 \ site-packages \ pyomo \ opt \ base \ solvers.py”,第623行,解决“求解器(%s)未正常退出”%self.name)
ApplicationError:Solver(asl)没有正常退出 .
注意:我可以使用以下代码作为对象函数,也可以使用couenne
model.obj = Objective(expr= model.x+log(1.0+model.x), sense=maximize)
2 回答
使用COIN-OR的二进制分布解决了这个问题,它不是一个pyomo问题 . 从ampl.com下载的couenne的二元分布由于某些奇怪的原因,不接受log-function,只接受log10 .
首先,在调试这样的问题时,整个模型最有用 . 第二,当Couenne异常退出时会抛出什么错误?
至于答案:
Pyomo对BONMIN和Couenne使用相同的接口(它们都通过ASL),所以你不应该仅仅因为切换求解器而改变你的表达式 .
log
和log10
当然不是同一个功能,所以你没有解决同样的问题 .我怀疑问题是
model.xA2
小于或等于-1(即,解算器要求ASL评估log(0)
. 验证这一点的方法是通过查看求解器日志 . 另外,你需要确保Pyomo向解算器发送"symbolic"标签,以便错误引用实际的变量/约束名称,而不仅仅是错误消息中的"x1, x2, x3, ..."和"c1, c2, c3, ..." .Couenne是一个全局求解器,而BONMIN是一个局部求解器 . 由于这是一个非凸的问题,Couenne可能正在探索BONMIN从未去过的解决方案空间的一部分 .