How to define constraints over multiple dimensions?
AnsweredHello,
I am new to Gurobi and would like to model a simple resource allocation problem. I have looked at the example Jupyter notebooks on Github but I am still having trouble defining the constraints. Suppose this is (part of) the problem I would like to solve:
Where I is the set of supply nodes, J is the set of resource types, and L is the set of demand nodes. I would like to minimize the total deployment time, t_ijl, which is the time it takes resource type j to be transported from supply node i to demand node l. q_jl is the quantity of resource type j that demand node l needs, and a_ij is the available resource j at supply node i.
I have input the data as follows:
resource = ['A', 'B', 'C']
demand_node = ['Sink1', 'Sink2']
supply_node = ['Node1', 'Node2', 'Node3']
for q_jl:
demand_combo, demand_quantity = gp.multidict({
('A','Sink1') : 2,
('A','Sink2') : 2,
('B','Sink1') : 2,
('B','Sink2') : 1,
('C','Sink1') : 3,
('C','Sink2') : 3
})
for a_ij:
resource_combo, supply_avail = gp.multidict({
('Node1', 'A') : 2,
('Node2', 'A') : 1,
('Node3', 'A') : 1,
('Node1','B') : 1,
('Node2','B') : 1,
('Node3','B') : 0,
('Node1', 'C') : 1,
('Node2', 'C') : 1,
('Node3', 'C') : 1,
})
for t_ijl:
combinations, time = gp.multidict(
{('Node1','A', 'Sink1'): 1,
('Node2','A', 'Sink1'): 3,
('Node3','A', 'Sink1'): 5,
('Node1','A', 'Sink2'): 2,
('Node2','A', 'Sink2'): 3,
('Node3','A', 'Sink2'): 2,
('Node1','B', 'Sink1'): 3,
('Node2','B', 'Sink1'): 5,
('Node3','B', 'Sink1'): 0,
('Node1','B', 'Sink2'): 4,
('Node2','B', 'Sink2'): 5,
('Node3','B', 'Sink2'): 0,
('Node1','C', 'Sink1'): 8,
('Node2','C', 'Sink1'): 10,
('Node3','C', 'Sink1'): 9,
('Node1','C', 'Sink2'): 10,
('Node2','C', 'Sink2'): 10,
('Node3','C', 'Sink2'): 6
})
Then, for my decision variable, I defined the following:
x = m.addVars(combinations, vtype=GRB.BINARY, name = 'allocate')
I tried to do the following for the first constraint:
# capacity constraint
capacity = m.addConstr((x.sum('*', j, l) <= supply_avail[i,j] for i in supply_node for j in resource), name = 'capacity')
But it is giving me an error. I am sure that I am not correctly defining the constraint, but I am not sure how to fix it.
Also, is there a faster way to define my data? Should I be using some sort of list comprehension or pandas dataframe?
Any help would be greatly appreciated! Thank you.

Hi Irene,
It looks like to me like the first and second constraints are mixed up in the capacity constraint you coded. In particular, \( \texttt{supply_avail[i, j]} \) corresponds to \( a_{ij} \) in the formulation, which shows up in the second constraint set. However, you sum over \( I \) on the lefthand side, which is done only in the first constraint set. I'll assume we are trying to write the second constraint set.
Model.addConstr() is used to add a single constraint. Instead, we can use Model.addConstrs() to add multiple constraints with a single method call. Additionally, for the second constraint, we want to sum over \( L \) on the lefthand side, not \( I \). Altogether:
m.addConstrs((x.sum(i, j, '*') <= supply_avail[i, j] for i in supply_node for j in resource), name='capacity')
This code adds the following constraints:
capacity[Node1,A]: allocate[Node1,A,Sink1] + allocate[Node1,A,Sink2] <= 2
capacity[Node1,B]: allocate[Node1,B,Sink1] + allocate[Node1,B,Sink2] <= 1
capacity[Node1,C]: allocate[Node1,C,Sink1] + allocate[Node1,C,Sink2] <= 1
capacity[Node2,A]: allocate[Node2,A,Sink1] + allocate[Node2,A,Sink2] <= 1
capacity[Node2,B]: allocate[Node2,B,Sink1] + allocate[Node2,B,Sink2] <= 1
capacity[Node2,C]: allocate[Node2,C,Sink1] + allocate[Node2,C,Sink2] <= 1
capacity[Node3,A]: allocate[Node3,A,Sink1] + allocate[Node3,A,Sink2] <= 1
capacity[Node3,B]: allocate[Node3,B,Sink1] + allocate[Node3,B,Sink2] <= 0
capacity[Node3,C]: allocate[Node3,C,Sink1] + allocate[Node3,C,Sink2] <= 1As far as a better way to define the data: explicitly defining the data in the code should be very fast. The modelbuilding time should be negligible for a model of this size.
Thanks,
Eli
0 
Hi Eli,
Thank you for your quick reply.
Apologies for the error. You are correct, I was trying to demonstrate the second set of constraints.
This makes a lot of sense and is exactly what I was looking for! Thank you.
Best,
Irene
0
Please sign in to leave a comment.
Comments
2 comments