Search code examples
pythonvariablespyomo

Pyomo and VarList - generate variables automatically


I would like to create a VarList automatically in Pyomo.

The model should have two (or at the end more) sets: one over time t (e.g. 8760), another over different components k (e.g. 3). Each component k should ideally get a time series with t elements.

Unfortunately, this does not work, but I write it anyway for better understanding and hope that someone understands my idea behind it better:

import numpy as np
from pyomo.environ import *

mdl = ConcreteModel()
mdl.t = Set(initialize=np.arange(0,8760))
mdl.k = Set(initialize=np.arange(0,3))

# VarList
## generate variable x for each component k
mdl.x = VarList()
for k in mdl.k:
    mdl.x.add()

## generate for each component k a variable for each time t
for k in mdl.k:
    mdl.x[k]=VarList()
    for t in mdl.t:
        mdl.x[k].add()

Is there a way to manage that kind of variable generation? Or a similar one?

Best greetings! Mathias


Solution

  • Welcome to the site.

    I think what you'd really like is a variable that is double-indexed by time and k, right?

    The correct way to do that is just to provide both indexing sets when creating the variable, as shown below. This will allow you to do summations over either variable, etc. in your constraints and OBJ.

    Other advice: avoid numpy when making these models. Unnecessary and adds to confusion most of the time.

    I've posted a bunch of pyomo example probs if you look at my profile answers with the pyomo tag, you'll probably find some other useful examples.

    import pyomo.environ as pyo
    
    m = pyo.ConcreteModel()
    
    # SETS
    m.T = pyo.Set(initialize=range(4))
    m.K = pyo.Set(initialize=range(3))
    
    # VARS
    m.X = pyo.Var(m.T, m.K, domain=pyo.NonNegativeReals)
    
    # example objective
    m.OBJ = pyo.Objective(expr=sum(m.X[t, k] for t in m.T for k in m.K))
    
    m.pprint()