【问题标题】:Gekko sum of intermediate variables condition中间变量条件的 Gekko 和
【发布时间】:2021-08-02 07:49:56
【问题描述】:

我有一个简单的优化问题,我试图优化潜在客户的数量,每个潜在客户都有一定的成本(这取决于潜在客户的数量,例如 1 个潜在客户可能需要 1 美元,而 2 个潜在客户可能需要花费每个 1.5 美元)。使用以下函数计算每个潜在客户的成本。 cmets 是我为解决不同问题所做的尝试。

# Here x is leads and returns spend
def objective_inverse(x, a, b, c):
     if c == 0:
         return 0
     else:
         return np.real(a + (x/c)**(1./b))

这里是变量reg_feats,其中列表中的每个元组都是前面函数中的(a,b,c)

reg_feats = [(0.0, 1.0, 0.0008237661018136143), (0.9999999999999811, 0.8536915943397881, 0.004454688129841911), (0.0, 1.0, 0.0004855869694355375), (0.0, 1.0, 0.00038427101866404334), (8.308985001840891e-10, 1.097417548409198, 0.0009170956872015353), (0.999999999998488, 1.9999999897072056, 1.144122017534284e-07), (0.9999999999825329, 0.8097037523302283, 0.20606857088111075), (0.9999999999999963, 1.1649279015402045, 0.009316713936903972), (0.0, 1.0, 0.0034430519212229715), (0.0, 1.0, 0.0007980573950249244), (0.0, 1.0, 0.0009069008844368589)]

并且每个变量的边界都有一个列表。

bounds = [(0, 4), (0, 20), (0, 3), (0, 1), (0, 114), (0, 14), (0, 208), (0, 529), (0, 1), (0, 4), (0, 4)]

这是优化的代码:

m = GEKKO(remote=not bool(i))

m.options.SOLVER=1
# optional solver settings with APOPT
m.solver_options = ['minlp_maximum_iterations 50000', \
                # minlp iterations with integer solution
                'minlp_max_iter_with_int_sol 100', \
                # treat minlp as nlp
                'minlp_as_nlp 0', \
                # nlp sub-problem max iterations
                'nlp_maximum_iterations 500', \
                # 1 = depth first, 2 = breadth first
                'minlp_branch_method 1', \
                # maximum deviation from whole number
                'minlp_integer_tol 0.05', \
                # covergence tolerance
                'minlp_gap_tol 0.01']

这里的 x 是每个广告系列的潜在客户数量。

x = m.Array(m.Var, (len(bounds)),integer=True)
# Here x is the number of leads and is the decision variable
# x variables are nb of leads, not $ to be allocated
for i, xi in enumerate(x):
    lb, ub = bounds[i]
    xi.lower = lb
    xi.upper = ub
    xi.value = ub

这个中间变量是获取每个潜在客户的成本。这用于下一个约束。

sums = [m.Intermediate(objective_inverse(xi,*y)) for xi,y in zip(x,reg_feats)]

max_budget = 150000
m.Maximize(m.sum(x))
c = m.Const(max_budget, 'Budget')
m.Equation(m.sum(sums) < c)
m.solve(disp=True)

在这里,如果我运行此代码,我会收到一条错误消息,提示找不到解决方案和Warning: no more possible trial points and no integer solution

此外,如果我删除 max_budget 约束,我会得到一个总花费低于 max_budget 的解决方案,这意味着添加约束不应该改变解决方案。

我知道我如何定义约束存在问题,但不知道如何解决。

