TransWikia.com

Possibility of indexing decision variables with 2 indices using a set of tuples in Pyomo

Operations Research Asked on November 24, 2021

I am currently attempting to solve a network problem that is not fully connected.Thus, I have attempted to do some preprocessing of data so as to form a set of tuples, e.g. ${(a,b), (c,e),ldots}$, i.e. from $a$ to $b$, from $c$ to $e$.

I am able to declare binary decision variables with keys such as $(a,b)$, $(c,e)$ via using the set of tuples for indexing.

However, when I tried to use rules to declare constraints, with decision variables such as x[i][j], errors are thrown stating that $(a,b)$ is an invalid index.

Hence, I would like to ask if tuples can be used as indices for decision variables.

If not, is there a way to only declare the only decision variables that are needed, rather than declaring all, and then setting those unneeded to 0.

Thank you!

3 Answers

Yes. Totally doable. Here are 2 examples using either tuples in a pyomo set or just making some up on-the-fly and passing them to a rule-based constraint to make the appropriate number of sparse constraints (seen in the result).

# subsets in tuples

import pyomo.environ as pyo

mdl = pyo.ConcreteModel()

# sets
mdl.I = pyo.Set(initialize=range(4))
mdl.J = pyo.Set(initialize=range(3))
mdl.select_combos = pyo.Set(within = mdl.I * mdl.J, initialize = [(1,2), (3,1)])

# vars
mdl.X = pyo.Var(mdl.I, mdl.J, domain=pyo.NonNegativeReals)

# constraint with rule and tuples from pyomo Set
def c1(self, i, j):
    return mdl.X[i, j] <= 2
mdl.c1 = pyo.Constraint(mdl.select_combos, rule=c1)

# or make a set of tuples of interest on the fly
my_combos = {(i, j) for i in mdl.I for j in mdl.J if
                i <=2 and
                j >=2 }
def c2(self, i, j):
    return mdl.X[i, j] >= 1
mdl.C2 = pyo.Constraint(my_combos, rule=c2)

mdl.pprint()

Output:

6 Set Declarations
    C2_index : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None
        [(0, 2), (1, 2), (2, 2)]
    I : Dim=0, Dimen=1, Size=4, Domain=None, Ordered=False, Bounds=(0, 3)
        [0, 1, 2, 3]
    J : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(0, 2)
        [0, 1, 2]
    X_index : Dim=0, Dimen=2, Size=12, Domain=None, Ordered=False, Bounds=None
        Virtual
    select_combos : Dim=0, Dimen=2, Size=2, Domain=select_combos_domain, Ordered=False, Bounds=None
        [(1, 2), (3, 1)]
    select_combos_domain : Dim=0, Dimen=2, Size=12, Domain=None, Ordered=False, Bounds=None
        Virtual

1 Var Declarations
    X : Size=12, Index=X_index
        Key    : Lower : Value : Upper : Fixed : Stale : Domain
        (0, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (0, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (0, 2) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 2) :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 2) :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 0) :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 2) :     0 :  None :  None : False :  True : NonNegativeReals

2 Constraint Declarations
    C2 : Size=3, Index=C2_index, Active=True
        Key    : Lower : Body   : Upper : Active
        (0, 2) :   1.0 : X[0,2] :  +Inf :   True
        (1, 2) :   1.0 : X[1,2] :  +Inf :   True
        (2, 2) :   1.0 : X[2,2] :  +Inf :   True
    c1 : Size=2, Index=select_combos, Active=True
        Key    : Lower : Body   : Upper : Active
        (1, 2) :  -Inf : X[1,2] :   2.0 :   True
        (3, 1) :  -Inf : X[3,1] :   2.0 :   True

9 Declarations: I J select_combos_domain select_combos X_index X c1 C2_index C2
[Finished in 2.5s]

Answered by AirSquid on November 24, 2021

An example is as follows:

##First, create the set of tuples needed for filtering


#Op_Machine: set of (operation, machine) tuples created to avoid redundancy in decision variable declaration Op_Machine=list() for machine_id, op_proctime in Machine_Op_Time.items():
    for op in op_proctime.keys():
        print(Op_Machine)
        print((op,machine_id))
        Op_Machine.append((op,machine_id))
        print(Op_Machine)

##Next, invoke the rule using the if statement to filter across all possible indices accepting those combinations that are aligned with the tuples within the set
##Use Constraint.Skip to Skip creating constraints that do not belong to the set of tuples


def F1_rule(model,i,k):
    if (i,k) in Op_Machine:
        ##print(i,k)
        return model.Cmax>=model.completion_time[i,k]
    else:
        return Constraint.Skip            
            
#model.makespan= Constraint(model.op_set, model.mach_set, rule=Cmax_rule) model.F1= Constraint(Operation_Set, Machine_Set, rule=F1_rule)

Note that the sets Operation_Set, Machine_Set function as the universal set as it comprises all combinations of operations and machines. Hence the statement model.F1= Constraint(Operation_Set, Machine_Set, rule=F1_rule) can be thought a for loop that iterates over all combinations while the if statement within the def function acts a filter to generate the needed constraints.

Answered by Mike on November 24, 2021

It is possible to use tuples as the indices of your variables. If the tuple like $(a_1, a_2)$ is not defined in the index set, errors will be thrown but you can skip those undefined indices by using:

Constraint.Skip

checking if the tuple is defined or not. An example of implementation would be as follow:

model.cons = ConstraintList()        
for i in model.nodes:
    for j in model.nodes:
        if [i,j] in tuples_list:
           model.cons.add("some expressions")
        else:
            Constraint.Skip

Answered by Oguz Toragay on November 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP