如何使用 gekko 优化列表切片的索引

问题描述 投票:0回答:1

如果我有一个像 python 中那样的字符串列表,如下所示:

my_list = ["x", "y", "x", "x", "x", "x", "y"]
我想最大化“x”的数量,同时也最大化两个索引之外的“y”的数量 我该如何使用 GEKKO 来做到这一点?

这是我的想法:

from gekko import GEKKO
m = GEKKO(remote=False)

def count_x(lst):
    return sum([1 if item == 'x' else 0 for item in lst])

def count_y(lst):
    return len(lst) - count_x(lst)

my_list = ["x", "y", "x", "x", "x", "x", "y"]
def loss_function(x) -> int:
        x_0 = int(str(x[0].value))
        x_1 = int(str(x[1].value))
        return -1*count_y(my_list[:x_0]) - count_x(my_list[x_0:x_1]) - count_y(my_list[x_1:])

x = m.Array(m.Var, 2, lb=0, ub=len(my_list),integer=True)
m.Minimize(loss_function(x))
m.Equation(x[0] <= x[1])
m.solve()
print(x)

当我取出 x_0 和 x_1 时,出现此错误:

TypeError: slice indices must be integers or None or have an __index__ method

当我离开 x_0 和 x_1 时,我得到以下输出:

WARNING: objective equation 2 has no variables ss.Eqn(2) 0 = -4

我期望得到的是 [[2.0] [6.0]] 但我得到的是 [[0.0] [0.0]]

预先感谢您的帮助!

gekko
1个回答
0
投票

Gekko 构建模型一次,然后将其传递给混合整数非线性规划求解器 (APOPT)。 Python 函数没有回调。这是解决问题的一种方法,使用二进制变量来指示在选择中最大化

x
和最小化
y
的部分。

from gekko import GEKKO
import numpy as np

m = GEKKO(remote=False)

def opt_seg(z):
    nz = len(z)
    zb = [1 if i=='x' else 0 for i in z]

    b = m.Array(m.Var,nz,value=1,lb=0,ub=1,integer=True)
    [m.Maximize(zb[i]*b[i]) for i in range(nz)]
    [m.Minimize(2*(1-zb[i])*b[i]) for i in range(nz)]

    d = [m.Intermediate(b[i]-b[i-1]) for i in range(1,nz)]
    m.Equation(m.sum(d)==0)

    m.options.SOLVER = 1
    m.solve(disp=False)

    return (np.argmax(d)+1,np.argmin(d)+1)
    
z = ["x", "y", "x", "x", "x", "x", "y"]
print('-'*10)
print(z)
print(opt_seg(z))

z = ["x", "y", "y", "x", "x", "y", "y"]
print('-'*10)
print(z)
print(opt_seg(z))

z = ["y", "x", "x", "x", "y", "x", "y", "y", "x", "x", "y"]
print('-'*10)
print(z)
print(opt_seg(z))

对解进行后处理以获得范围。这是几个不同测试条件下的输出:

----------
['x', 'y', 'x', 'x', 'x', 'x', 'y']
(2, 6)
----------
['x', 'y', 'y', 'x', 'x', 'y', 'y']
(3, 5)
----------
['y', 'x', 'x', 'x', 'y', 'x', 'y', 'y', 'x', 'x', 'y']
(1, 4)
© www.soinside.com 2019 - 2024. All rights reserved.