Unable to model constraint
AnsweredI've tried everything to add a constraint to my model, but I just can't seem to get it to work.
The constraint I'm trying to add is:
In my model, t is defined as a list of time points where the last element of the list is h.
Furthermore I have the follow dictionary:
times = {
(0.0, 0.0, 0.0) 12.0,
(0.0, 1.0, 1.0) 9.0,
(1.0, 1.0, 1.0) 11.0,
(0.0, 2.0, 2.0) 11.0,
(1.0, 2.0, 2.0) 80,0,
(0.0, 3.0, 3.0) 13.0,
(0.0, 4.0, 4.0) 9.0,
(0.0, 5.0, 5.0) 15.0,
(0.0, 6.0, 6.0) 2.0,
(1.0, 6.0, 6.0) 4.0,
(2.0, 6.0, 6.0) 44.0,
(4.0, 6.0, 7.0) 11.0,
(0.0, 7.0, 8.0) 99.0,
(1.0, 7.0, 8.0) 13.0,
(2.0, 7.0, 8.0) 4.0,
(4.0, 7.0, 8.0) 15.0,
(0.0, 8.0, 8.0) 23.0,
(1.0, 8.0, 8.0) 23.0,
(2.0, 8.0, 8.0) 2.0,
(4.0, 8.0, 8.0) 34.0,
(1.0, 9.0, 0.0) 29.0,
(1.0, 10.0, 3.0) 77.0,
(1.0, 11.0, 5.0) 4.0
}
Here the first element of each tuple key is p, the second j and the third k. All the p's together for set P, all j's together for set J and all k's together form set K.
The values in the dictionary are the tau for each p, j, k combination.
The X variables are created for every key in the dictionary combined with the time points t, so X[p,j,k,t]. The F variables are created exactly the same.
Is there someone that knows how to correctly implement the constraint into my model? I've been stuck on this for two days.
-
Could you please share a minimal reproducible example where you implement the respective lists/sets, variables and try to implement the constraint you mentioned?
0 -
First an multidict is created:
proc_combo, costs = {
(0, 0, 0): 5,
(0, 1, 1): 10,
(1, 1, 1): 15,
(0, 2, 2): 20,
(1, 2, 2): 25,
(0, 3, 3): 30,
(0, 4, 4): 35,
(0, 5, 5): 40,
(0, 6, 6): 45,
(1, 6, 6): 50,
(2, 6, 6): 55,
(4, 6, 7): 60,
(0, 7, 8): 65,
(1, 7, 8): 70,
(2, 7, 8): 75,
(4, 7, 8): 80,
(0, 8, 8): 85,
(1, 8, 8): 90,
(2, 8, 8): 95,
(4, 8, 8): 100,
(1, 9, 0): 105,
(1, 10, 3): 110,
(1, 11, 5): 115,
(3, 12, 8): 120}The dictionary times, mentioned in the first post, is created. Note that the tuples that form the keys are the same tuples als in the multidict.
times = {
(0.0, 0.0, 0.0) 12.0,
(0.0, 1.0, 1.0) 9.0,
(1.0, 1.0, 1.0) 11.0,
(0.0, 2.0, 2.0) 11.0,
(1.0, 2.0, 2.0) 80,0,
(0.0, 3.0, 3.0) 13.0,
(0.0, 4.0, 4.0) 9.0,
(0.0, 5.0, 5.0) 15.0,
(0.0, 6.0, 6.0) 2.0,
(1.0, 6.0, 6.0) 4.0,
(2.0, 6.0, 6.0) 44.0,
(4.0, 6.0, 7.0) 11.0,
(0.0, 7.0, 8.0) 99.0,
(1.0, 7.0, 8.0) 13.0,
(2.0, 7.0, 8.0) 4.0,
(4.0, 7.0, 8.0) 15.0,
(0.0, 8.0, 8.0) 23.0,
(1.0, 8.0, 8.0) 23.0,
(2.0, 8.0, 8.0) 2.0,
(4.0, 8.0, 8.0) 34.0,
(1.0, 9.0, 0.0) 29.0,
(1.0, 10.0, 3.0) 77.0,
(1.0, 11.0, 5.0) 4.0
}Than a list of time points is created:
time_points =[]
for i in range(250):
time_points.append(i)
i += 1Here the first element of each tuple key is p, the second j and the third k. All the p's together for set P, all j's together for set J and all k's together form set K.
The values in the dictionary are the tau for each p, j, k combination.
Then the X and F variables are created with the aid of the multidict and the list:
X = m.addVars([(int(p), int(j), int(k), t) for (p, j, k) in proc_combo for t in time_points], vtype=GRB.BINARY, name='X')
F = m.addVars([(int(p), int(j), int(k), t) for (p, j, k) in proc_combo for t in time_points], vtype=GRB.BINARY, name='F')Subsequent I'm trying to add the constraint shown below.
0 -
Your constraint as it stands has an issue. You want to add a constraint \(\forall j \in J\setminus \{12\}, \{t \in T | t+\tau_{pjk} 1 \leq h\}\) where \(\tau\) depends on indices \(p,k\) which are only used in the sums, i.e., it is not clear which \(p,k\) to use when constructing for a fixed \(t\).
Could you please clarify or adjust your constraint such that it is a valid one?
0 -
My apologies, you're right. The additional condition for t can be dropped so that it the constraint must only hold for all j (except 12) and t:
0 -
Hi Sander,
Here is a version which might work for you.
m = gp.Model()
proc_combo, costs = gp.multidict({
(0, 0, 0): 5,
(0, 1, 1): 10,
(1, 1, 1): 15,
(0, 2, 2): 20,
(1, 2, 2): 25,
(0, 3, 3): 30,
(0, 4, 4): 35,
(0, 5, 5): 40,
(0, 6, 6): 45,
(1, 6, 6): 50,
(2, 6, 6): 55,
(4, 6, 7): 60,
(0, 7, 8): 65,
(1, 7, 8): 70,
(2, 7, 8): 75,
(4, 7, 8): 80,
(0, 8, 8): 85,
(1, 8, 8): 90,
(2, 8, 8): 95,
(4, 8, 8): 100,
(1, 9, 0): 105,
(1, 10, 3): 110,
(1, 11, 5): 115,
(3, 12, 8): 120})
P = [p for p in range(5)]
J = [j for j in range(13)]
K = [k for k in range(9)]
times = {
(0.0, 0.0, 0.0): 12.0,
(0.0, 1.0, 1.0): 9.0,
(1.0, 1.0, 1.0): 11.0,
(0.0, 2.0, 2.0): 11.0,
(1.0, 2.0, 2.0): 80.0,
(0.0, 3.0, 3.0): 13.0,
(0.0, 4.0, 4.0): 9.0,
(0.0, 5.0, 5.0): 15.0,
(0.0, 6.0, 6.0): 2.0,
(1.0, 6.0, 6.0): 4.0,
(2.0, 6.0, 6.0): 44.0,
(4.0, 6.0, 7.0): 11.0,
(0.0, 7.0, 8.0): 99.0,
(1.0, 7.0, 8.0): 13.0,
(2.0, 7.0, 8.0): 4.0,
(4.0, 7.0, 8.0): 15.0,
(0.0, 8.0, 8.0): 23.0,
(1.0, 8.0, 8.0): 23.0,
(2.0, 8.0, 8.0): 2.0,
(4.0, 8.0, 8.0): 34.0,
(1.0, 9.0, 0.0): 29.0,
(1.0, 10.0, 3.0): 77.0,
(1.0, 11.0, 5.0): 4.0
}
time_points =[]
for i in range(250):
time_points.append(i)
i += 1
X = m.addVars([(int(p), int(j), int(k), t) for (p, j, k) in proc_combo for t in time_points], vtype=GRB.BINARY, name='X')
F = m.addVars([(int(p), int(j), int(k), t) for (p, j, k) in proc_combo for t in time_points], vtype=GRB.BINARY, name='F')
for j in J:
if j == 12:
continue
for t in time_points:
m.addConstr(gp.quicksum(X[p,j,k,t_prime] for p in P
for k in K if (p,j,k) in proc_combo
for t_prime in range(t,t+int(times[p,j,k])-1) if t+int(times[p,j,k])-1 <= 250)
+ gp.quicksum(F[p,j,k,t] for p in P
for k in K if (p,j,k) in proc_combo)
<= 1)There are multiple things to note here. You originally did not define objects proc_combo and costs as a multidict. I added the lists P,J,K for easier \(\texttt{for}\)-loops in the quicksums. Additionally, there was a typo at "(1.0, 2.0, 2.0): 80,0,".
In the above, we are adding a constraint 1 by 1. In your latest comment, it is \(J_{pk}\) so it might be that your set \(J\) is dependent on indicies \(p,k\). As mentioned in my previous comment, this will not work, because \(p,k\) are only within the constraint and not in the "\(\forall\)" block.
We had to add the safe guards "if (p,j,k) in proc_combo" and "if t+int(times[p,j,k])-1 <= 250" to avoid index key errors. It is possible that there is a nicer way of writing these constraints when different data structures are used but I think this should give you a good idea of how to approach such constraints in the future.
When working with complex constraints, I would recommend to write the model to a human-readable LP file via the write method and analyze the resulting file.
m.write("myModel.lp")Best regards,
Jaromił0 -
Thank you for your clear answer, despite the mistakes in my post. The constraint finally seems to work!
0
Please sign in to leave a comment.
Comments
6 comments