2017-03-06 155 views
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.") 

回答

0

您可以構建約束,稍後可以使用Expression對象或可變參數進行更新。可變參數允許您更新系數或rhs,而表達式允許您更新約束的子表達式。例如:

model = ConcreteModel() 
model.p = Param(mutable=True) 
model.e = Expression() 
model.x = Var() 
model.c = Constraint(expr=model.e == model.p) 
# set the constraint rhs to 1 
model.p.value = 1 
# set the constraint lhs to x**2 
model.e.expr = model.x**2 

注意,不應使用表達式來存儲的關係式(例如,==>=<=)。

+0

後綴是什麼?正如你所看到的,我從約束中獲得了一些lambda值。 Lambda = s.dual [s.Cut_Defn [i]]如果我使用表達式而不是約束,這仍然可以工作。 – Icedkk

+0

存儲在後綴中的值將與最近解決的返回值相對應。更改約束不會影響後綴值(直到您再次求解模型)。 –

+0

它工作gabe ty :) – Icedkk