0
我正在編碼benders分解。算法python與pyomo。我的問題是,你可以在下面的第1步中看到,我需要找到一種方法來以某種方式更新添加的約束,而不是刪除並向子問題constraintList添加新的約束。更新約束列表在Pyomo飛行
有什麼優雅的方法嗎?
喜歡的東西
s.Cut_Defn [1] .update(SX == mxvalue)
或
s.Cut_Defn [1] .pop
s.Cut_Defn。 add(sx == mxvalue)
???
Icedkk
PS:在步驟0,我一個約束添加到子問題constraintlist。在步驟1中,我想實際更新步驟0中添加的約束,但是我無法完成此操作,因此我刪除了第一個添加的約束,並添加了下一個約束,這對編碼有點不利。
import sys
from pyomo.opt.base import SolverFactory
from pyomo.core import *
import pyomo.environ
import numpy as np
import timeit
# Importing Models
from master import m
from sub import s
# Misc. init.
start = timeit.default_timer()
GAP = float('Inf')
maxit = 5
###################################
# STEP 0: Init.
opt = SolverFactory('glpk')
results_M = opt.solve(m) # solve master
s.Cut_Defn.add(s.x == m.x.value) # s.x = m.x.value
results_S = opt.solve(s) # solve sub
print('i','\t','Mx','\t','Sx','\t','Ma','\t','Sy',\
'\t','Lmda','\t','Zup','\t','Zdo','\t','Gap',\
'\t','Objective')
#######################################################################
# Benders Loop
for i in sequence(maxit):
###################################
# STEP 1: Subproblem Solution
if i == 1:
pass
else:
del s.Cut_Defn[i-1]
s.Cut_Defn.add(s.x == m.x.value)
results_S = opt.solve(s)
###################################
# Adding the Master Cut
Lambda = s.dual[s.Cut_Defn[i]] # get Lambda from Solver
m.Cut_Defn.add(s.Obj() + float(Lambda)*(m.x-s.x.value) <= m.a) # add Cut to Master
###################################
# STEP 2: Convergence Checking
Zup = s.Obj() - s.x.value/4
Zdo = m.Obj()
newGAP = Zup - Zdo
if newGAP > 0.00001:
GAP = min(GAP, newGAP)
else:
print(i,'\t',round(m.x.value,1),'\t',round(s.x.value,1),'\t',round(m.a.value,1),'\t',round(s.y.value,1),\
'\t',round(Lambda,2),'\t',round(Zup,1),'\t',round(Zdo,1),'\t',round(newGAP,2),\
'\t',round(m.Obj(),5))
break
###################################
# STEP 3: Re-Solve Masterproblem
print(i,'\t',round(m.x.value,1),'\t',round(s.x.value,1),'\t',round(m.a.value,1),'\t',round(s.y.value,1),\
'\t',round(Lambda,2),'\t',round(Zup,1),'\t',round(Zdo,1),'\t',round(GAP,2),\
'\t',round(m.Obj(),5))
#solve_all_instances(solver_manager, 'cplex', [Instance_M])
results_M = opt.solve(m)
stop = timeit.default_timer()
print("Benders converged in", round(stop-start,2),"s.")
後綴是什麼?正如你所看到的,我從約束中獲得了一些lambda值。 Lambda = s.dual [s.Cut_Defn [i]]如果我使用表達式而不是約束,這仍然可以工作。 – Icedkk
存儲在後綴中的值將與最近解決的返回值相對應。更改約束不會影響後綴值(直到您再次求解模型)。 –
它工作gabe ty :) – Icedkk