您的脚本的一个问题是您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))
对于求解器建议,这里是Gekko 中公开可用的求解器列表。Gekko 中还有其他商业可用的求解器选项,但对于此响应,我将只使用可公开访问的求解器选项(APOPT、BPOPT 和 IPOPT)。任何非线性规划求解器都应该能够处理非线性目标,例如x**0.613
. 您的问题还包括特殊有序集,类型 1 (m.sos1),因此您的问题不仅是非线性规划 (NLP) 问题,还包括sos1
. 这意味着您需要使用混合整数非线性规划 (MINLP) 求解器。APPT 求解器是 Gekko 中唯一公开可用的 MINLP 求解器,当您创建一个sos1
目的。如果您想尝试使用 NLP 求解器(例如 IPOPT)解决 MINLP 问题,则需要在创建对象后指定求解器。m.sos1
m.options.SOLVER = 3
这可能会导致错误的解决方案,因为x3
只能是以下之一:30, 42, 45, 55
. 在这种情况下, IPOPT 找到了 so 的最小解x3==47.079550873
,它没有返回整数解。如果要保证整数解,则需要使用 APPT。
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
如果您需要更改 MINLP APOPT 求解器的某些调整参数,则可以使用如下内容:
m.solver_options = ['minlp_gap_tol 1.0e-2',\
'minlp_maximum_iterations 10000',\
'minlp_max_iter_with_int_sol 500']
有关于 APPT 求解器选项的附加信息。