Está en la página 1de 4

PONTIFICIA UNIVERSIDAD CATÓLICA DE CHILE Curso: ICS1113-Optimización

ESCUELA DE INGENIERÍA Ayudante: Javiera Gebhardt


Departamento de Ingenierı́a Industrial y de Sistemas Mail: javieragr@uc.cl

Python - Gurobi
Parte 1. Estructura básica de un modelo en Python-Gurobi
from gurobipy import GRB, Model
from gurobipy import quicksum #para las sumatorias

#----------------------- Generacion del modelo ------------------------

model = Model()
model.setParam("TimeLimit", 60) #Establece el tiempo máximo en segundos

#---------------- Se instancian variables de decision -----------------

# vtype : tipo de variable


# Variables binarias: vtype = GRB.BINARY
# Variables continuas: vtype = GRB.CONTINUOUS
# Variables enteras: vtype = GRB.INTEGER

# Para definir solamente a UNA variable:


x = model.addVar(vtype = GRB.INTEGER, name = "x")
#Para definir un conjunto de variables que dependen del conjunto T:
y = model.addVars(T, vtype = GRB.CONTINUOUS, name = "y")

#------------------ Agregar las variables al modelo -------------------

model.update()

#----------------------- Agregar Restricciones ------------------------

# Para agregar solamente UNA restriccion:


model.addConstr(restriccion, name="R1")
#Para definir un conjunto de restricciones
model.addConstrs(conjunto_restricciones, name="R2")

#------------------------- Funcion Objetivo ---------------------------

model.setObjective(funcion_objetivo, GRB.MAXIMIZE) # o GRB.MINIMIZE


model.optimize()

#------------------------ Manejo Soluciones ---------------------------

# Tiempo ejecución:
tiempo_ejecucion = model.Runtime
# Valor objetivo:
valor_objetivo = model.ObjVal
# Solucion para una variable que no depende de conjuntos:
print(f"La variable x toma el valor de {x.x}")
# Solucion para variables que dependen de conjuntos:
for t in T:
print(f"Para t = {t} la variable y toma el valor de {y[t].x}")
# Mostrar los valores de todas las soluciones que no son cero
model.printAttr("X")

#----------------------------- Holguras -------------------------------


# Imprime las holguras de las restricciones
# (0 significa que la restricción es activa).
for constr in model.getConstrs():
print(constr, constr.getAttr("slack"))

#----------------------------- Variables Duales -------------------------------


# Imprime el valor de las variables duales por restricción:
for constr in model.getConstrs():
print(constr.pi)

Parte 2. Interpretando la salida de un modelo


Supongamos que se resuelve un problema en Gurobi que arroja el siguiente output:

1 Optimize a model with 784 rows, 272 columns and 2100 nonzeros
2 Model fingerprint: 0x7d7514fd
3 Variable types: 16 continuous, 256 integer (256 binary)
4 Coefficient statistics:
5 Matrix range [1e+00, 2e+01]
6 Objective range [5e+01, 3e+03]
7 Bounds range [1e+00, 1e+00]
8 RHS range [1e+00, 2e+01]
9 Found heuristic solution: objective 14755.000000
10 Presolve removed 542 rows and 17 columns
11 Presolve time: 0.01s
12 Presolved: 242 rows, 255 columns, 2228 nonzeros
13 Variable types: 15 continuous, 240 integer (240 binary)
14

15 Root relaxation: objective 5.669972e+03, 53 iterations, 0.00 seconds (0.00 work units)
16

17 Nodes | Current Node | Objective Bounds | Work


18 Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
19

20 0 0 5669.97241 0 25 14755.0000 5669.97241 61.6% - 0s


21 H 0 0 7390.0000000 5669.97241 23.3% - 0s
22 0 0 6113.00000 0 32 7390.00000 6113.00000 17.3% - 0s
23 0 0 6113.00000 0 32 7390.00000 6113.00000 17.3% - 0s
24 0 0 6113.00000 0 26 7390.00000 6113.00000 17.3% - 0s
25 0 0 6113.00000 0 26 7390.00000 6113.00000 17.3% - 0s
26 0 0 6113.00000 0 26 7390.00000 6113.00000 17.3% - 0s
27 H 0 0 7065.0000000 6113.00000 13.5% - 0s
28 0 0 6113.00000 0 26 7065.00000 6113.00000 13.5% - 0s
29 0 0 6113.00000 0 26 7065.00000 6113.00000 13.5% - 0s
30 0 0 6113.00000 0 26 7065.00000 6113.00000 13.5% - 0s
31 0 0 6113.00000 0 26 7065.00000 6113.00000 13.5% - 0s
32 0 0 6134.55682 0 29 7065.00000 6134.55682 13.2% - 0s
33 0 0 6134.55682 0 26 7065.00000 6134.55682 13.2% - 0s
34 0 0 6134.55682 0 26 7065.00000 6134.55682 13.2% - 0s
35 0 0 6134.55682 0 26 7065.00000 6134.55682 13.2% - 0s
36 0 0 6134.55682 0 26 7065.00000 6134.55682 13.2% - 0s
37 0 0 6134.55682 0 26 7065.00000 6134.55682 13.2% - 0s
38 0 0 6134.55682 0 26 7065.00000 6134.55682 13.2% - 0s
39 0 2 6205.00000 0 26 7065.00000 6205.00000 12.2% - 0s
40 H 82 58 7032.0000000 6208.00000 11.7% 5.0 0s
41 * 113 73 26 6926.0000000 6211.07143 10.3% 4.8 0s
42 * 173 109 26 6909.0000000 6221.00000 10.0% 4.7 0s
43 * 625 292 44 6875.0000000 6283.00000 8.61% 5.4 0s
44 * 4684 785 30 6859.0000000 6579.26190 4.08% 6.3 1s
45

