繁体   English   中英

如何在 python 中将 sos1 与 GEKKO 阵列一起使用?

[英]How to use sos1 with GEKKO Array in python?

我正在尝试使用 GEKKO 解决优化问题,我必须设置有关解决方案值的特定约束。 我正在使用 sos1 来做到这一点。 但是,我很难尝试将 sos1 与 GEKKO.Array() 一起使用。

如果我使用以下代码,我会得到一个依赖于约束的结果:

from gekko import GEKKO
import numpy as np

# Initialize Model
m = GEKKO(remote=True)
eq = m.Param(value=40)
x1 = m.sos1([1.2, 1.5, 2, 3, 3.5])
x2 = m.sos1([i for i in np.arange(1, 5, 1)])
x3 = m.sos1([i for i in np.arange(1, 5, 1)])
x4 = m.sos1([i for i in np.arange(1, 5, 0.5)])

x1.value = 1
x2.value = 5
x3.value = 5
x4.value = 1

x1.lower = 1
x2.lower = 1
x3.lower = 1
x4.lower = 1

x1.upper = 5
x2.upper = 5
x3.upper = 5
x4.upper = 5

m.Equation(x1*x2*x3*x4>=25)
m.Equation(x1**2+x2**2+x3**2+x4**2==eq)

#Objective
m.Obj(x1*x4*(x1+x2+x3)+x3)

#Set global options
m.options.IMODE = 3 #steady state optimization

m.solve()

#Results
print('')
print('Results')
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('x4: ' + str(x4.value))

我正在尝试将 sos1 与 Array 一起使用,如下所示:

from gekko import GEKKO
import numpy as np

# Initialize Model
m = GEKKO(remote=True)
eq = m.Param(value=40)
x = m.Array(m.Var, 4)
i = 0
value = [1, 5, 5, 1]
l = [1, 1, 1, 1]
u = [5, 5, 5, 5]
specific_values = [[1.2, 1.5, 2, 3, 3.5], [1, 2, 3, 4], [1, 2, 3, 4], [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]]

for xi in x:
    xi.value = value[i]
    xi.lower = l[i]
    xi.upper = u[i]
    xi = m.sos1(specific_values[i])
    i+=1

m.Equation(np.prod(x)>=25)
m.Equation(x[0]**2+x[1]**2+x[2]**2+x[3]**2==eq)

#Objective
m.Obj(x[0]*x[3]*(x[0]+x[1]+x[2])+x[2])

#Set global options
m.options.IMODE = 3 #steady state optimization

m.solve()

#Results
print('')
print(x[0].value, x[1].value, x[2].value, x[3].value)

结果与我尝试在没有 sos1 的情况下优化 function 相同。 此外,似乎 sos1 正在覆盖下限和上限的值。 我究竟做错了什么? 有没有办法将 sos1 与 gekko 数组一起使用?

编辑:我检查了数组不支持 sos1,所以我没有创建一个数组,而是尝试在 for 循环中单独创建一个 sos1 列表并且它有效。 它需要对方程式定义进行一些小的修改,但它很简单。

from gekko import GEKKO
import numpy as np
# Initialize Model
m = GEKKO(remote=True)
eq = m.Param(value=40)
specific_values = [[1.2, 1.5, 2, 3, 3.5], [1, 2, 3, 4], [1, 2, 3, 4], [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]]

x = [m.sos1(specific_values[i]) for i in range(4)] # m.Array(m.Var, 4)
i = 0
value = [1, 5, 5, 1]
l = [1, 1, 1, 1]
u = [5, 5, 5, 5]

for xi in x:
    xi.value = value[i]
    print(specific_values[i])
    xi.lower = l[i]
    xi.upper = u[i]
    
    print(xi.lower, xi.upper, xi.value)
    i+=1

m.Equation(np.prod(np.asarray(x))>=25)
m.Equation(np.sum(np.asarray(x)**2)==eq)

#Objective
m.Obj(x[0]*x[3]*(x[0]+x[1]+x[2])+x[2])

#Set global options
m.options.IMODE = 3 #steady state optimization

m.solve()

# Results
print('')
print(x[0].value, x[1].value, x[2].value, x[3].value)

正如作者在编辑中所讨论的,使用for循环或列表推导来创建特殊有序集 ( sos1() ) 变量的列表。 以下是问题作者提供的答案中的示例:

specific_values = [[1.2, 1.5, 2, 3, 3.5],
                   [1, 2, 3, 4],
                   [1, 2, 3, 4],
                   [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]]
x = [m.sos1(specific_values[i]) for i in range(4)]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM