我不熟悉优化,我想实现以下目标:

假设我有3个常量列表:

list_1 = [1, 2, 3, 4]
list_2 = [5, 8, 10, 11]
list_3 = [20, 27, 89, 100]

我想找3个索引i1, i2, i3,与上面的3个列表相对应,这样总和就会最小化:min(list_1[i1] + list_2[i2] + list_3[i3])

受一些限制的限制:

i1 >= 0
i2 >= 0
i3 >= 0
i1 + i2 + i3 == 4
64 * i1 + 72 * i2 + 74 * i3 >= 240

我试着写成:

from gekko import GEKKO

m = GEKKO()

x_1_storage = m.Array(m.Const, 4)
x_1_values = [1, 2, 3, 4]
i = 0
for xi in x_1_storage:
    xi.value = x_1_values[i]
    i += 1

x_2_storage = m.Array(m.Const, 4)
x_2_values = [5, 8, 10, 11]
i = 0
for xi in x_2_storage:
    xi.value = x_2_values[i]
    i += 1

x_3_storage = m.Array(m.Const, 4)
x_3_values = [20, 27, 89, 100]
i = 0
for xi in x_3_storage:
    xi.value = x_3_values[i]
    i += 1


x,y,z = m.Array(m.Var,3,integer=True,lb=0) 
m.Minimize(x_1_storage[x.value.value] + x_2_storage[y.value.value] + x_3_storage[z.value.value])
m.Equations([x>=0,
             y>=0,
             z>=0,
             x+y+z==4,
             64*x + 72*y + 74*z >= 240])
m.options.SOLVER = 1
m.solve()
print('Objective: ', m.options.OBJFCNVAL)
print('x: ', x.value[0])
print('y: ', y.value[0])
print('z: ', z.value[0])

然而,打印的目标值是26,而正确的目标值应该是4,因为x_1_storage[4] = 4.以某种方式,每个列表中的第一个元素被添加为目标值.我的印象是,表达目标的方式有问题:

m.Minimize(x_1_storage[x.value.value] + x_2_storage[y.value.value] + x_3_storage[z.value.value])

然而,我不太确定在这种情况下该怎么做.如有任何提示,我们不胜感激.

推荐答案

.value属性仅用于存储m.solve()之前的初始猜测值以及在求解后报告解.如果在表达式中使用这些值,则它们将是优化问题中的常量值.

解决方案i1=4是不正确的,因为指数从03.下面是解决问题的另一种形式.三次样条线对象cspline用于将索引决策变量与目标函数的x_store列表值相关联.

from gekko import GEKKO

m = GEKKO(remote=True)

# index decision variable
x = m.Array(m.Var,3,value=4,lb=0,ub=3,integer=True)
i1,i2,i3 = x

# cublic spline
ix = [0,1,2,3]
list_1 = [1, 2, 3, 4]
list_2 = [5, 8, 10, 11]
list_3 = [20, 27, 89, 100]
y = m.Array(m.Var,3)
y1,y2,y3 = y
for i,iy in enumerate([list_1,list_2,list_3]):
    m.cspline(x[i],y[i],ix,iy,bound_x=True)

# constraints
m.Equations([i1+i2+i3==4,
             64 * i1 + 72 * i2 + 74 * i3 >= 240])
             
# objective
m.Minimize(y1+y2+y3)

# solve
m.options.SOLVER = 1
m.solve()

# print solution
print(f'x: {x}')
print(f'y: {y}')
print(f'objective: {m.options.OBJFCNVAL}')

解决方案:

x: [[3.0] [1.0] [0.0]]
y: [[4.0] [8.0] [20.0]]
objective: 32.0

如果允许索引在1和4之间,则解i1=4是不正确的,因为如果存在i1>=1i2>=1i3>=1的下界,则约束i1+i2+i3=4是不可行的.如果它是基于1的索引,则不允许使用i2=0i3=0.

from gekko import GEKKO

m = GEKKO(remote=False)

# index decision variable
x = m.Array(m.Var,3,lb=1,ub=4,integer=True)
i1,i2,i3 = x

# cublic spline
ix = [1,2,3,4]
list_1 = [1, 2, 3, 4]
list_2 = [5, 8, 10, 11]
list_3 = [20, 27, 89, 100]
y = m.Array(m.Var,3)
y1,y2,y3 = y
for i,iy in enumerate([list_1,list_2,list_3]):
    m.cspline(x[i],y[i],ix,iy,bound_x=True)

# constraints
m.Equations([i1+i2+i3==4,
             64 * i1 + 72 * i2 + 74 * i3 >= 240])
             
# objective
m.Minimize(y1+y2+y3)

# solve
m.options.SOLVER = 1
m.solve()

# print solution
print(f'x: {x}')
print(f'y: {y}')
print(f'objective: {m.options.OBJFCNVAL}')

解决方案是:

x: [[2.0] [1.0] [1.0]]
y: [[2.0] [5.0] [20.0]]
objective: 27.0

Python相关问答推荐

枢轴框架值及其单位

网页抓取数据框架但只有500个字节

为什么自定义pytree aux_data对于jnp.数组来说在.jit()之后跟踪,而对于np.数组来说则不是?

Python 枕头上的图像背景变黑

Pandas .类型错误:只能将字符串(而不是int)连接到字符串

调试回归无法解决我的问题

当变量也可以是无或真时,判断是否为假

Python:MultiIndex Dataframe到类似json的字典列表

Django序列化器没有验证或保存数据

合并同名列,但一列为空,另一列包含值

无法导入已安装的模块

在matplotlib动画gif中更改配色方案

如果条件为真,则Groupby.mean()

Python库:可选地支持numpy类型,而不依赖于numpy

PMMLPipeline._ fit()需要2到3个位置参数,但给出了4个位置参数

所有列的滚动标准差,忽略NaN

Pandas Loc Select 到NaN和值列表

如何在turtle中不使用write()来绘制填充字母(例如OEG)

实现神经网络代码时的TypeError

启动带有参数的Python NTFS会导致文件路径混乱