Optimization Gekko-最优调度的不可行解,与gurobi的比较
我对古洛比有点熟悉,但过渡到盖柯似乎有一些优势。不过我遇到了一个问题,我将用我想象中的苹果园来说明。5周的收获期(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个苹果的储藏空间,所以我可以提前计划,在最有利的时候出售苹果,从而最大限度地提高我的收入。我尝试使用以下模型确定
#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]