# 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!

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:
else:
Constraint.Skip


Answered by Oguz Toragay on November 24, 2021

## Related Questions

### What is a general procedure to prove that the LP relaxation of an IP delivers the optimal IP solution?

2  Asked on August 19, 2021 by k88074

### CPLEX MIP warm start seems slow down the program?

1  Asked on August 19, 2021 by mengfan-ma

### (Iterative?) Solutions to a certain quadratic program with non-convex constraints

2  Asked on August 19, 2021 by cfp

### Problem with implementing squared terms in the objective function

1  Asked on August 19, 2021 by poofybridge

### Scheduling with setup cost

0  Asked on August 19, 2021 by dirk-nachbar

### Is a convex or MILP (without big-M) formulation possible for this problem

1  Asked on August 19, 2021 by batwing

### MINLP Solution same as Global Optimum?

2  Asked on August 19, 2021 by clement

### Linear objective function with non-linear constraints

2  Asked on August 19, 2021 by fightmilk

### Meta papers on operations research

2  Asked on August 19, 2021 by luke599999

### Verifying the correctness of KKT conditions

0  Asked on August 19, 2021 by s_scouse

### How can I use warm start in C#

1  Asked on August 19, 2021 by fhm-ider

### Feasible sets represented as point clouds

1  Asked on August 19, 2021 by harry-cohen

### Is this the same as Agent Based DES or something different?

0  Asked on August 19, 2021 by brendan-hill

### Column generation when intractable variables appear in the objective function

1  Asked on August 19, 2021 by mostafa

### Is there any OR way to solve this problem?

3  Asked on August 19, 2021 by samiczy

### Find a particular optimal solution

1  Asked on August 19, 2021 by ljg

### How to find all vertices of a polyhedron

3  Asked on August 19, 2021

### Can every convex problem use Lagrangian dual method?

0  Asked on August 19, 2021

### Does strong duality hold when I dualize only a subset of the constraints?

1  Asked on August 19, 2021 by george-chang