微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用二进制选择器的边界优化求和函数 - GEKKO

如何解决使用二进制选择器的边界优化求和函数 - GEKKO

我正在尝试优化求和函数。从类似的 question 中,我找到了我问题的一半答案(我已经使我的目标函数类似于该问题中的目标函数)。

问题:

尝试:

from gekko import GEKKO
import numpy as np
from scipy.special import factorial

m = GEKKO(remote=False)
x = m.sos1([1,2,3])
yb = m.Array(m.Var,3,lb=0,ub=1,integer=True)
m.Equation(m.sum(yb)==1)
y = m.sum([yb[i]*(i+1) for i in range(3)])
m.Equation(m.sum([yb[i]*(i+1) for i in range(3)])<2)
yf = factorial(np.linspace(0,len(yb),len(yb)+1))
obj = m.exp(x)
for j in range(0,len(yb)):
    obj += x**j/yf[j]
    m.Maximize(obj*yb[j])
m.solve()
print('x='+str(x.value[0]))
print('y='+str(y.value[0]))
print('Objective='+str(-m.options.objfcnval))

这有效,但仅当我在 for 循环中添加 m.Maximize 时才有效。在循环内没有 m.Maximize 的情况下运行相同的结果会产生错误的结果(如下所示)。问题在于二元选择器 yb。当 yb = [0,1,0] => y=2 时,求和界限将为 i=0 到 2。但我无法获得此行为。我无法使用 range(y) 运行 for 循环,因为它是一个 GKVariable 并且它会随着变量值的变化而改变方程的大小。

obj = m.exp(x) + x**0/yf[0]
for j in range(1,len(yb)+1):
    obj += x**j/yf[j]*yb[j-1] # It non-zero only when yb[j-1]=1 and misses the values before that.
#Without it I'm computing the entire bound everytime and changing yb has no impact.
m.Maximize(obj)

在工作解决方案中,Gekko 如何给我正确的结果?当函数是如下约束时(即在 for 循环中不使用 m.maximize),如何重现这种行为?谢谢。

编辑: (修改了上面的python代码)。下图说明了这个问题。考虑yb=[0,0] => y=2。所以求和应该停在 i=0 to 1

如果 xyb 是普通列表,我可以轻松做到这一点,然后我可以从下面得到预期的结果。

import numpy as np
from scipy.special import factorial

x = 3
yb = [0,0]
y = np.sum([yb[i]*(i+1) for i in range(3)])
yf = factorial(np.linspace(0,len(yb)+1))
obj = np.exp(x)
for j in range(0,y):
    obj += x**j/yf[j] 
print(obj)

如果我不希望最终方程大小随变量变化,我可以执行以下操作。

x = 3
yb = [0,len(yb)+1))
obj = np.exp(x)
for i in range(0,y):
    yb[i] = 1
for j in range(0,len(yb)):
    obj += (x**j/yf[j]) * yb[j]
print(obj)

我不能用 Gekko 做这两个选项,因为 xyb 是 GKVariable(设计变量)并且不能被解释为整数(即​​)range(y) 不起作用。有什么解决方法吗?谢谢。

解决方法

由于没有任何回复,我正在分享我想出的解决方法。这可能不是一种有效的方法,但它确实有效。

m = GEKKO(remote=False)
x = m.sos1([1,2,3])
yb = m.Array(m.Var,3,lb=0,ub=1,integer=True)
m.Equation(m.sum(yb)==1)
y = m.sum([yb[i]*(i+1) for i in range(3)])
#m.Equation(m.sum([yb[i]*(i+1) for i in range(3)])<2)
yf = factorial(np.linspace(0,len(yb),len(yb)+1))
obj = m.exp(x) + x**0/yf[0]
obj_temp=[]
for j in range(1,len(yb)+1):
    obj_temp.append(x**j/yf[j])
    for k in range(j):
        obj+= obj_temp[k] * yb[j-1]
m.Maximize(obj)        
m.solve()
print('x='+str(x.value[0]))
print('y='+str(y.value[0]))
print('Objective='+str(-m.options.objfcnval))

然而,我不知道 Gekko 如何在内部复制这个额外的 for loop 以及为什么它只在求和函数是目标(m.Maximze)时才有效,而在它是约束时失败({{ 1}}).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。