【问题标题】:How to make constriants in gekko by for loop?如何通过 for 循环在 gekko 中进行约束?
【发布时间】:2021-02-11 02:34:06
【问题描述】:

根据a related question 中关于使用字典作为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))

这很成功。

但假设我将变量系数作为 LHS,将标准数据作为 RHS,采用数据框格式,

例如;

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,版本 0.9.2
APMonitor 优化套件


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

每个时间步包含
对象:6
常量:0
变量:28
中间体:0
连接数:24
方程式:22
残差:22
@error: 模型表达式 *** 错误 函数字符串的语法:无效元素:x1

位置:7 v9-(((x1)*(v1))) ?

Traceback(最近一次通话最后一次):

文件“”,第 1 行,在 LP.solve(disp=True)

文件 “/opt/anaconda3/envs/py37/lib/python3.7/site-packages/gekko/gekko.py”, 第 2130 行,在求解 引发异常(apm_error)

异常:@error:模型表达式 *** 函数语法错误 字符串:无效元素:x1

位置:7 v9-(((x1)*(v1))) ?

我的代码有什么问题?

【问题讨论】:

    标签: python for-loop constraints linear-programming gekko


    【解决方案1】:

    为了正确准备 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
    

    这适用于中小型问题。但是,如果您有大规模线性规划 (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])
    

    您可以使用 axb 函数让 Gekko 为您完成(参见示例 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+ 变量的情况下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多