How can I get constraints to find the maximum completion time in each machines?
OngoingI have tried to create the constraints to get the max value of completion time for each machine.
import gurobipy as gp
from gurobipy import GRB
import pandas as pd
m = gp.Model("Sustainable")
Num_of_machines = 3
Machines = range(1,Num_of_machines+1)
Num_of_jobs = 9
Jobs = range (1,Num_of_jobs+1)
Time_span = 24
Times = range(1,Time_span+1)
Times_buffer = range(1,Time_span+10)
Processing = {1:4,2:2,3:3,4:1,5:1,6:5,7:3,8:3,9:5}
Due_date = {1:4,2:3,3:4,4:2,5:6,6:8,7:10,8:11,9:7}
x = {}
for i in Jobs:
for j in Machines:
for k in Times_buffer:
x[i,j,k] = m.addVar(vtype = GRB.BINARY,name = "x")
y = {}
for j in Machines:
for k in Times:
y[j,k] = m.addVar(vtype = GRB.BINARY,name = "y")
s = {}
for i in Jobs:
for j in Machines:
for k in Times:
s[i,j,k] = m.addVar(vtype = GRB.BINARY,name = "s")
Starting_buffer_const = m.addConstrs(((gp.quicksum(gp.quicksum(s[i,j,k]* Times[Times.index(k)] for j in Machines) for k in Times)) <= Time_span  Processing[i] for i in Jobs), name = "Starting_buffer_const")
Starting_time_Consts = m.addConstrs((gp.quicksum(gp.quicksum(s[i,j,k] for j in Machines) for k in Times) == 1 for i in Jobs) , name = "Starting_Const")
machine_status = m.addConstrs((gp.quicksum(x[i,j,k] for i in Jobs) + y[j,k] == 1 for j in Machines for k in Times),name = "Machine_status")
Machine_capacity = m.addConstrs((gp.quicksum(x[i,j,k] for i in Jobs) <= 1 for j in Machines for k in Times), name = "Machine_capacity")
Production_Const = m.addConstrs(((gp.quicksum(x[i,j,k] for k in range(k,k+(Processing[i]))) >= s[i,j,k]*Processing[i]) for i in Jobs for j in Machines for k in Times),name = "Production_const")
aux1 = m.addVars(Jobs, lb = 20.0, vtype=GRB.CONTINUOUS, name="aux1")
aux2 = m.addVars(Jobs, lb = 20.0, vtype=GRB.CONTINUOUS, name="aux2")
Max_Completion_Time = m.addVars(Jobs, lb = 0.0, vtype=GRB.CONTINUOUS, name="Max_Completion_Time")
Earliness_i = m.addVars(Jobs, vtype=GRB.CONTINUOUS, name="Earliness")
Tardiness_i = m.addVars(Jobs, vtype=GRB.CONTINUOUS, name="Tardiness")
completion_time = {}
for i in Jobs:
for j in Machines:
completion_time[i, j] = m.addVar(vtype=GRB.CONTINUOUS, lb=0, name="completion_time")
Starting_job = {}
for i in Jobs:
Starting_job[i] = (gp.quicksum(gp.quicksum(s[i,j,k] for j in Machines)*k for k in Times))
completion_time[i,j] = Starting_job[i]+Processing[i]
max_completion_time = {}
for j in Machines:
max_completion_time[j] = m.addGenConstrMax(Max_Completion_Time[j],completion_time[i, j],name="Max_completion_time")
Tardy = m.addConstrs((Starting_job[i] + Processing[i]  1  Due_date[i]  aux1[i] == 0 for i in Jobs), name="aux_constr1.1")
Early = m.addConstrs((Due_date[i]  Starting_job[i]  Processing[i] + 1  aux2[i] == 0 for i in Jobs), name="aux_constr1.2")
Tardy_Cal = m.addConstrs((Tardiness_i[i] == gp.max_([aux1[i], 0.0]) for i in Jobs), name="aux_constr2.1")
Early_Cal = m.addConstrs((Tardiness_i[i] == gp.max_([aux1[i], 0.0]) for i in Jobs), name="aux_constr2.2")
It got an error here "TypeError: object of type 'Var' has no len()". How can I fix this problem?
Thank you

