Python 3.x Pyomo(使用couenne)无法优化功率>;=3.

Python 3.x Pyomo(使用couenne)无法优化功率>;=3.,python-3.x,pyomo,Python 3.x,Pyomo,我有一个MINLP问题要解决,当我试图优化它时,couenne崩溃了。我设法在仍然撞车的情况下将其大幅降低,并找到了可能的罪魁祸首 简化问题目标函数是一个交替多项式x[n]-x[n-1]+x[n-2]-…。有一个变量数组x[k],k=n..1,其中索引表示x的指数。还有一个限制数组强制执行此幂运算 对于大于2的功率: 如果我直接指数化x[k]=x[1]**k,那么couenne crastses 如果我级联指数x[k]=x[k-1]*x[1],couenne正常求解 所以我的问题是:从解算器

我有一个MINLP问题要解决,当我试图优化它时,couenne崩溃了。我设法在仍然撞车的情况下将其大幅降低,并找到了可能的罪魁祸首

简化问题目标函数是一个交替多项式
x[n]-x[n-1]+x[n-2]-…
。有一个变量数组
x[k],k=n..1
,其中索引表示x的指数。还有一个限制数组强制执行此幂运算

对于大于2的功率:

  • 如果我直接指数化
    x[k]=x[1]**k
    ,那么couenne crastses
  • 如果我级联指数
    x[k]=x[k-1]*x[1]
    ,couenne正常求解
所以我的问题是:从解算器的角度来看,有什么不同?这是意料之中的失败吗?我应该用另一个依赖项重新编译couenne吗

  • 我的环境是Ubuntu 18.04
  • 我使用的是通过conda安装的Pyomo 5.5(Linux 4.15.0-29-generic上的CPython 3.6.5)
  • 我自己使用默认标志编译了couenne,并下载了以下依赖项(第三方,全部使用存储库提供的wget脚本下载):ASL、Blas、Lapack、Metis和Mumps。我没有下载HSL、SCIP和SoPlex
以下是测试代码:

#! /usr/bin/env python3

import pyomo.environ
import pyomo.core as pc
from pyomo.opt import SolverFactory

def run(max_pow, cascade):
  model = pc.ConcreteModel()
  model.s = pc.RangeSet(1, max_pow)
  model.x = pc.Var(model.s, bounds=(-1,1))

  model.s_rest = pc.Set(initialize=list(ii for ii in model.s)[1:])

  ## TWO DIFFERENT WAYS OF COMPUTING POWERS ##
  if cascade: # x[k] = x[k-1]*x[1]
    model.x_c = pc.Constraint(model.s_rest, rule=lambda m, s: m.x[s] == m.x[1]*m.x[s-1])
  else:       # x[k] = x[1]**k
    model.x_c = pc.Constraint(model.s_rest, rule=lambda m, s: m.x[s] == m.x[1]**s)

  # Alternating objective function: x[k] - x[k-1] + x[k-2] - ....
  def obj(x, s, pos=True):
    result = x[s]
    if s > 1:
      result = result + obj(x, s-1, not pos)
    if not pos:
      result = -result
    return result

  model.objective = pc.Objective(rule=lambda m: obj(m.x, max_pow), sense=pc.maximize)

  opt = SolverFactory("couenne")
  results = opt.solve(model)

  model.display()

# Test 3 different cases
for max_pow, cascade in [(2, False,), (3, False,), (3, True)]:
  print("\nDegree: {}, cascade: {}".format(max_pow, cascade))
  print("-"*25)
  try:
    run(max_pow, cascade)
  except Exception as e:
    print(e)
结果如下:

Degree:2,cascade:False
-------------------------
模型未知
变量:
x:Size=2,Index=s
Key:Lower:Value:Upper:Fixed:Stale:Domain
1:-1:-1.0:1:False:False:Reals
2:-1:1.0:1:False:False:Reals
目标:
目标:大小=1,索引=无,活动=真
键:活动:值
无:正确:2.0
限制条件:
x_c:Size=1
键:下:身体:上
2 :   0.0 :  0.0 :   0.0
学位:3,等级:假
-------------------------
错误:解算器(asl)返回非零返回代码(-11)
错误:解算器日志:Couenne 0.5--混合整数的开源解算器
非线性优化邮件列表:couenne@list.coin-or.org
说明:http://www.coin-or.org/Couenne 库恩:
解算器(asl)未正常退出
学位:3,等级:真
-------------------------
模型未知
变量:
x:Size=3,Index=s
Key:Lower:Value:Upper:Fixed:Stale:Domain
1:-1:-0.002154434679988468:1:False:False:Reals
2:-1:4.6415887903301E-06:1:False:False:Reals
3:-1:-9.99999860147783E-09:1:假:假:真
目标:
目标:大小=1,索引=无,活动=真
键:活动:值
无:对:0.002149783091198271
限制条件:
x_c:尺寸=2
键:下:身体:上
2 :   0.0 :  0.0 :   0.0
3 :   0.0 :  0.0 :   0.0

Pyomo倾向于将模型完全按照您的公式发送到解算器,除非您应用一些高级转换(如GDP或DAE)

对于许多解算器来说,
x*x*x
形式的表达式处理方式与
x**3
不同。在某些系统中,即使是
x**2
pow(x,2)
,和
sqr(x)
也会给您带来不同的行为。虽然在数学上是等效的,但对边界行为和域限制的处理可能会有所不同