2017-03-06 23 views
0

나는 benders decomp를 코딩하고 있습니다. Python으로 파이썬에서 알고리즘. 내 질문은 1 단계에서 아래에서 볼 수 있듯이 하위 문제 constraintList에 새 제약 조건을 삭제하고 추가하는 대신 추가 된 제약 조건을 어떻게 든 업데이트하는 방법을 찾아야합니다.Pyomo의 ConstraintList 업데이트하기

우아한 방법이 있습니까?

또는

s.Cut_Defn [1]

s.Cut_Defn을 .pop

s.Cut_Defn [1] .update를 추천

있는 정보 (SX == mxvalue). add (sx == mxvalue)

???

는 Icedkk

시가 : 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 개체 또는 변경 가능한 Param을 사용하여 나중에 업데이트 할 수있는 제약 조건을 만들 수 있습니다. 변경할 수있는 Param을 사용하면 계수 또는 rhs를 업데이트 할 수 있지만 Expression을 사용하면 제약 조건의 하위 표현식을 업데이트 할 수 있습니다. 예 : 당신이 관계식을 저장하기 위해 표현을 사용해서는 안

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 = s.dual [s.Cut_Defn [i]] 제약 조건의 표현식 istead를 사용하면 여전히 작동합니다. – Icedkk

+0

접미어에 저장된 값은 가장 최근의 해결로 반환 된 값과 일치합니다. 구속 조건을 변경해도 접미사 값에 영향을 미치지 않습니다 (모델을 다시 풀 때까지). –

+0

그것은 게이 티를 일했다 :) – Icedkk