Python GEKKO:非线性优化的性能优化

Python GEKKO:非线性优化的性能优化,python,nonlinear-optimization,gekko,Python,Nonlinear Optimization,Gekko,我用的是GEKKO‍。我的目标是比较GEKKO‍性能,所以我想确保我是从GEKKO获得的‍它能提供的最好的 有n个二进制变量,每个变量都分配了一个权重,每个权重都是区间[0,1]中的一个数字(即,一个有理数w满足0),一种重新表述问题以提高速度的方法是使用中间变量 原始(0.0325秒,Var=5) m.Obj(-np.prod([1-变量[i]+权重[i]*变量[i]\ 对于范围内的i(len(变量))]) 修改(0.0156秒,Var=5) ival=[m.Intermediate(1-变

我用的是
GEKKO‍。我的目标是比较
GEKKO‍性能,所以我想确保我是从
GEKKO获得的‍它能提供的最好的


有n个二进制变量,每个变量都分配了一个权重,每个权重都是区间[0,1]中的一个数字(即,一个有理数w满足0),一种重新表述问题以提高速度的方法是使用中间变量

原始(0.0325秒,Var=5)

m.Obj(-np.prod([1-变量[i]+权重[i]*变量[i]\
对于范围内的i(len(变量))])
修改(0.0156秒,Var=5)

ival=[m.Intermediate(1-变量[i]+权重[i]*变量[i])\
对于范围内的i(len(变量))]
m、 目标(-np.prod(ival))
这也可以帮助您避免字符串长度问题,除非您有非常大的
变量数
。当
权重[i]=1
变量[i]=0
时,最佳解决方案似乎总是
变量[i]=1
=0
。对于
np.prod
,这意味着如果任何一个产品项为零,则整个目标函数为零。是否有助于将单个产品值设置为
1
,而不是使用目标函数来查找值?帮助APOPT找到正确解决方案的一件事是使用类似
的方法>1.1
而不是
1.0
。因此,当您最大化时,它会尝试避免
0.1
值,以利于找到一个给出
1.1
的解决方案

从gekko导入gekko
将numpy作为np导入
m=GEKKO(远程=False)
变量的数量=5
权重=[0,1,0,1,0]
m、 options.IMODE=3
变量=m.Array(m.Var,(变量的数量),lb=0,ub=1,integer=True)
对于变量中的var:
变量值=1
ival=[m.Intermediate(1.1-变量[i]+权重[i]*变量[i])\
对于范围内的i(len(变量))]
#目标函数
m、 目标(-np.prod(ival))
#带APOPT的整数解
m、 options.SOLVER=1
m、 解算器_选项=['minlp_最大迭代次数500'\
#整数解的minlp迭代
“minlp_max_iter_,带“int_sol 10”\
#将minlp视为nlp
“minlp_as_nlp 0”\
#nlp子问题最大迭代次数
“nlp_最大迭代次数50”\
#1=深度优先,2=宽度优先
“minlp_分支_方法1”\
#与整数的最大偏差
“最小整数0.05”\
#收敛容限
“最小间隙0.01”]
m、 解决()
打印(变量)
解算器也更容易找到求和的解决方案,例如
m.sum()
,它提供了与
np.prod()
选项相同的
变量
解决方案

目标函数 m、 Obj(-m.sum(ival))
您可以添加后处理行以恢复产品目标函数,该函数将为
0
1


if3
函数对于您的应用程序不是一个好选项,因为切换条件为0,轻微的数值变化将导致不可靠的结果。根据选项
minlp\u integer\u tol=0.0,解算器将
0
0.05
0.95
1
视为整数解5
。这是一个选项,允许在整数解足够接近整数值时接受整数解。如果
变量[i]
值为
0.01
if3
函数在选择
False
选项时将选择
True
选项。如果在
m.if3(变量[i]-0.5,权重[i],1)等二进制值之间进行切换,则仍可使用
if3
函数
。但是,解决问题的方法比使用
if3
函数更简单。

重新制定问题以提高速度的一种方法是使用中间变量

原始(0.0325秒,Var=5)

m.Obj(-np.prod([1-变量[i]+权重[i]*变量[i]\
对于范围内的i(len(变量))])
修改(0.0156秒,Var=5)

ival=[m.Intermediate(1-变量[i]+权重[i]*变量[i])\
对于范围内的i(len(变量))]
m、 目标(-np.prod(ival))
这也可以帮助您避免字符串长度问题,除非您有非常大的
变量数
。当
权重[i]=1
变量[i]=0
时,最佳解决方案似乎总是
变量[i]=1
=0
。对于
np.prod
,这意味着如果任何一个产品项为零,则整个目标函数为零。是否有助于将单个产品值设置为
1
,而不是使用目标函数来查找值?帮助APOPT找到正确解决方案的一件事是使用类似
的方法>1.1
而不是
1.0
。因此,当您最大化时,它会尝试避免
0.1
值,以利于找到一个给出
1.1
的解决方案

从gekko导入gekko
将numpy作为np导入
m=GEKKO(远程=False)
变量的数量=5
权重=[0,1,0,1,0]
m、 options.IMODE=3
变量=m.Array(m.Var,(变量的数量),lb=0,ub=1,integer=True)
对于变量中的var:
变量值=1
ival=[m.Intermediate(1.1-变量[i]+权重[i]*变量[i])\
因为我在电话里
m.Obj(-np.prod([1 - variables[i] + weights[i] * variables[i] for i in range(len(variables))]))
aux_variables = [m.if3(variables[i], weights[i], 1) for i in range(len(variables))]
m.Obj(-np.prod(aux_variables))
# initialize model

m = GEKKO(remote=False)


# set global variables

m.options.SOLVER = 1 # APOPT solver
# "APOPT is an MINLP solver"
# "APOPT is also the only solver that handles Mixed Integer problems."

m.options.IMODE = 3 # steady state optimization

m.solver_options = ['minlp_maximum_iterations 500', \
                    # minlp iterations with integer solution
                    'minlp_max_iter_with_int_sol 10', \
                    # treat minlp as nlp
                    'minlp_as_nlp 0', \
                    # nlp sub-problem max iterations
                    'nlp_maximum_iterations 50', \
                    # 1 = depth first, 2 = breadth first
                    'minlp_branch_method 1', \
                    # maximum deviation from whole number
                    'minlp_integer_tol 0.05', \
                    # covergence tolerance
                    'minlp_gap_tol 0.01']

# initialize variables
variables = m.Array(m.Var, (number_of_vars), lb=0, ub=1, integer=True)

# set initial values
for var in variables:
    var.value = 1