Error while defining a variable
AnsweredHello,
I have an error that seems to be occuring when I am defining a variable. I have looked online, try to modify the upper and lower bounds, modify the constraints that use the variable in case they would cause the problem in the first place, etc. Nothing worked so farn I am starting to be a little bit desperate... Thank you in advance for any help you could give me.
The error that I receive is a list index out of range when I am defining E, but I don't know where it could come from. This is the error:
runfile('C:/Users/atouz/Documents/SJTU/Thèse/Stage 1 Gurobi.py', wdir='C:/Users/atouz/Documents/SJTU/Thèse')
Traceback (most recent call last):
File ~\.conda\envs\MyVirtualEnvironment\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
exec(code, globals, locals)
File c:\users\atouz\documents\sjtu\thèse\stage 1 gurobi.py:45
E = m.addVars(lb=0.0,ub=M,vtype = gp.GRB.CONTINUOUS, name = 'E')
File src\gurobipy\model.pxi:2795 in gurobipy.Model.addVars
File src\gurobipy\model.pxi:261 in gurobipy.__listify.__init__
IndexError: list index out of range
The sets used in the code taken from the excel file are the following:
I = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
J = [50, 63, 65, 51, 52, 54, 56, 45, 41, 61]
A = [800, 95, 468, 358, 439, 1187, 298, 565, 1247, 311]
G = [3, 3, 10, 10, 3, 3, 10, 3, 10, 3]
And the code is as follow:
import gurobipy
import pandas as pd
excel = pd.ExcelFile(r"C:\Users\atouz\Documents\SJTU\Thèse\Data_trains.xlsx")
df1 = pd.read_excel(excel,sheet_name="Trains")
excel.close()
# Sets and parameters
I,Train_nb,Q,G,J,A =[df1.iloc[:,i].tolist() for i in range(6)]
t_buf = 5 #in minutes
M = 15000
K = [k for k in range(1,6)] #number of lines
Pta = 5
Ptd = 5
# Define a mapping from G values to time value
time_mapping = {
"Containers": 3, # time required for Containers
"Steel coils & equivalent": 10, # time required for Steel coils & equivalent
}
# Use a list comprehension to create the list of time values
G = [time_mapping.get(g, g) for g in G]
w_i = [J[i-1]*G[i-1] for i in I]
# Model
m = gp.Model("Stage_1")
# Decision variables
x = m.addVars(I,K,vtype = gp.GRB.BINARY, name='x')
y = m.addVars(K,vtype = gp.GRB.BINARY, name='y')
z = m.addVars(K,vtype = gp.GRB.BINARY, name='z')
D = m.addVars(I,vtype = gp.GRB.CONTINUOUS, name = 'D')
E = m.addVars(lb=0.0,ub=M,vtype = gp.GRB.CONTINUOUS, name = 'E')
F = m.addVars(lb=0.0,ub=M,vtype = gp.GRB.CONTINUOUS, name = 'F')
Tia = m.addVars(I,vtype = gp.GRB.CONTINUOUS, name = 'Tia')
W = m.addVars(K,vtype = gp.GRB.CONTINUOUS, name = 'W')
m.update()
# Subject to constraints
# Line specific constraints
One_Train_per_line = m.addConstrs((gp.quicksum(x[i,k] for k in K) == 1 for i in I), name='One_Train_per_line')
One_Train_at_a_time = m.addConstrs((gp.quicksum(x[i,k] for i in I) <= 1 for k in K), name='One_Train_at_a_time')
# Workload specific constraints
for k in K:
Workload = m.addConstrs((W[k] == gp.quicksum(w_i[i] * x[i, k] for i in I)), name='Workload')
F_lowbound = m.addConstr((F >= W[k]), name='F_lowbound')
F_upbound = m.addConstr((F <= W[k] + M*(1-z[k])),name='F_upbound')
Nb_Lines_max_wk = m.addConstrs((gp.quicksum(z[k]) >= 1), name='Nb_Lines_max_wk')
E_upbound = m.addConstrs((E <= W[k]), name='E_lowbound')
E_lowbound = m.addConstrs((E >= W[k] + M*(1-y[k])),name='E_upbound')
Nb_Lines_min_wk = m.addConstrs((gp.quicksum(y[k]) >= 1), name='Nb_Lines_min_wk')
# Time specific constraints
Min_Di = m.addConstrs((A[i] + Pta + Ptd + w_i[i] <= D[i] for i in I), name="Min_Di")
Tia_lowbound = m.addConstrs((Tia[i] >= A[i] + Pta for i in I), name='Tia_lowbound')
Tia_upbound = m.addConstrs((Tia[i] <= D[i] - Ptd - w_i[i] for i in I), name='Tia_upbound')
Security = m.addConstrs((D[j] - A[i] >= t_buf - M*(2-x[i,k]-x[j,k]) for i in I for j in I if i!=j for k in K),name="Security")
# Objective function
m.setObjective(F - E, gp.GRB.MINIMIZE)
m.write('Stage1.lp')
m.optimize()
-
Hi Alexandre,
If E and F are just single variables then use Model.addVar. The Model.addVars function is expecting one or more indices as the first argument.
- Riley
0 -
Thank you!! It was that indeed. I have modified it as you proposed but I have other errors in the constraints that I don't know how to fix. Sorry that those are be simple questions, I am new to using gurobi.
I suppose that it is a syntax issue, but I am not sure what to change.
The problem is that for the constraints Workload, Min_Di, Tia_lowbound, Tia_upbound and Security I receive the message IndexError: list index out of range. Can you see what is wrong?
# Line specific constraints
One_Train_per_line = m.addConstrs((gp.quicksum(x[i,k] for k in K) == 1 for i in I), name='One_Train_per_line')
One_Train_at_a_time = m.addConstrs((gp.quicksum(x[i,k] for i in I) <= 1 for k in K), name='One_Train_at_a_time')
# Workload specific constraints
Workload = m.addConstrs((W[k] == gp.quicksum(w_i[i] * x[i,k] for i in I) for k in K), name='Workload')
F_lowbound = m.addConstrs(((F >= W[k]) for k in K), name='F_lowbound')
F_upbound = m.addConstrs(((F <= W[k] + M*(1-z[k])) for k in K),name='F_upbound')
Nb_Lines_max_wk = m.addConstrs((gp.quicksum(z[k] for k in K) >= 1 for k in K), name='Nb_Lines_max_wk')
E_upbound = m.addConstrs(((E <= W[k]) for k in K), name='E_lowbound')
E_lowbound = m.addConstrs(((E >= W[k] + M*(1-y[k])) for k in K),name='E_upbound')
Nb_Lines_min_wk = m.addConstrs((gp.quicksum(y[k] for k in K) >= 1 for k in K), name='Nb_Lines_min_wk')
# Time specific constraints
Min_Di = m.addConstrs((A[i] + Pta + Ptd + w_i[i] <= D[i] for i in I), name="Min_Di")
Tia_lowbound = m.addConstrs((Tia[i] >= A[i] + Pta for i in I), name='Tia_lowbound')
Tia_upbound = m.addConstrs((Tia[i] <= D[i] - Ptd - w_i[i] for i in I), name='Tia_upbound')
Security = m.addConstrs((D[j] - A[i] >= t_buf - M*(2-x[i,k]-x[j,k]) for i in I for j in I if i!=j for k in K),name="Security")0 -
Hi Alexandre,
It is not easy for me to help you, since this is not a minimum reproducible example.
Perhaps the simplest solution is to do some "print debugging". For example, if there is an issue with Min_Di constraints then try finding the exact error by running the following code:
for i in I:
print("value of i", i)
print(A[i])
print(w_i[i])
print(D[i])Knowing where exactly the code fails will help you figure out what is going wrong.
- Riley
0 -
Thanks to your advice, I think I found where I was incorrect. Thank you a lot!
0
Please sign in to leave a comment.
Comments
4 comments