如果我的目标函数是非线性(也是指数解释)函数,应该使用什么求解器?Python GEKKO

Ser*_*gio 5 python optimization nonlinear-optimization exponential gekko

我正在尝试使用GEKKO优化指数目标函数,但是我不知道所选的求解器是否是解决此类问题的最佳方法。

被选择的一个是有效的选择吗?

import numpy as np

'GEKKO MODELING'
from gekko import GEKKO
m = GEKKO()
m.options.SOLVER=1  # APOPT is an MINLP solver

# Initialize variables
x = []
x1 = m.Var(value=20,lb=20, ub=6555)  #integer=True
x2 = m.Var(value=0,lb=0,ub=10000)  #integer=True
x3 = m.sos1([30, 42, 45, 55])

x = [x1, x2, x3]
# Equations
m.Equation((x1 * x2* x3) * 10 ** (-6)>=50)

def fun(x):
    return 44440 + ((np.pi * x[0] * x[1] * x[2]) * 10 ** (-4))**0.613

x = [400,300,19]

'GEKKO Optimization'
m.Obj(fun(x))

m.solve(disp=False) # Solve
print('Results')
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))

print('Objective: ' + str(m.options.objfcnval))
Run Code Online (Sandbox Code Playgroud)

Joh*_*ren 5

脚本的问题在于,您x = [400,300,19]在调用目标函数之前要重新定义的值。应该使用原始定义来调用目标函数,x = [x1, x2, x3]以便可以优化这些变量。另一项更改是,x3默认情况下,的值等于零。将其设置为零x3.value=1.0可以使APOPT和IPOPT求解器收敛,因为您之前是从虚数目标的边界开始的x3<0

import numpy as np
from gekko import GEKKO
m = GEKKO()
x = []
x1 = m.Var(value=20,lb=20, ub=6555)  #integer=True
x2 = m.Var(value=1,lb=1,ub=10000)  #integer=True
x3 = m.sos1([30, 42, 45, 55])
x3.value = 1.0
x = [x1, x2, x3]
m.Equation((x1 * x2* x3) * 1e-6 >= 50)
def fun(x):
    return 44440 + ((np.pi * x[0] * x[1] * x[2]) * 1e-4)**0.613
m.Obj(fun(x))

# Change to True to initialize with IPOPT
init = False
if init:
    m.options.SOLVER=3  
    m.solve(disp=False) # Solve

m.options.SOLVER=1
m.solve(disp=True) # Solve

print('Results')
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('Objective: ' + str(m.options.objfcnval))
Run Code Online (Sandbox Code Playgroud)

对于求解器的建议,以下是Gekko中公开可用的求解器列表。Gekko中还有其他可商购的求解器选项,但对于此响应,我将仅坚持使用可公开访问的解决方案(APOPT,BPOPT和IPOPT)。任何非线性规划求解器都应能够处理非线性目标,如x**0.613。您的问题还包括类型1特殊有序集(m.sos1),因此您的问题不仅是非线性编程(NLP)问题,还包括的二进制变量sos1。这意味着您需要使用混合整数非线性编程(MINLP)求解器。APOPT求解器是Gekko中唯一公开提供的MINLP求解器,在您创建APOPT求解器时会自动为您选择sos1宾语。如果您想尝试使用NLP求解器(例如IPOPT)来解决MINLP问题,则创建m.sos1对象需要指定求解器。

m.options.SOLVER = 3
Run Code Online (Sandbox Code Playgroud)

这可能会导致不正确的解决方案,因为x3只能是以下情况之一:30, 42, 45, 55。IPOPT找到一个最小解,x3==47.079550873因此在这种情况下,它没有返回整数解。如果要保证整数解,则需要使用APOPT。

 Successful solution

 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :   4.279999999562278E-002 sec
 Objective      :    44813.4405591393     
 Successful solution
 ---------------------------------------------------

Results
x1: [677.59896405]
x2: [2459.665311]
x3: [30.0]
Objective: 44813.440559
Run Code Online (Sandbox Code Playgroud)

如果您需要更改MINLP APOPT求解器的某些调整参数,则可以使用以下内容:

m.solver_options = ['minlp_gap_tol 1.0e-2',\
                    'minlp_maximum_iterations 10000',\
                    'minlp_max_iter_with_int_sol 500']
Run Code Online (Sandbox Code Playgroud)

对APOPT求解器选项的其他信息