Why does my time limit doesn't work in IPython 8.10.0?
回答済みfrom pyomo.environ import *
m=AbstractModel ('Modelo1TFG')
import pyoutil as pu
#INDICES
m.I= Set() #nodos
m.K= Set() #vehículo
#CONJUNTOS duda sobre por cual termino se multiplica k
m.RP = Set(within=m.K)
m.RS = Set(within=m.K)
m.IJ = Set(within=m.I*m.I)
#PARAMETROS
m.dem = Param(m.I)
m.cap = Param(m.K)
m.p = Param()
m.cf = Param(m.K)
m.cv = Param(m.K)
m.dis = Param(m.IJ)
m.t = Param(m.IJ)
m.ts = Param()
m.hi = Param()
m.hm = Param(m.I)
m.o = Param(m.K)
m.vmax = Param()
m.M = Param()
#VARIABLES
m.Y = Var(m.I,m.K, domain=Boolean, initialize = 0)
m.YS = Var(m.IJ,m.K, domain=Boolean, initialize = 0)
m.YK = Var(m.K, domain=Boolean, initialize = 0)
m.C = Var(m.IJ,m.K, domain=Integers, initialize = 0, bounds=(0, None)) #bound maximo cap/p. Relajada
m.CA = Var(m.I,m.K, domain=Integers, initialize = 0, bounds=(0, None))
m.DE = Var(m.I,m.K, domain=Integers, initialize = 0, bounds=(0, None))
m.HE = Var(m.I,m.K, domain=Integers, initialize = 0, bounds=(0, None)) #bound un día en minutos. Relajada
m.HS = Var(m.I,m.K, domain=Integers, initialize = 0, bounds=(0, None)) #bound un día en minutos . Relajada
m.ADELANTO = Var(m.I,m.K, domain=Integers, initialize = 0, bounds=(0, None))
m.RETRASO = Var(m.I,m.K, domain=Integers, initialize = 0, bounds=(0, None))
m.YRET = Var(m.I,m.K, domain = Boolean, initialize = 0)
#EXPRESSIONS
#duda sobre como realizar dos sumatorios uno de variables y otra de fijo (considere solamente la parte vble falta la fija)
def CosteFijo_rule (m):
return sum(m.YK[k] * m.cf[k] for k in m.K)
m.CosteFijo = Expression(rule = CosteFijo_rule)
def CosteVariable_rule (m):
return sum (m.YS[i,j,k] * m.cv[k] * m.dis[i,j] for i in m.I for j in m.I for k in m.K if (i,j) in m.IJ)
m.CosteVariable= Expression(rule= CosteVariable_rule)
def Penalizacion_rule(m):
return sum(m.RETRASO[i,k] for i in m.I for k in m.K if i != m.o[k])*0.5
m.Penalizacion=Expression(rule= Penalizacion_rule)
def Objetivo_rule (m):
return m.CosteFijo + m.CosteVariable + m.Penalizacion
m.obj = Objective(rule = Objetivo_rule, sense = minimize)
#CONSTRAINTS
def ADRET_rule(m,i,k):
return m.HE[i,k] - m.hm[i] == m.RETRASO[i,k] - m.ADELANTO[i,k]
m.ADRET = Constraint(m.I,m.K, rule = ADRET_rule)
def ADR1_rule(m,i,k):
return m.RETRASO[i,k] <= 1440 * m.YRET[i,k]
m.ADR1 = Constraint(m.I,m.K, rule = ADR1_rule)
def ADR2_rule(m,i,k):
return m.YRET[i,k] <= m.RETRASO[i,k]
m.ADR2 = Constraint(m.I,m.K, rule = ADR2_rule)
def ADR3_rule(m,i,k):
return m.ADELANTO[i,k] <= 1440 - 1440 * m.YRET[i,k]
m.ADR3 = Constraint(m.I,m.K, rule = ADR3_rule)
def ADR4_rule(m,i,k):
return 1 - m.YRET[i,k] <= m.ADELANTO[i,k]
m.ADR4 = Constraint(m.I,m.K, rule = ADR4_rule)
'''-----------------------------------------------
CARGA VEHÍCULOS
-----------------------------------------------'''
''' Asumo que los vehículos solo pueden cargarse en su nodo origen '''
''' Poner como futura línea de mejora que se puedan cargar en cualquier nodo '''
def R1_rule(m,i,k):
if i == m.o[k]:
return m.CA[i,k] >= 0
else:
return m.CA[i,k] == 0
m.R1 = Constraint(m.I, m.K, rule = R1_rule)
''' Debe salir de la fábrica suficiente cantidad de producto para satisfacer toda la demanda '''
def R2_rule(m):
return sum(m.CA[0,k] for k in m.K if (k) in m.RP) >= sum(m.dem[i] for i in m.I)
m.R2 = Constraint(rule = R2_rule)
''' La cantidad cargada en el vehículo se encuentra limitada por su capacidad '''
def R3_rule(m,k):
return m.CA[m.o[k],k] * m.p <= m.YK[k] * m.cap[k]
m.R3 = Constraint(m.K, rule = R3_rule)
'''-----------------------------------------------
BALANCE PRODUCTO VEHÍCULOS
-----------------------------------------------'''
''' La cantidad de producto que se transporta desde el nodo de origen hasta el siguiente nodo es la cantidad que se ha cargado '''
def R4_rule(m,k):
return m.CA[m.o[k],k] == sum(m.C[m.o[k],j,k] for j in m.I if (m.o[k],j) in m.IJ)
m.R4 = Constraint(m.K, rule = R4_rule)
''' Balance de producto en cada nodo de un mismo vehículo '''
def R6_rule(m,j,k):
if j != m.o[k]:
return sum(m.C[i,j,k] for i in m.I if (i,j) in m.IJ) == m.DE[j,k] + sum(m.C[j,i,k] for i in m.I if (j,i) in m.IJ)
else:
return Constraint.Skip
m.R6 = Constraint(m.I, m.K, rule = R6_rule)
'''El vehículo vuelve vacío al nodo de origen '''
def R7_rule(m,k):
return sum(m.C[i,m.o[k],k] for i in m.I if (i,m.o[k]) in m.IJ) == 0
m.R7 = Constraint(m.K, rule = R7_rule)
''' Un vehículo solo puede transportar producto de un nodo a otro si el vehículo realiza ese trayecto '''
def R8_rule(m,i,j,k):
return m.C[i,j,k] * m.p <= m.YS[i,j,k] * m.cap[k]
m.R8 = Constraint(m.IJ, m.K, rule = R8_rule)
'''-----------------------------------------------
BALANCE PRODUCTO VEHÍCULOS
-----------------------------------------------'''
''' La demanda de los nodos debe ser satisfecha por el producto que llega al nodo '''
def R9_rule(m,i):
if i >= 1:
return sum(m.DE[i,k] for k in m.K) == sum(m.CA[i,k] for k in m.K) + m.dem[i]
else:
return Constraint.Skip
m.R9 = Constraint (m.I, rule = R9_rule)
'''-----------------------------------------------
VISITA DE NODOS
-----------------------------------------------'''
''' Todos los nodos deben ser visitados al menos por un vehículo '''
def R10_rule(m,i):
return sum(m.Y[i,k] for k in m.K) >= 1
m.R10 = Constraint(m.I, rule = R10_rule)
''' Cuando un vehículo sale de un nodo puede ir directamente solo a otro nodo '''
def R11_rule(m,i,k):
return sum(m.YS[i,j,k] for j in m.I if (i,j) in m.IJ) == m.Y[i,k]
m.R11 = Constraint(m.I,m.K, rule = R11_rule)
''' Cuando un vehículo llega a un nodo solo puede venir directamente desde otro nodo '''
def R12_rule(m,i,k):
return sum(m.YS[j,i,k] for j in m.I if (j,i) in m.IJ) == m.Y[i,k]
m.R12 = Constraint(m.I,m.K, rule = R12_rule)
''' Los vehículos de rutas secundarias no pueden visitar la fábrica '''
def R13_rule(m,k):
return m.Y[0,k] == 0
m.R13 = Constraint(m.RS, rule = R13_rule)
'''-----------------------------------------------
USO DE LOS VEHICULOS
-----------------------------------------------'''
''' Se utiliza un camión si este visita algún nodo '''
def R14_rule(m,i,k):
return m.YK[k] >= m.Y[i,k]
m.R14 = Constraint(m.I,m.K, rule = R14_rule)
''' Como máximo se puede utilizar un determinado número de camiones '''
def R15_rule(m):
return sum(m.YK[k] for k in m.K) <= m.vmax
m.R15 = Constraint(rule = R15_rule)
#A partir de aquí no he modificdo las restricciones para hacer el modelo más compacto
'''-----------------------------------------------
VENTANAS TEMPORALES
-----------------------------------------------'''
''' En las rutas primarias, los vehículos pueden salir desde hi del nodo inicial. En cuanto al resto de nodos, puede salir de ellos tras hacer las tareas de carga/descarga '''
def R16_rule(m,i,k):
if i == 0:
return m.HS[i,k] >= m.Y[i,k] * m.hi
else:
return m.HS[i,k] == m.HE[i,k] + m.Y[i,k] * m.ts
m.R16 = Constraint(m.I,m.RP, rule = R16_rule)
''' En el caso de rutas secundarias, los vehículos no pueden salir del nodo origen hasta que ha llegado el vehículo que deposita el producto. En cuanto al resto de nodos, pueden salir de los mismos tras hacer las rutas de carga/descarga '''
def R17_rule(m,i,k):
if i == m.o[k]:
return sum(m.HE[i,kaux] for kaux in m.K if kaux != k) + m.ts - m.M + m.Y[i,k] * m.M <= m.HS[i,k]
else:
return m.HS[i,k] == m.HE[i,k] + m.Y[i,k] * m.ts
m.R17 = Constraint(m.I,m.RS, rule = R17_rule)
''' En cualquier ruta, la hora de entrada en un nodo que no es el origen debe suceder antes de la hora límite establecida para ese nodo '''
#def R18_rule(m,i,k):
# if i != m.o[k]:
# return m.HE[i,k] <= m.Y[i,k] * m.hm[i]
# else:
# return Constraint.Skip
#m.R18 = Constraint(m.I,m.K, rule = R18_rule)
''' La hora de entrada a un nodo depende de la hora en que se salió del nodo anterior '''
''' Con esta primera restricción, cuando sí se hace una ruta, se asegura que la hora de entrada al nodo sea mayor o igual a la hora de salida del nodo anterior más el tiempo de transporte'''
def R19a_rule(m,i,j,k):
return m.HS[i,k] + m.t[i,j] * m.YS[i,j,k] - m.M + m.YS[i,j,k] * m.M <= m.HE[j,k]
m.R19a = Constraint(m.IJ,m.K, rule = R19a_rule)
''' Con esta segunda restricción, cuando sí se hace una ruta, se asegura que la hora de entrada al nodo sea menor o igual a la hora de salida del nodo anterior más el tiempo de transporte. Tener en cuenta ambas restricciones hace que actúe como un =, y la hora de entrada a un nodo sea igual a la hora de salida del nodo anterior más el tiempo de transporte '''
#def R19b_rule(m,i,j,k):
# return m.HS[i,k] + m.t[i,j] + m.M - m.YS[i,j,k] * m.M >= m.HE[j,k]
#m.R19b = Constraint(m.IJ,m.K, rule = R19b_rule)
''' Un vehículo solo puede tener hora de entrada y salida en un nodo si lo visita '''
def R20_rule(m,i,k):
return m.HE[i,k] + m.HS[i,k] <= 2 * m.M * m.Y[i,k]
m.R20 = Constraint(m.I,m.K, rule = R20_rule)
''' MUY IMPORTANTE. Para que la restricción R17 funcione correctamente, solo pueden visitar cada nodo dos vehículos, siempre y cuando ese nodo no sea el taller ( i = 0 ). Esto hay que ponerlo en el word como una hipótesis al problema'''
def R21_rule(m,i):
if i >= 1:
return sum(m.Y[i,k] for k in m.K) <= 2
else:
return Constraint.Skip
m.R21 = Constraint(m.I, rule = R21_rule)
#DATA LOAD
dp= DataPortal()
dp.load(filename= 'index_i.tab', set=m.I)
dp.load(filename= 'index_k.tab', set=m.K)
dp.load(filename= 'indexSparse_IJ.tab', set=m.IJ)
dp.load(filename= 'indexSparse_RP.tab', set=m.RP)
dp.load(filename= 'indexSparse_RS.tab', set=m.RS)
dp.load(filename= 'param_cap.tab', param=m.cap, index=m.K)
dp.load(filename= 'param_cf.tab', param=m.cf, index=m.K)
dp.load(filename= 'param_cv.tab', param=m.cv, index=m.K)
dp.load(filename= 'param_dem.tab', param=m.dem, index=m.I)
dp.load(filename= 'param_dis.tab', param=m.dis, index=m.IJ)
dp.load(filename= 'param_t.tab', param=m.t, index=m.IJ)
dp.load(filename= 'param_hi.tab', param=m.hi)
dp.load(filename= 'param_hm.tab', param=m.hm, index=m.I)
dp.load(filename= 'param_o.tab', param=m.o, index=m.K)
dp.load(filename= 'param_p.tab', param=m.p)
dp.load(filename= 'param_ts.tab', param=m.ts)
dp.load(filename= 'param_M.tab', param=m.M)
dp.load(filename= 'param_vmax.tab', param=m.vmax)
#OPTIMIZE AND PRINT RESULTS
inst = m.create_instance(dp)
#inst.pprint()
opt = SolverFactory('gurobi')
results = opt.solve(inst, tee=True)
#opt.options['MIPFocus'] = 1
#opt.options['Method'] = 3
opt.options['TimeLimit'] = 1000
inst.solutions.store_to(results)
print(results)
pu.save_results_to_file(inst, results)
0
-
You need to set the parameter before the solve call, i.e., before the line
results = opt.solve(inst, tee=True)0
サインインしてコメントを残してください。
コメント
1件のコメント