【问题讨论】:

    标签: gekko


    【解决方案1】:

    问题似乎不在于约束,而在于x 的起点。当我运行您的代码时,我得到了解决方案(我没有收到任何错误)。但是当我将max_budget 更改为100000 时开始出现同样的错误。我怀疑这是因为 APPT 需要一个好的初始猜测。由于我没有很好的猜测,所以我使用np.random 来生成起点。我尝试了几个不同的 max_budget 并且它可以工作(尽管尝试了几次才能获得一个好的初始点)。

    import numpy as np
    from gekko import GEKKO
    
    # Here x is leads and returns spend
    def objective_inverse(x, a, b, c):
         if c == 0:
             return 0
         else:
             return np.real(a + (x/c)**(1./b))
    
    reg_feats = [(0.0, 1.0, 0.0008237661018136143), (0.9999999999999811, 0.8536915943397881, 0.004454688129841911), (0.0, 1.0, 0.0004855869694355375), (0.0, 1.0, 0.00038427101866404334), (8.308985001840891e-10, 1.097417548409198, 0.0009170956872015353), (0.999999999998488, 1.9999999897072056, 1.144122017534284e-07), (0.9999999999825329, 0.8097037523302283, 0.20606857088111075), (0.9999999999999963, 1.1649279015402045, 0.009316713936903972), (0.0, 1.0, 0.0034430519212229715), (0.0, 1.0, 0.0007980573950249244), (0.0, 1.0, 0.0009069008844368589)]
    bounds = [(0, 4), (0, 20), (0, 3), (0, 1), (0, 114), (0, 14), (0, 208), (0, 529), (0, 1), (0, 4), (0, 4)]
    m = GEKKO(remote=False)
    
    m.options.SOLVER=1
    # optional solver settings with APOPT
    m.solver_options = ['minlp_maximum_iterations 50000', \
                    # minlp iterations with integer solution
                    'minlp_max_iter_with_int_sol 100', \
                    # treat minlp as nlp
                    'minlp_as_nlp 0', \
                    # nlp sub-problem max iterations
                    'nlp_maximum_iterations 500', \
                    # 1 = depth first, 2 = breadth first
                    'minlp_branch_method 1', \
                    # maximum deviation from whole number
                    'minlp_integer_tol 0.05', \
                    # covergence tolerance
                    'minlp_gap_tol 0.01']
    
    x = m.Array(m.Var, (len(bounds)),integer=True)
    # Here x is the number of leads and is the decision variable
    # x variables are nb of leads, not $ to be allocated
    for i, xi in enumerate(x):
        lb, ub = bounds[i]
        xi.lower = lb
        xi.upper = ub
        xi.value = np.random.randint(lb,ub)
    
    print("Initial Value: ",x)
    
    sums = [m.Intermediate(objective_inverse(xi,*y)) for xi,y in zip(x,reg_feats)]
    
    max_budget = 90000
    # max_budget = 100000
    # max_budget = 120000
    # max_budget = 150000
    m.Maximize(m.sum(x))
    c = m.Const(max_budget, 'Budget')
    m.Equation(m.sum(sums) < c)
    m.solve(disp=True)
    
    
    x_ans =[i[0] for i in x]
    print('x : ', x_ans)
    print('Constraint: ', np.sum([(objective_inverse(xi,*y)) for xi,y in zip(x_ans,reg_feats)]))
    

    输出:

    Initial Value:  [2 7 0 0 113 5 205 151 0 3 2]
     ----------------------------------------------------------------
     APMonitor, Version 0.9.2
     APMonitor Optimization Suite
     ----------------------------------------------------------------
    
    
     --------- APM Model Size ------------
     Each time step contains
       Objects      :  1
       Constants    :  1
       Variables    :  24
       Intermediates:  11
       Connections  :  12
       Equations    :  24
       Residuals    :  13
    
     Number of state variables:    24
     Number of total equations: -  13
     Number of slack variables: -  1
     ---------------------------------------
     Degrees of freedom       :    10
    
     ----------------------------------------------
     Steady State Optimization with APOPT Solver
     ----------------------------------------------
    Iter:     1 I:  0 Tm:      0.00 NLPi:   12 Dpth:    0 Lvs:    2 Obj: -8.85E+02 Gap:       NaN
    Iter:     2 I:  0 Tm:      0.00 NLPi:    3 Dpth:    1 Lvs:    3 Obj: -8.85E+02 Gap:       NaN
    Iter:     3 I:  0 Tm:      0.00 NLPi:    3 Dpth:    2 Lvs:    4 Obj: -8.85E+02 Gap:       NaN
    Iter:     4 I:  0 Tm:      0.00 NLPi:    3 Dpth:    3 Lvs:    5 Obj: -8.85E+02 Gap:       NaN
    Iter:     5 I:  0 Tm:      0.00 NLPi:    3 Dpth:    4 Lvs:    6 Obj: -8.84E+02 Gap:       NaN
    Iter:     6 I:  0 Tm:      0.00 NLPi:    3 Dpth:    5 Lvs:    7 Obj: -8.84E+02 Gap:       NaN
    --Integer Solution:  -8.84E+02 Lowest Leaf:  -8.85E+02 Gap:   8.39E-04
    Iter:     7 I:  0 Tm:      0.00 NLPi:    2 Dpth:    6 Lvs:    7 Obj: -8.84E+02 Gap:  8.39E-04
     Successful solution
    
     ---------------------------------------------------
     Solver         :  APOPT (v1.0)
     Solution time  :  0.0677 sec
     Objective      :  -884.
     Successful solution
     ---------------------------------------------------
    
    
    x :  [0.0, 18.0, 0.0, 0.0, 114.0, 14.0, 208.0, 529.0, 1.0, 0.0, 0.0]
    Constraint:  89187.87455034524
    

    我知道,如果没有良好的初始猜测,对于更大的问题来说,随机生成起点可能是不可行的。但不幸的是,我不知道在这种情况下如何使用 APPT。

    【讨论】:

    • 感谢您的回答。使用随机起点解决了代码问题,但是结果非常不稳定(非常依赖于起始解决方案)。为什么会这样?我更熟悉 MILP,其中起始解决方案不应该是一个因素。另外,我知道我可以简单地用随机起点进行多次试验,这将使我非常接近真正的最优解。
    猜你喜欢
    • 2020-08-12
    • 2022-01-06
    • 1970-01-01
    • 2021-12-21
    • 2022-11-02
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多