Pyomo: como el índice de la Variable en sólo una parte de un Conjunto?

0

Pregunta

Estoy tratando de hacer un seguimiento de la Soc en un pyomo modelo de optimización. Tengo número de BEVs y quiero keept pista de eachs SOC. El xpression me pase a pe.Objective el siguiente aspecto:

sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times)

model.buses y model.times son dos juegos que me han declarado como pe.Set. Los tiempos de (0, ...., 95). Así que en la última iteración de la model.times se trata de acceder model.SOC[96, b] lo que conduce a una KeyError.

Hay una manera de decirle a pyomo a leafe fuera el último elemento del conjunto para evitar este Error?

Algo como:

sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times[0:-2])

que tristemente también genera un Error:

IndexError: times indices must be integers, not slice

aquí está una minmal ejemplo que debe reproducir el Error:

import pyomo.environ as pe

solver = pe.SolverFactory('glpk')
model = pe.ConcreteModel('Test')
model.times = pe.Set(initialize=list(range(96)))
model.buses = pe.Set(initialize=list(range(5)))
model.SOC = pe.Var(model.times*model.buses, domain=pe.PositiveReals)

def example_rule(model):
    return sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times)

model.obj = pe.Objective(rule=example_rule, sense=pe.maximize)

model.pprint()

Muchas gracias de antemano!

optimization pyomo python
2021-11-16 15:17:42
1

Mejor respuesta

1

Sí, hay un par de maneras de hacer esto. En primer lugar, si el conjunto que desea índice a es la ordenada (que es el predeterminado), puede utilizar la first, lasty prev métodos en el conjunto de diversas maneras. (ver mis ediciones a su código de abajo)

En segundo lugar, usted siempre puede construir su propio subconjunto y poner en el modelo o no. El segundo modelo que a continuación se muestra la construcción de una forma arbitraria complicado subconjunto y la pone en el modelo. Este conjunto puede ser utilizado como base para un objetivo o restricción.

Esta solución es similar a esta respuesta

import pyomo.environ as pe

solver = pe.SolverFactory('glpk')
model = pe.ConcreteModel('Test')
model.times = pe.Set(initialize=list(range(5)), ordered=True)  # ordered is default, this is for clarity...
model.buses = pe.Set(initialize=list(range(2)))
model.SOC = pe.Var(model.times*model.buses, domain=pe.PositiveReals)

def example_rule(model):
    return sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times if t != model.times.last())

model.obj = pe.Objective(rule=example_rule, sense=pe.maximize)

model.pprint()


# making your own subset...
times = 10
model2 = pe.ConcreteModel("other")
model2.times = pe.Set(initialize=range(times))
# make a subset of the even values that are no more than 4 values close to the end....
model2.times_subset = pe.Set(initialize=[t for t in model2.times if t%2==0 and t <= times-4])

model2.pprint()

Rendimientos:

3 Set Declarations
    SOC_index : Size=1, Index=None, Ordered=True
        Key  : Dimen : Domain      : Size : Members
        None :     2 : times*buses :   10 : {(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1), (4, 0), (4, 1)}
    buses : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    2 : {0, 1}
    times : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    5 : {0, 1, 2, 3, 4}

1 Var Declarations
    SOC : Size=10, Index=SOC_index
        Key    : Lower : Value : Upper : Fixed : Stale : Domain
        (0, 0) :     0 :  None :  None : False :  True : PositiveReals
        (0, 1) :     0 :  None :  None : False :  True : PositiveReals
        (1, 0) :     0 :  None :  None : False :  True : PositiveReals
        (1, 1) :     0 :  None :  None : False :  True : PositiveReals
        (2, 0) :     0 :  None :  None : False :  True : PositiveReals
        (2, 1) :     0 :  None :  None : False :  True : PositiveReals
        (3, 0) :     0 :  None :  None : False :  True : PositiveReals
        (3, 1) :     0 :  None :  None : False :  True : PositiveReals
        (4, 0) :     0 :  None :  None : False :  True : PositiveReals
        (4, 1) :     0 :  None :  None : False :  True : PositiveReals

1 Objective Declarations
    obj : Size=1, Index=None, Active=True
        Key  : Active : Sense    : Expression
        None :   True : maximize : SOC[1,0] - SOC[0,0] + SOC[1,1] - SOC[0,1] + SOC[2,0] - SOC[1,0] + SOC[2,1] - SOC[1,1] + SOC[3,0] - SOC[2,0] + SOC[3,1] - SOC[2,1] + SOC[4,0] - SOC[3,0] + SOC[4,1] - SOC[3,1]

5 Declarations: times buses SOC_index SOC obj
2 Set Declarations
    times : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :   10 : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    times_subset : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    4 : {0, 2, 4, 6}

2 Declarations: times times_subset
[Finished in 553ms]
2021-11-16 17:03:25

perfecto, gracias! :) Esta prevw soluciona mi problema. Hay un lugar en internet donde uno puede aprender de esto? En el pyomo documentación prevw ni siquiera se menciona (o al menos yo no lo he visto)
Andre

Sí, en mi humilde opinión, la Pyomo documentación cubre los conceptos básicos, pero se echa en falta en buena documentación del módulo. Esto es "bueno" pero no muy bien... yo no habría sabido prevw sin que otro post. A veces me tinker en ipython que muestra terminaciones y doc talones. pyomo.readthedocs.io/en/expr_dev/_modules/index.html
AirSquid

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................