Hi,
To find the maximum completion time for each machine, you can use the following code:
Max_Completion_Time = m.addVars(Machines, vtype=GRB.CONTINUOUS, name="Max_Completion_Time")
completion_time = m.addVars(Jobs, Machines,vtype=GRB.CONTINUOUS, lb=0, name="completion_time")
Max_Completion_Time_constrs = m.addConstrs( (Max_Completion_Time[j] == gp.max_(completion_time[i, j] for i in Jobs) for j in Machines), name= "Max_Completion_Time")Also, note that with your following code, all x variables get the same name, "x"for i in Jobs: for j in Machines: for k in Times_buffer: x[i,j,k] = m.addVar(vtype = GRB.BINARY,name = "x")
You can use the addVars() method to ensure your variables get names based on indices.x = m.addVars( Jobs, Machines, Times_buffer, vtype = GRB.BINARY,name = "x")
Regards,Simran0 
Hello Simran,
Thank you for the reply, but it still does not work. After I changed some codes to the following codes.
I got the error "GurobiError: Invalid data in vars array"
GurobiError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_9928\2500881551.py in <module> 29 # max_completion_time[j] = m.addGenConstrMax(Max_Completion_Time[j],completion_time[i, j],name="Max_completion_time") 30 > 31 Max_Completion_Time = m.addConstrs( (Max_Completion_Time[j] == gp.max_(completion_time[i, j] for i in Jobs) for j in Machines), name= "Max_Completion_Time") 32 33 Tardy = m.addConstrs((Starting_job[i] + Processing[i]  1  Due_date[i]  aux1[i] == 0 for i in Jobs), name="aux_constr1.1") src\gurobipy\model.pxi in gurobipy.Model.addConstrs() src\gurobipy\model.pxi in gurobipy.Model.addConstr() src\gurobipy\genexpr.pxi in gurobipy.GenExprMax._addAsConstr() src\gurobipy\model.pxi in gurobipy.Model.addGenConstrMax() GurobiError: Invalid data in vars array
Best regards
Jirayu
0 
Hi Jirayu,
The error you are seeing is coming from another part of your code.
First, let's note that gp.max_ method takes a variable, a list of variables, or a tupledict of variables as arguments.
Now, let's look at the following line of your code.
completion_time[i,j] = Starting_job[i]+Processing[i]
This makes completion_time[I,j] a LinExpr, which is not supported by the gp.max_method as an argument; hence, you see the error.
Also, the above line of code will not give the desired completion time of i on a machine j. For example, let's say we have two machines and one job. Suppose the job starts at time 1 on machine 1 and has a processing time of 5. So, as per your code, Starting_job[i] will be 1, and the completion time of the job on both machine 1 and machine 2 is 6, which is incorrect
One way to fix this will be to define completion_time[i,j] as variables
completion_time = m.addVars(Jobs, Machines,vtype=GRB.CONTINUOUS, name="completion_time")
and replace
completion_time[i,j] = Starting_job[i]+Processing[i]
with the following constraints that calculate the completion time of a job on a machine using your "s" variables that indicate whether a job starts on the machine and at what time.
completion_time_constr = m.addConstrs(( completion_time[i,j] == gp.quicksum( (k+Processing[i]) * s[i,j,k] for k in Times ) for i in Jobs for j in Machines), name="completion_time")
Regards,
Simran
0 
Hello Simran,
Thank you for fixing my wrong code. Your code is perfect, but I got the new problem after I calculate the idle time.
Total_ET = gp.quicksum(Earliness_i[i] for i in Jobs) + gp.quicksum(Tardiness_i[i] for i in Jobs)
Total_Idel_Time = gp.quicksum(Max_Completion_Time[j] for j in Machines)+ gp.quicksum(Processing[i] for i in Jobs)
m.setObjectiveN(Total_Idel_Time, index=1, priority = 1, name = "Total_Idel_Time")
m.setObjectiveN(Total_ET, index=0, priority = 2, reltol = 0.4 , name = "Total_ET")TypeError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_4332\2182328771.py in <module> 1 Total_ET = gp.quicksum(Earliness_i[i] for i in Jobs) + gp.quicksum(Tardiness_i[i] for i in Jobs) > 2 Total_Idel_Time = gp.quicksum(Max_Completion_Time[j] for j in Machines)+ gp.quicksum(Processing[i] for i in Jobs) 3 4 m.setObjectiveN(Total_Idel_Time, index=1, priority = 1, name = "Total_Idel_Time") 5 m.setObjectiveN(Total_ET, index=0, priority = 2, reltol = 0.4 , name = "Total_ET") src\gurobipy\gurobi.pxi in gurobipy.quicksum() TypeError: unsupported operand type(s) for +=: 'gurobipy.LinExpr' and 'GenConstr'
It is about the unsupported code for 'gurobipy.LinExpr' and 'GenConstr'
Best regards
Jirayu
0 
Hi Jirayu,
One can only sum constants, Var objects, LinExpr objects, or QuadExpr objects using the quicksum() method.
You are getting the error
TypeError: unsupported operand type(s) for +=: 'gurobipy.LinExpr' and 'GenConstr'
as Max_Completion_Time[j] is a general constraint object in the quicksum below
gp.quicksum(Max_Completion_Time[j] for j in Machines)
Please name your constraint differently from the variable names
Max_Completion_Time_constrs = m.addConstrs( (Max_Completion_Time[j] == gp.max_(completion_time[i, j] for i in Jobs) for j in Machines), name= "Max_Completion_Time")
Regards,
Simran
0 
Thank you Simran I really appreciate your help. It's perfect.
0 
Hi All,
I have few more questions in accordance with the discussion 1. What if I need to calculate maximum completion time of each job (where each job has different no of operations, i.e., job 1 has 3 operations, job 2 has 2 operations), so that I can calculate tardiness and earliness based on delivery time window, for e.g., [a_i, b_i] = [18, 24].
2. How to consider setup time of machines, delay time of machines and transportation time between machines while calculating makespan?
0
Please sign in to leave a comment.
Comments
7 comments