如何通过for循环在gekko中进行约束?

How to make constriants in gekko by for loop?

根据 中关于使用字典作为 gekko 源输入的提示,我做了如下操作;

import pandas as pd
from gekko import GEKKO
my_vars = ['x1','x2','x3']

# stored as dictionaries

Cost = {'x1':100,'x2':125,'x3':80}
Min = {'x1':0,'x2':0,'x3':0}
Max = {'x1':70,'x2':40,'x3':15}

LP = GEKKO(remote=False)
va = LP.Array(LP.Var, (len(my_vars)))  # array
vd = {}                                # dictionary
for i,xi in enumerate(my_vars):
    vd[xi] = va[i]
    vd[xi].lower = Min[xi]
    vd[xi].upper = Max[xi]

# Cost function
LP.Minimize(LP.sum([Cost[xi]*vd[xi] for xi in my_vars])) 

# This also works as a dictionary
LP.Equation(LP.sum([vd[xi] for xi in my_vars])==100)

LP.solve(disp=True)

for xi in my_vars:
    print(xi,vd[xi].value[0])
print ('Cost: ' + str(LP.options.OBJFCNVAL))

这是成功的。

但假设我的变量系数为左轴,标准数据为右轴,采用数据帧格式,

例如;

Coef = [['x1', 33, 8.8, 0.2, 0.1], ['x2', 24, 4.5, 2, 0.5], ['x3', 82, '', '', '']]
LHS = pd.DataFrame(Coef, columns=['Name', 'p1', 'p2', 'p3', 'p4'])
LHS.set_index('Name')
and
goals = [['p1', 30], ['p2', 5], ['p3', 0.7], ['p4', 0.2]]
RHS = pd.DataFrame(goals, columns=['property', 'goal'])

我想在 for 循环中使用 LHS 和 RHS 数据动态构造约束。 我做了如下,

for i in range(len(RHS)):
    LP.Equation(LP.sum([LHS.iloc[list(my_vars).index(xi), i]*vd[xi] for xi in my_vars]) >= RHS.iloc[i,1])

但是有错误。


APMonitor, Version 0.9.2
APMonitor Optimization Suite


 --------- APM Model Size ------------  

Each time step contains
Objects : 6
Constants : 0
Variables : 28
Intermediates: 0
Connections : 24
Equations : 22
Residuals : 22
@error: Model Expression *** Error in syntax of function string: Invalid element: x1

Position: 7 v9-(((x1)*(v1))) ?

Traceback (most recent call last):

File "", line 1, in LP.solve(disp=True)

File "/opt/anaconda3/envs/py37/lib/python3.7/site-packages/gekko/gekko.py", line 2130, in solve raise Exception(apm_error)

Exception: @error: Model Expression *** Error in syntax of function string: Invalid element: x1

Position: 7 v9-(((x1)*(v1))) ?

我的代码有什么问题?

要正确准备 Pandas 数据框,您需要做几件事。这是一个将所有内容放在一起并提供成功解决方案的脚本。

import pandas as pd
from gekko import GEKKO
my_vars = ['x1','x2','x3']

# stored as dictionaries
Cost = {'x1':100,'x2':125,'x3':80}
Min = {'x1':0,'x2':0,'x3':0}
Max = {'x1':70,'x2':40,'x3':15}

Coef = [['x1', 33, 8.8, 0.2, 0.1],\
        ['x2', 24, 4.5, 2.0, 0.5],\
        ['x3', 82, 0.0, 0.0, 0.0]]
LHS = pd.DataFrame(Coef,\
                   columns=['Name','p1','p2','p3','p4'])
LHS = LHS.set_index('Name')
print(LHS.head())

goals = [['p1', 30], ['p2', 5], ['p3', 0.7], ['p4', 0.2]]
RHS = pd.DataFrame(goals, columns=['property', 'goal'])
RHS = RHS.set_index('property')
print(RHS.head())

LP = GEKKO(remote=False)
va = LP.Array(LP.Var, (len(my_vars)))  # array
vd = {}                                # dictionary
for i,xi in enumerate(my_vars):
    vd[xi] = va[i]
    vd[xi].lower = Min[xi]
    vd[xi].upper = Max[xi]

for yi in LHS.columns.values:
    LP.Equation(LP.sum([LHS[yi][xi]*vd[xi] for xi in my_vars]) \
                >= RHS['goal'][yi])

# Cost function
LP.Minimize(LP.sum([Cost[xi]*vd[xi] for xi in my_vars])) 

LP.solve(disp=False)

print('\n---Solution---')
for xi in my_vars:
    print(xi,vd[xi].value[0])
print ('Total Cost: ' + str(LP.options.OBJFCNVAL))

Pandas 数据帧显示常量。

      p1   p2   p3   p4
Name                   
x1    33  8.8  0.2  0.1
x2    24  4.5  2.0  0.5
x3    82  0.0  0.0  0.0
          goal
property      
p1        30.0
p2         5.0
p3         0.7
p4         0.2

问题解决方法如下:

---Solution---
x1 0.40506330168
x2 0.31898731988
x3 0.10947823632
Total Cost: 89.138004059

这适用于中小型问题。但是,如果您有 large-scale 线性规划 (LP) 问题,那么您可能需要考虑使用 Gekko 中的一些更有效的方法来解决 LP 问题。而不是自己建立方程式:

for yi in LHS.columns.values:
    LP.Equation(LP.sum([LHS[yi][xi]*vd[xi] for xi in my_vars]) \
                >= RHS['goal'][yi])

您可以让 Gekko 使用 axb 函数为您做这件事(参见示例 linear programming problems)。

A = np.array(LHS.values).T
b = np.array(RHS.values)
LP.axb(A,b,x=va,etype='>=',sparse=False)

Gekko 可以利用 Ab 常量矩阵中的稀疏性为 100,000 多个变量提供有效的解决方案。 Gekko 使用非线性规划 (NLP) 求解器来寻找 LP 问题的解决方案,因此这也可能会限制解决方案的速度,尤其是当您有超过 1M 个变量时。