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()
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP