Python: Constraint coding problem.
Hi, I would like to know how to code the constraint below.
#index
i |
Task (i = 1, 2, …, I) |
k |
Artificial nodes(k = 1, 2, …, K) |
j,v |
Workstation (j = 1, 2, …, J;v=1, 2, …,V) |
u |
Type of operator (u = 1, 2, …, U) |
#Parameter
#Decision variables
#Constraint
#My code
#index:
I=['i1','i2','i3','i4','i5','i6','i7','i8','i9','i10','i11','i12','i13','i14','i15','i16','i17','i18','i19','i20','i21']
K=['k1','k2','k3','k4','k5','k6','k7','k8','k9','k10','k11','k12','k13','k14','k15','k16','k17','k18']
U=['u1','u2','u3','u4','u5','u6','u7','u8']
J=[int(i)+1 for i in range(21)]
V=['j1','j2','j3','j4','j5','j6','j7','j8','j9','j10','j11','j12','j13','j14','j15','j16','j17','j18','j19','j20','j21']
#decision variables
X= m.addVars( I , J , U , vtype=GRB.BINARY,name="Xiju")
XV= m.addVars( I , V , U , vtype=GRB.BINARY,name="Xivu")
#parameters
Sik={
'i1':{'k1':1,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i2':{'k1':1,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i3':{'k1':1,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i4':{'k1':0,'k2':1,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i5':{'k1':0,'k2':0,'k3':1,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i6':{'k1':0,'k2':0,'k3':1,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i7':{'k1':0,'k2':0,'k3':0,'k4':1,'k5':1,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i8':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':1,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i9':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':1,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i10':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':1,'k7':1,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i11':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':1,'k8':1,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i12':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':1,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i13':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':1,'k10':0,
'k11':0,'k12':0,'k13':1,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i14':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':1,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i15':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':1,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i16':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':1,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i17':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':1,'k15':0,'k16':0,'k17':0,'k18':0},
'i18':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':1,'k16':0,'k17':0,'k18':0},
'i19':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':1,'k17':0,'k18':0},
'i20':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':1,'k18':0},
'i21':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':1},
}
Pik={
'i1':{'k1':0,'k2':1,'k3':1,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i2':{'k1':0,'k2':0,'k3':0,'k4':1,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i3':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':1,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i4':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':1,'k7':1,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i5':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':1,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i6':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':1,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i7':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':1,'k10':1,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i8':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':1,'k12':1,'k13':1,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i9':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':1,'k16':1,'k17':0,'k18':0},
'i10':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':1,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':1,'k15':0,'k16':0,'k17':0,'k18':1},
'i11':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':1,'k15':0,'k16':1,'k17':1,'k18':0},
'i12':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':1,'k18':0},
'i13':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':1,'k14':0,'k15':0,'k16':0,'k17':1,'k18':0},
'i14':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':1},
'i15':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':1,'k17':0,'k18':1},
'i16':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':1,'k18':0},
'i17':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i18':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i19':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i20':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
'i21':{'k1':0,'k2':0,'k3':0,'k4':0,'k5':0,'k6':0,'k7':0,'k8':0,'k9':0,'k10':0,
'k11':0,'k12':0,'k13':0,'k14':0,'k15':0,'k16':0,'k17':0,'k18':0},
}
#constraint
for k in K:
for v in V:
m.addConstr((gurobipy.quicksum(Pik[i][k]*X[i,j,u] for i in I for j in V for u in U))>=(gurobipy.quicksum(Sik[i][k]*XV[i,v,u] for i in I for u in U)),'c8')
#Question
I'm not sure about index, decision variables and constraint.Should I only create a variable(Xiju)?
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi,
Yes, you should only create one set of \(X\) variables as they denote the decision. You could do it with two sets of variables but you would have to enforce equality on each of the variable pairs making the problem unnecessary complicated.
Your code should then look something like this
I=list('i'+str(i) for i in range(1,22))
K=list('k'+str(i) for i in range(1,19))
U=list('u'+str(i) for i in range(1,9))
J=list('j'+str(i) for i in range(1,22))
#decision variables
X= m.addVars( I , J , U , vtype=GRB.BINARY,name="X")
#parameters
Sik = { i : { k : 0 for k in K } for i in I}
Sik['i1']['k1'] = 1
Sik['i2']['k1'] = 1
Sik['i3']['k1'] = 1
Sik['i4']['k2'] = 1
Sik['i5']['k3'] = 1
Sik['i6']['k3'] = 1
Sik['i7']['k4'] = 1
Sik['i7']['k5'] = 1
Sik['i8']['k5'] = 1
Sik['i9']['k6'] = 1
Sik['i10']['k6'] = 1
Sik['i10']['k7'] = 1
Sik['i11']['k7'] = 1
Sik['i11']['k8'] = 1
Sik['i12']['k8'] = 1
Sik['i13']['k9'] = 1
Sik['i13']['k13'] = 1
Sik['i14']['k10'] = 1
Sik['i15']['k11'] = 1
Sik['i16']['k12'] = 1
Sik['i17']['k14'] = 1
Sik['i18']['k15'] = 1
Sik['i19']['k16'] = 1
Sik['i20']['k17'] = 1
Sik['i21']['k18'] = 1
Pik = { i : { k : 0 for k in K } for i in I}
Pik['i1']['k2'] = 1
Pik['i1']['k3'] = 1
Pik['i2']['k4'] = 1
Pik['i3']['k5'] = 1
Pik['i4']['k6'] = 1
Pik['i4']['k7'] = 1
Pik['i5']['k8'] = 1
Pik['i6']['k9'] = 1
Pik['i7']['k9'] = 1
Pik['i7']['k10'] = 1
Pik['i8']['k11'] = 1
Pik['i8']['k12'] = 1
Pik['i8']['k13'] = 1
Pik['i9']['k15'] = 1
Pik['i9']['k16'] = 1
Pik['i10']['k6'] = 1
Pik['i10']['k14'] = 1
Pik['i10']['k18'] = 1
Pik['i11']['k14'] = 1
Pik['i11']['k16'] = 1
Pik['i11']['k17'] = 1
Pik['i12']['k17'] = 1
Pik['i13']['k13'] = 1
Pik['i13']['k17'] = 1
Pik['i14']['k18'] = 1
Pik['i15']['k16'] = 1
Pik['i15']['k18'] = 1
Pik['i16']['k17'] = 1
#constraints
for k in K:
for v in J:
m.addConstr(
(quicksum(Pik[i][k]*X[i,j,u] for i in I for j in J for u in U))
>=(quicksum(Sik[i][k]*X[i,v,u] for i in I for u in U)),'c'+str(k)+str(v))I tried to stick to your notation to avoid confusion. Note that I define the dictionaries \(P_{ik}\) and \(S_{ik}\) differently. I first set all entries to 0. Then, I set the desired entries to 1. Performance wise, this is in general slower than writing the whole dictionary by hand, but as you only have a few 1 entries, it is acceptable and makes the code shorter.
Please let me know if the above was helpful and don't hesitate to ask further questions.
Best regards,
Jaromił0 -
Dear Jaromił:
Thank you for your idea.
I have tried this but it is in feasible.The error report as the enclosed picture.
On my opinion, I thought the reason was that you only create one variable X[i,j,u] but in the part of constraints, you wrote X[i,j,u] & X[i,v,u].
I'm glad to discuss with you.
B.R.,
Jimmy
0 -
Dear Jaromił:
I also found a mistake(as the red rectangle) from your code below. Index J should be revise as index V.
I forget to explain what constraint (8) means: It ensures that the selected
successor is not assigned to a lower -indexed station than the one to which the
selected predecessor is assigned.The constraint:
Your code:
The key point is that index V hasn't been created,but both J and V are meaning work stations. And J is predecessor, V is successor.
B.R.,
Jimmy
0 -
Hi Jimmy,
I am not sure if I understand your problem correctly. In your code you define \(J\) as a list of integers and \(V\) as a list of strings. I assume the \(J\) list is defined this way due to your other Community post. Are the sets \(J\) and \(V\) meant to be equal? If yes, then I think that you don't need both to construct your constraint (8).
Could you provide an example of constraint (8) with small sets \(U\), \(I\), \(V\), and \(K\), e.g., the cardinality of all sets could be 2 and all \(p_{ik}\) and \(s_{ik}\) equal 1, and check if the above code produces the desired constraints? You can do it conveniently by calling \(\texttt{model.write("myLP.lp")}\).
As far as I understand, with the above, constraint (8) would provide
\(\begin{align}
&p_{11} X_{111} + p_{11} X_{121} + p_{11} X_{112} + p_{11} X_{122}\\
+&p_{21} X_{211} + p_{21} X_{221} + p_{21} X_{212} + p_{21} X_{222} \\
\geq & s_{11} X_{111} + s_{11} X_{112} + s_{21} X_{211} + s_{21} X_{212}
\end{align}\)
If now all \(p\) and \(s\) equal 1 you can eliminate 4 variables. If not, then you can eliminate only parts of the variables. This is should be achieved by the provided code.Best regards,
Jaromił0 -
Hi Jaromił,
You are right that you assume the J list is defined this way due to my other community post.
Sets J & V both are the index of workstation,but when they come to constraint(8); J is predecessor and V is successor.B.R.,
Jimmy
0 -
Hi Jimmy,
How do you express that \(J\) is a predecessor and \(V\) is a successor? Is it modeled in a different constraint?
In constraint (8), you use the set \(V\) only and since \(J\) has the same indices as \(V\), you can just use \(J\) in this case.
Did you try writing down the constraints and printing the LP file to check whether the code produces the constraints you desire?Best regards,
Jaromił0
Post is closed for comments.
Comments
7 comments