【问题标题】:Max equation length limit in Gekko constraintGekko 约束中的最大方程长度限制
【发布时间】:2020-10-03 22:27:05
【问题描述】:

我正在努力在约束条件下优化一长串方程。目标函数可以拆分为多个目标函数,但我无法以任何我能找到的方式拆分我的约束函数。在上个月,我尝试以几种不同的方式解决这个问题,同时使用 sympy 和 scipy.optimize,但都需要很长时间才能运行。在此示例中,我将长度限制为出现错误的最短长度之一,但我希望能够通过增加constraintmonth、nummonthstodo 并添加到db1permonth 来尽可能多地扩展它。我怎样才能绕过长度限制错误:

Exception:  @error: Max Equation Length
 Error with line number:           67
 (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
 [...lots of numbers here..]
 0/(1.0+(2.718281828459045^(-(((v14-476.0))/(120)))))))))+((-2.02635827)*((200.0
 /(1.0+(2.718281

 APM model error: string >       15000  characters
 Consider breaking up the line into multiple equations

 The may also be due to only using newline character CR
   instead of CR LF (for Windows) or LF (for MacOS/Linux)
 To fix this problem, save APM file with appropriate newline characters

 STOPPING...

在这段代码中:

import numpy as np
from gekko import GEKKO    
from math import e


m = GEKKO()

nummonthstodo = 20
constraintmonth = 15
markets=3
fudgefactor = 1.18
constraint = -100000
ig = np.tile([1169.00,476.00,191.00],(nummonthstodo))
dynamic_scale = np.tile(np.array([100,120,80]),nummonthstodo)
turning_point =np.tile( np.array([1169.00,476.00,191.00]),nummonthstodo)
eo14_scale = np.tile(np.array([72.00,200.00,500.00]),nummonthstodo)
db1life = np.tile(np.array([2131.64415,  927.62553,  376.79813]),nummonthstodo)

db1permonth = np.array([-7.69469125e+01, -8.27515903e+01, -8.23699131e+01,  4.45215469e+02,
        3.69705278e+02,  1.58977477e+02, -3.88706011e+00, -3.02636074e+00,
       -2.79420475e+00, -7.67567831e-01, -3.03178864e+00, -2.79921627e+00,
        6.82114433e+01,  5.11866268e+01,  7.41661986e+01, -3.22847133e+00,
       -2.28929507e+00, -1.28846317e+00, -7.10922109e-01, -2.29483815e+00,
       -1.29158293e+00,  5.33895986e+01,  3.53279803e+01,  4.70884129e+01,
       -2.98307479e+00, -2.02448766e+00, -8.09906719e-01, -8.69398271e-01,
       -2.02635827e+00, -8.10655068e-01,  4.40599327e+01,  2.74298296e+01,
        3.40114832e+01, -2.83729295e+00, -1.90180770e+00, -5.82931770e-01,
       -4.06643364e+01, -2.85105835e+01, -8.73890925e+00,  2.05687539e+02,
        1.15368035e+02,  2.54844135e+01, -1.93419651e+00, -1.17779492e+00,
       -4.36383453e-01, -3.54686842e-01, -1.17891974e+00, -4.36800210e-01,
        3.28820412e+01,  1.73557733e+01,  2.03414999e+01, -1.85294103e+00,
       -1.09751072e+00, -3.47833721e-01, -4.44622167e-01, -1.09856091e+00,
       -3.48166558e-01,  2.90051018e+01,  1.46659871e+01,  1.69382174e+01])



x = m.Array(m.Var,(len(ig)))

# lower bounds
for i,xi in enumerate(x):
    xi.value = ig[i]
    xi.lower = 0
    xi.upper = 1500


def eo14(a,b):
    return np.divide(np.tile(eo14_scale[0:3],int((b-a)/3)),(np.ones(b-a)+e**(-np.divide((x[a:b]-np.tile(turning_point[0:3],int((b-a)/3))),np.tile(dynamic_scale[0:3],int((b-a)/3))))))
def db1(a,b):
    return db1permonth[a:b]
def cac(a,b):
    return x[a:b]

eo14s = [eo14(i*markets,(i+1)*markets) for i in range(nummonthstodo)]
db1s = [db1(i*markets,(i+1)*markets) for i in range(nummonthstodo)]
cacs = [cac(i*markets,(i+1)*markets) for i in range(nummonthstodo)]

db1month = 0

for i in range(constraintmonth):
    for j in range(constraintmonth-i):
        db1month = db1month + np.multiply(db1s[j],eo14s[i])

spend = 0

for i in range(constraintmonth):
        spend = spend + np.multiply(cacs[i],eo14s[i])

alleo14 = eo14(0,len(ig))

m.Equation(m.sum(db1month - spend) >= constraint)

for i in range(len(ig)):
   m.Obj(-(np.multiply(db1life-x,alleo14))[i])

m.solve()

print(x)

提前感谢您提供的任何帮助,作为数据科学的学生和初学者,这确实让我头疼了一段时间。

【问题讨论】:

    标签: python numpy gekko


    【解决方案1】:

    您可以通过将您的产品声明为列表来克服最大方程式长度,然后使用m.sum()。否则,它会构建一个非常大的表达式,超过每个方程 15,000 个字符的限制。您还可以使用m.Intermediate() 变量来减小表达式大小。这是您的程序的新版本,已成功求解。

    import numpy as np
    from gekko import GEKKO    
    from math import e
    
    m = GEKKO(remote=False)
    
    nummonthstodo = 20
    constraintmonth = 15
    markets=3
    fudgefactor = 1.18
    constraint = -100000
    ig = np.tile([1169.00,476.00,191.00],(nummonthstodo))
    dynamic_scale = np.tile(np.array([100,120,80]),nummonthstodo)
    turning_point =np.tile( np.array([1169.00,476.00,191.00]),nummonthstodo)
    eo14_scale = np.tile(np.array([72.00,200.00,500.00]),nummonthstodo)
    db1life = np.tile(np.array([2131.64415,  927.62553,  376.79813]),nummonthstodo)
    
    db1permonth = np.array([-7.69469125e+01, -8.27515903e+01, -8.23699131e+01,  4.45215469e+02,
            3.69705278e+02,  1.58977477e+02, -3.88706011e+00, -3.02636074e+00,
           -2.79420475e+00, -7.67567831e-01, -3.03178864e+00, -2.79921627e+00,
            6.82114433e+01,  5.11866268e+01,  7.41661986e+01, -3.22847133e+00,
           -2.28929507e+00, -1.28846317e+00, -7.10922109e-01, -2.29483815e+00,
           -1.29158293e+00,  5.33895986e+01,  3.53279803e+01,  4.70884129e+01,
           -2.98307479e+00, -2.02448766e+00, -8.09906719e-01, -8.69398271e-01,
           -2.02635827e+00, -8.10655068e-01,  4.40599327e+01,  2.74298296e+01,
            3.40114832e+01, -2.83729295e+00, -1.90180770e+00, -5.82931770e-01,
           -4.06643364e+01, -2.85105835e+01, -8.73890925e+00,  2.05687539e+02,
            1.15368035e+02,  2.54844135e+01, -1.93419651e+00, -1.17779492e+00,
           -4.36383453e-01, -3.54686842e-01, -1.17891974e+00, -4.36800210e-01,
            3.28820412e+01,  1.73557733e+01,  2.03414999e+01, -1.85294103e+00,
           -1.09751072e+00, -3.47833721e-01, -4.44622167e-01, -1.09856091e+00,
           -3.48166558e-01,  2.90051018e+01,  1.46659871e+01,  1.69382174e+01])
    
    x = m.Array(m.Var,len(ig),lb=0,ub=1500)
    for i,xi in enumerate(x):
        xi.value = ig[i]
    
    def eo14(a,b):
        return np.divide(np.tile(eo14_scale[0:3],int((b-a)/3)),\
                         (np.ones(b-a)+e**(-np.divide((x[a:b]\
                            -np.tile(turning_point[0:3],int((b-a)/3))),\
                                np.tile(dynamic_scale[0:3],int((b-a)/3))))))
    def db1(a,b):
        return db1permonth[a:b]
    def cac(a,b):
        return x[a:b]
    
    eo14s = [eo14(i*markets,(i+1)*markets) for i in range(nummonthstodo)]
    db1s = [db1(i*markets,(i+1)*markets) for i in range(nummonthstodo)]
    cacs = [cac(i*markets,(i+1)*markets) for i in range(nummonthstodo)]
    
    prod1 = [db1s[j]*eo14s[i] for j in range(constraintmonth-i) \
                             for i in range(constraintmonth)]
    db1month = m.sum(prod1)
    
    prod2 = [cacs[i]*eo14s[i] for i in range(constraintmonth)]
    spend = m.sum(prod2)
    
    alleo14 = eo14(0,len(ig))
    
    m.Equation(db1month - spend >= constraint)
    
    for i in range(len(ig)):
       m.Maximize((np.multiply(db1life-x,alleo14))[i])
    
    m.solve()
    
    print(x)
    

    这给出了求解器的输出:

    Number of Iterations....: 9
    
                                       (scaled)                 (unscaled)
    Objective...............: -1.7974777841412724e+003  -2.8845129361943263e+006
    Dual infeasibility......:  1.3421365394256974e-009   2.1538014234551661e-006
    Constraint violation....:  0.0000000000000000e+000   0.0000000000000000e+000
    Complementarity.........:  2.1861799117816599e-010   3.5082849379387629e-007
    Overall NLP error.......:  1.3421365394256974e-009   2.1538014234551661e-006
    
    
    Number of objective function evaluations             = 10
    Number of objective gradient evaluations             = 10
    Number of equality constraint evaluations            = 10
    Number of inequality constraint evaluations          = 0
    Number of equality constraint Jacobian evaluations   = 10
    Number of inequality constraint Jacobian evaluations = 0
    Number of Lagrangian Hessian evaluations             = 9
    Total CPU secs in IPOPT (w/o function evaluations)   =      0.066
    Total CPU secs in NLP function evaluations           =      0.001
    
    EXIT: Optimal Solution Found.
    
     The solution was found.
    
     The final value of the objective function is  -2884512.9361943263
    
     ---------------------------------------------------
     Solver         :  IPOPT (v3.12)
     Solution time  :  0.127 sec
     Objective      :  -2884512.9361943263
     Successful solution
     ---------------------------------------------------
    

    以及解决方案:

    [[1359.5263445] [561.97176237] [203.39330742] [1359.5263445]
     [561.97176237] [203.39330742] [1359.5263445] [561.97176237]
     [203.39330742] [1359.5263445] [561.97176237] [203.39330742]
     [1359.5263445] [561.97176237] [203.39330742] [1359.5263445]
     [561.97176237] [203.39330742] [1359.5263445] [561.97176237]
     [203.39330742] [1359.5263445] [561.97176237] [203.39330742]
     [1359.5263445] [561.97176237] [203.39330742] [1359.5263445]
     [561.97176237] [203.39330742] [1359.5263445] [561.97176237]
     [203.39330742] [1359.5263445] [561.97176237] [203.39330742]
     [1359.5263445] [561.97176237] [203.39330742] [1359.5263445]
     [561.97176237] [203.39330742] [1359.5263445] [561.97176237]
     [203.39330742] [1359.5263445] [561.97176237] [203.39330742]
     [1359.5263445] [561.97176237] [203.39330742] [1359.5263445]
     [561.97176237] [203.39330742] [1359.5263445] [561.97176237]
     [203.39330742] [1359.5263445] [561.97176237] [203.39330742]]
    

    【讨论】:

      猜你喜欢
      • 2021-10-21
      • 2020-09-24
      • 1970-01-01
      • 2017-10-07
      • 2017-11-07
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多