Optimization Gekko-最优调度的不可行解,与gurobi的比较

Optimization Gekko-最优调度的不可行解,与gurobi的比较,optimization,time,schedule,gekko,Optimization,Time,Schedule,Gekko,我对古洛比有点熟悉,但过渡到盖柯似乎有一些优势。不过我遇到了一个问题,我将用我想象中的苹果园来说明。5周的收获期(#horizon:T=5)即将到来,我的——非常微薄的——农产品将是: [3.0,7.0,9.0,5.0,4.0] 我为自己保留的一些苹果[2.0,4.0,2.0,4.0,2.0],剩下的农产品我将以以下价格在农贸市场出售:[0.8,0.9,0.5,1.2,1.5]。我有6个苹果的储藏空间,所以我可以提前计划,在最有利的时候出售苹果,从而最大限度地提高我的收入。我尝试使用以下模型确定

我对古洛比有点熟悉,但过渡到盖柯似乎有一些优势。不过我遇到了一个问题,我将用我想象中的苹果园来说明。5周的收获期(
#horizon:T=5
)即将到来,我的——非常微薄的——农产品将是:
[3.0,7.0,9.0,5.0,4.0]
我为自己保留的一些苹果
[2.0,4.0,2.0,4.0,2.0]
,剩下的农产品我将以以下价格在农贸市场出售:
[0.8,0.9,0.5,1.2,1.5]
。我有6个苹果的储藏空间,所以我可以提前计划,在最有利的时候出售苹果,从而最大限度地提高我的收入。我尝试使用以下模型确定最佳时间表:

m=GEKKO()
m、 时间=np.linspace(0,4,5)
乌节=m.Param([3.0,7.0,9.0,5.0,4.0])
需求=m.Param([2.0,4.0,2.0,4.0,2.0])
价格=m.Param([0.8,0.9,0.5,1.2,1.5])
###操纵变量
#在市场上销售
卖出=毫伏(磅=0)
sell.DCOST=0
sell.STATUS=1
#拯救苹果
存储输出=m.MV(值=0,磅=0)
存储\u out.DCOST=0
存储输出状态=1
存储单位=毫伏(磅=0)
存储\u in.DCOST=0
存储状态=1
###存储空间
存储=m.Var(lb=0,ub=6)
###约束条件
#存储更改
m、 方程(storage.dt()==存储输入-存储输出)
#平衡方程
m、 等式(销售+入库+需求==出库+果园)
#目标:在[0,4]中t的argmax总和(卖出[t]*价格[t])
m、 最大化(销售*价格)
m、 选项。IMODE=6
m、 options.NODES=3
m、 选项。解算器=3
m、 选项。最大值=1000
m、 解决()
由于某些原因,这是不可行的(错误代码=2)。有趣的是,如果将
demand[0]设置为3.0,而不是2.0(即等于
orchard[0]
),则该模型确实产生了一个成功的解决方案

  • 为什么会这样
  • 即使是“成功”的输出值也有点奇怪:存储空间一次也没有使用,并且
    存储输出
    在最后一个时间步中没有得到适当的约束。显然,我没有正确地制定约束条件。我应该怎么做才能得到与gurobi输出相当的实际结果(参见下面的代码)
  • Gurobi模型通过
    demand=[3.0,4.0,2.0,4.0,2.0]
    解决。请注意,Gurobi还通过
    demand=[2.0,4.0,2.0,4.0,2.0]
    生成了一个解决方案。这对结果的影响很小:以t=0售出的n个苹果变成了
    1

    T=5
    m=gp.Model()
    ###地平线(五周)
    ###供应、需求和价格数据
    乌节=[3.0,7.0,9.0,5.0,4.0]
    需求=[3.0,4.0,2.0,4.0,2.0]
    价格=[0.8,0.9,0.5,1.2,1.5]
    ###操纵变量
    #在市场上销售
    sell=m.addVars(T)
    #拯救苹果
    存储输出=m.addVars(T)
    m、 addConstr(存储输出[0]==0)
    存储=m.addVars(T)
    #存储空间
    存储=m.addVars(T)
    m、 范围(t)内t的addConstrs((存储[t]=0))
    m、 addConstr(存储[0]==0)
    #存储更改
    #m、 addConstr(存储[0]==(0-存储输出[0]*增量t+存储输入[0]*增量t))
    m、 范围(1,t)内的t的addConstrs(存储[t]==(存储[t-1]-存储[t]+存储[t])
    #平衡方程
    m、 范围(t)内的t的addConstrs(销售[t]+需求[t]+存储[t]==(存储[t]+果园[t])
    #目标:argmax sum(a_卖出[t]*a_价格[t]-b_买入[t]*b_价格[t])
    obj=t范围内t的总价格(价格[t]*卖出[t])
    m、 设定目标(目标,总目标最大化)
    m、 优化()
    
    输出:

        sell    storage_out storage_in  storage
    0   0.0     0.0         0.0         0.0
    1   3.0     0.0         0.0         0.0
    2   1.0     0.0         6.0         6.0
    3   1.0     0.0         0.0         6.0
    4   8.0     6.0         0.0         0.0
    

    您可以通过以下方式获得成功的解决方案:

    m.options.NODES=2
    
    问题在于,它是在用
    节点=3
    求解主节点点之间的平衡方程。您的微分方程具有线性解,因此
    节点=2
    应该足够精确

    以下是改进解决方案的两种其他方法:

    • 在将库存移入或移出存储时设置一个小的惩罚。否则,解算器可以使用
      storage\u in=storage\u out
      找到大的任意值
    • 我使用了
      m.Minimize(1e-6*存储入)
      m.Minimize(1e-6*存储出)
    • 因为初始条件通常是固定的,所以我在开始时使用零值只是为了确保计算第一个点
    • 如果以整数单位出售和存储,我也会切换到整数变量。如果想要使用
      solver=1
      的整数解,则需要切换到APOPT解算器
    这是修改后的脚本

    从gekko导入gekko
    将numpy作为np导入
    m=GEKKO(远程=False)
    m、 时间=np.linspace(0,5,6)
    乌节=m.Param([0.0,3.0,7.0,9.0,5.0,4.0])
    需求=m.Param([0.0,2.0,4.0,2.0,4.0,2.0])
    价格=m.Param([0.0,0.8,0.9,0.5,1.2,1.5])
    ###操纵变量
    #在市场上销售
    sell=m.MV(磅=0,整数=True)
    sell.DCOST=0
    sell.STATUS=1
    #拯救苹果
    存储器输出=m.MV(值=0,磅=0,整数=True)
    存储\u out.DCOST=0
    存储输出状态=1
    存储器_in=m.MV(磅=0,整数=True)
    存储\u in.DCOST=0
    存储状态=1
    ###存储空间
    存储=m.Var(lb=0,ub=6,整数=True)
    ###约束条件
    #存储更改
    m、 方程(storage.dt()==存储输入-存储输出)
    #平衡方程
    m、 等式(销售+入库+需求==出库+果园)
    #目标:在[0,4]中t的argmax总和(卖出[t]*价格[t])
    m、 最大化(销售*价格)
    m、 最小化(1e-6*存储空间)
    m、 最小化(1e-6*存储输出)
    m、 选项。IMODE=6
    m、 options.NODES=2
    m、 选项。解算器=1
    m、 选项。最大值=1000
    m、 解决()
    打印(‘出售’)
    打印(销售价值)
    打印('存储输出')
    打印(存储输出值)
    打印('存储在')
    打印(存储单位值)
    打印('存储')
    打印(存储值)
    
    再次感谢John,这确实非常有用!
        sell    storage_out storage_in  storage
    0   0.0     0.0         0.0         0.0
    1   3.0     0.0         0.0         0.0
    2   1.0     0.0         6.0         6.0
    3   1.0     0.0         0.0         6.0
    4   8.0     6.0         0.0         0.0
    
     Successful solution
     
     ---------------------------------------------------
     Solver         :  APOPT (v1.0)
     Solution time  :  0.058899999999999994 sec
     Objective      :  -17.299986
     Successful solution
     ---------------------------------------------------
     
    
    Sell
    [0.0, 0.0, 4.0, 1.0, 1.0, 8.0]
    Storage Out
    [0.0, 0.0, 1.0, 0.0, 0.0, 6.0]
    Storage In
    [0.0, 1.0, 0.0, 6.0, 0.0, 0.0]
    Storage
    [0.0, 1.0, 0.0, 6.0, 6.0, 0.0]