46 Cutting planes:
47 Learned: 6
48 Gomory: 4
49 Cover: 5
50 Implied bound: 9
51 Projected implied bound: 1
52 MIR: 2
53 Flow cover: 59
54 Inf proof: 5
55 Relax-and-lift: 1
56

57 Explored 6549 nodes (43980 simplex iterations) in 2.13 seconds (1.35 work units)
58 Thread count was 1 (of 8 available processors)
59

60 Solution count 8: 6859 6875 6909 ... 14755


61

62 Optimal solution found (tolerance 1.00e-04)


63 Best objective 6.859000000000e+03, best bound 6.859000000000e+03, gap 0.0000%
64 Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (mac64[x86])

¿Qué significa cada cosa?

⋄ Fila 1: Se menciona que el modelo tiene 784 filas, 272 columnas y 2100 elementos no nulos.
⋄ Fila 3: Los tipos de variables en el modelo son 16 continuas y 256 enteras, de las cuales 256 son binarias.
⋄ Fila 10-13: Por defecto Gurobi hace un presolve primero. Su objetivo es realizar transformaciones en el
modelo original para simplificarlo y reducir su tamaño antes de ser resuelto por el algoritmo de Branch
and Bound.
⋄ Fila 15: La relajación inicial del modelo (root relaxation) resultó en un valor objetivo de 5.669972e+03
después de 53 iteraciones del algoritmo simplex. Esta relajación proporciona una estimación inicial del
valor óptimo del modelo.
⋄ Filas 17 a 44:
• La tabla proporciona información detallada sobre el progreso del algoritmo Branch and Bound
durante la resolución del problema, incluyendo información sobre nodos explorados, valores de
objetivo, lı́mites y mejor incumbente. Esta información es esencial para monitorear y evaluar el
rendimiento del algoritmo y comprender el proceso de búsqueda utilizado para encontrar la solución
óptima.
• La columna ”Nodes” indica el número de nodos explorados durante el proceso de búsqueda del
algoritmo Branch and Bound. En este caso, se exploraron un total de 6549 nodos.
• La columna ”Gap” indica el gap relativo entre el mejor incumbente y la mejor cota actual infe-
rior/superior para problemas de minimización/maximización. Mide la diferencia porcentual entre
estos dos valores y proporciona una indicación de cuánto se ha progresado en la búsqueda de la
solución óptima.
• La columna ”Incumbent” representa el valor del mejor incumbente o mejor solución encontrada
hasta el momento. A medida que el algoritmo encuentra soluciones mejores, este valor puede ir
mejorando. La ”H” que aparece en algunas filas, corresponde a la obtención de un mejor incumbente
vı́a una heurı́stica y ”*” lo es vı́a branching.
• La columna ”BestBd” muestra la mejor cota inferior/superior del valor objetivo en el nodo actual.
Se utiliza para realizar podas y reducir el espacio de búsqueda.

⋄ Fila 46 a la 55: ”Cutting planes” se refiere a los diferentes tipos de planos de corte utilizados durante
la resolución del modelo para mejorar la relajación lineal inicial y obtener soluciones enteras. Los tipos
de planos de corte incluyen Learned, Gomory, Cover, Implied bound, Projected implied bound, MIR
(Mixed Integer Rounding), Flow cover, Inf proof (proof of infeasibility), y Relax-and-lift.

⋄ Fila 57: ”Explored” indica el número de nodos explorados durante la búsqueda del árbol de ramificación
y acotamiento.

⋄ Fila 60: ”Solution count” muestra el número de soluciones encontradas durante el proceso de optimiza-
ción.

⋄ Fila 62: ”Optimal solution found” indica que se ha encontrado una solución óptima para el modelo.

⋄ Fila 63: ”Best objective” muestra el valor de la función objetivo en la mejor solución encontrada. ”Best
bound” es una cota inferior para la función objetivo en el modelo. Si la brecha (gap) es cero, significa
que la mejor solución encontrada es óptima.

También podría gustarte