使用二进制选择器的边界优化求和函数 - GEKKO
Optimizing Summation function with bounds from binary selector - GEKKO
我正在尝试优化求和函数。从类似的 中,我找到了我问题的一半答案(我已经使我的 objective 函数类似于那个问题中的函数)。
问题:
)
尝试:
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
),如何重现此行为?谢谢。
%5C%5Cs.t.%5Cleft&space;(&space;e%5E%7Bx%7D&space;+&space;%5Csum_%7Bi=0%7D%5E%7By%7D%5Cfrac%7Bx%5Ei%7D%7Bi!%7D&space;%5Cright&space;)&space;%5Cleq&space;20)
编辑:
(修改了上面的python代码)。下图说明了这个问题。考虑 yb=[0,1,0]
=> y=2
。所以总和应该停止在 i=0 to 1

如果 x
和 yb
是普通列表,我可以很容易地做到这一点,然后我可以从下面得到预期的结果。
import numpy as np
from scipy.special import factorial
x = 3
yb = [0,1,0]
y = np.sum([yb[i]*(i+1) for i in range(3)])
yf = factorial(np.linspace(0,len(yb),len(yb)+1))
obj = np.exp(x)
for j in range(0,y):
obj += x**j/yf[j]
print(obj)
如果我不希望最终的方程大小随变量而变化,我可以执行以下操作。
x = 3
yb = [0,1,0]
y = np.sum([yb[i]*(i+1) for i in range(3)])
yf = factorial(np.linspace(0,len(yb),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 做这两个选项,因为 x
和 yb
是 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
以及为什么它只在求和函数是 objective (m.Maximze
) 时起作用,而在它时失败是一个约束(m.Equation
)。
我正在尝试优化求和函数。从类似的
问题:
尝试:
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,1,0]
=> y=2
。所以总和应该停止在 i=0 to 1
如果 x
和 yb
是普通列表,我可以很容易地做到这一点,然后我可以从下面得到预期的结果。
import numpy as np
from scipy.special import factorial
x = 3
yb = [0,1,0]
y = np.sum([yb[i]*(i+1) for i in range(3)])
yf = factorial(np.linspace(0,len(yb),len(yb)+1))
obj = np.exp(x)
for j in range(0,y):
obj += x**j/yf[j]
print(obj)
如果我不希望最终的方程大小随变量而变化,我可以执行以下操作。
x = 3
yb = [0,1,0]
y = np.sum([yb[i]*(i+1) for i in range(3)])
yf = factorial(np.linspace(0,len(yb),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 做这两个选项,因为 x
和 yb
是 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
以及为什么它只在求和函数是 objective (m.Maximze
) 时起作用,而在它时失败是一个约束(m.Equation
)。