Camilo Merino
Base abierta de ingeniería
Tópicos de Optimización

Unidad 4 · Problemas clásicos · vendedor viajero, ruteo, corte, cobertura y localización

Descargar PDFVerificadores

Qué vas a poder hacer. Reconocer, bajo el vocabulario de un enunciado, cuál de los problemas clásicos tienes delante; formular el vendedor viajero con la eliminación de subtours MTZ y explicar por qué funciona; escribir un ruteo con capacidad, un corte por patrones, una cobertura, un empaquetamiento, una partición y una localización con costo fijo; correrlos en OPL y leer qué tan buena es su relajación lineal.

Lo que necesitas antes. De la unidad 2, el problema de asignación (cada uno a exactamente uno) y la mochila. De la unidad 3, el costo fijo con una binaria de activación y la diferencia entre un acoplamiento agregado y uno desagregado. De la unidad 1, que la relajación lineal es una cota.

Tiempo. Unas 6 horas: 2,5 de lectura con OPL abierto y 3,5 de práctica.


1. La idea: reconocer la estructura

Una ruta de reparto, un turno de enfermería, un pedido de tablas cortadas y la ubicación de un desfibrilador parecen problemas distintos. Son media docena de estructuras que se repiten con otros nombres. Quien reconoce la estructura hereda su modelo, sus trampas conocidas y décadas de algoritmos; quien no la reconoce empieza de cero.

Estructura La pregunta La marca en el enunciado
Vendedor viajero ¿en qué orden visito todos los lugares una vez y vuelvo? «recorre», «visita cada uno», «vuelve al origen»
Ruteo de vehículos ¿qué vehículo atiende a quién, y en qué orden? varios vehículos con capacidad
Corte de piezas ¿cómo corto el material estándar para cubrir un pedido? barras, rollos o tablas de largo fijo
Cobertura ¿cuál es lo mínimo que deja a todos atendidos? «al menos uno», «que nadie quede sin»
Empaquetamiento ¿qué elijo sin que choquen? «sin traslape», «a lo más uno»
Partición ¿cómo reparto sin traslape ni omisión? «exactamente uno»
Localización con costo fijo ¿qué abro y quién se atiende desde dónde? costo de abrir más costo de servir

2. El vendedor viajero

Un vehículo sale de una base, visita \(n - 1\) lugares una sola vez y vuelve. Se busca el recorrido más corto. Con \(N = \{1, \dots, n\}\) los lugares (el 1 es la base) y \(d_{ij}\) la distancia de \(i\) a \(j\):

El modelo empieza como una asignación. De cada lugar se sale una vez y a cada lugar se entra una vez:

\[\min \sum_{i \in N} \sum_{j \in N,\, j \ne i} d_{ij}\, x_{ij} \quad \text{s.a.} \quad \sum_{j \ne i} x_{ij} = 1 \;\; \forall i \in N, \qquad \sum_{i \ne j} x_{ij} = 1 \;\; \forall j \in N\]

Y la asignación no basta. Toda ruta cumple esas restricciones, pero no al revés: la asignación acepta varios circuitos cerrados que no se tocan, los subtours. En el ejemplo de la sección 8, la asignación «visita» los seis lugares con tres idas y vueltas de a dos, y ninguna pasa por todos.

Eliminar subtours: dos formas.

MTZ, con sus piezas.

\[u_i - u_j + 1 \le (n - 1)(1 - x_{ij}) \qquad \forall i, j \in N \setminus \{1\},\; i \ne j\]

\[2 \le u_i \le n \quad \forall i \in N \setminus \{1\}, \qquad u_1 = 1, \qquad x_{ij} \in \{0,1\} \;\; \forall i \ne j\]

La intuición. Si la ruta va de \(i\) a \(j\) (\(x_{ij} = 1\)), la restricción queda \(u_j \ge u_i + 1\): \(j\) va al menos una posición después de \(i\). Ahora piensa en un subtour que no pasa por la base, por ejemplo \(2 \to 4 \to 5 \to 2\). Pediría \(u_4 \ge u_2 + 1\), \(u_5 \ge u_4 + 1\) y \(u_2 \ge u_5 + 1\): sumadas, \(0 \ge 3\). Imposible. Un ciclo de posiciones que siempre crecen no puede cerrarse, salvo pasando por la base, que está excluida de esas restricciones. Por eso queda una sola ruta, la que sale y vuelve a la base. Si \(x_{ij} = 0\), el lado derecho vale \(n - 1\) y la restricción no corta: la mayor diferencia posible, \(u_i = n\) y \(u_j = 2\), da justo \(n - 2 + 1 = n - 1\). Es una gran M ajustada, de la unidad 3.

El precio de MTZ. Tiene \((n-1)(n-2)\) restricciones en vez de \(2^n\), pero su relajación lineal es débil: con \(x\) fraccionarios, las \(u\) casi no estorban. Sirve bien para problemas chicos como los de esta unidad; para cientos de lugares se usan cortes DFJ o las heurísticas de la unidad 11.

Distancias de un mapa que no es completo. Si entre dos tiendas no hay camino directo, \(d_{ij}\) es el largo de la ruta más corta entre ellas por los caminos que existen (la unidad 8 enseña a calcularla con Dijkstra). La ruta del vendedor viajero dice el orden de las visitas; entre dos visitas el vehículo puede pasar por lugares que no visita, como un cruce.


3. Ruteo de vehículos (mención y modelo chico)

Con varios vehículos de capacidad \(Q\) y lugares que piden \(q_i\), el problema pasa a ser de ruteo de vehículos con capacidad: cada lugar lo atiende exactamente un vehículo, cada vehículo sale y vuelve a la base, y ninguno lleva más de \(Q\). El modelo cambia en tres cosas respecto del vendedor viajero:

\[u_j \ge u_i + q_j - Q\,(1 - x_{ij}) \qquad \forall i \in N,\; j \in N \setminus \{1\},\; i \ne j; \qquad q_i \le u_i \le Q\]

La misma desigualdad hace dos trabajos: elimina subtours (la carga crece a lo largo de un ciclo) y respeta la capacidad (nunca pasa de \(Q\)). Las variantes reales agregan ventanas de horario, flota distinta o varias bases; con cientos de clientes se resuelven con heurísticas.


4. Corte de piezas por patrones

Una maestranza compra barras de largo fijo y las corta en piezas pedidas. Un patrón es una forma de cortar una barra: cuántas piezas de cada tipo salen de ella. Lo que sobra es merma.

\[\min \sum_{p \in P} x_p \quad \text{s.a.} \quad \sum_{p \in P} a_{pi}\, x_p \ge D_i \;\; \forall i \in I, \qquad x_p \in \mathbb{Z}_0^+ \;\; \forall p \in P\]

Minimizar barras es minimizar desperdicio. Con barras de largo \(\ell\), lo desperdiciado es \(\ell \sum_p x_p - \sum_i \ell_i D_i\): el material pedido es fijo, así que bajar las barras baja el desperdicio (merma de los patrones más piezas cortadas de más). La restricción es de cobertura (\(\ge\)): exigir \(=\) suele volver infactible el pedido. Con muchos largos los patrones son millones; se generan solo los que convienen (generación de columnas), y el problema que decide el patrón nuevo es una mochila, la de la unidad 2.


5. Cobertura, empaquetamiento y partición

Una matriz de incidencia \(a_{ij} = 1\) si el candidato \(j\) atiende al elemento \(i\). Con \(J_i\) el conjunto de candidatos que atienden a \(i\) y \(x_j = 1\) si se elige el candidato \(j\); 0 en otro caso, \(\forall j \in J\), las tres estructuras cambian solo el signo:

Restricción, \(\forall i \in I\) Objetivo típico Ejemplo
Cobertura \(\sum_{j \in J_i} x_j \ge 1\) mínimo costo o cantidad desfibriladores, estaciones de bomberos
Empaquetamiento \(\sum_{j \in J_i} x_j \le 1\) máximo valor reservas de salas sin choques
Partición \(\sum_{j \in J_i} x_j = 1\) mínimo costo tripulaciones, turnos exactos

La asignación es una partición; la mochila es pariente del empaquetamiento. Escribir la suma sobre \(J_i\) y no sobre todos los \(j\) con su \(a_{ij}\) es lo mismo, pero no multiplica por ceros.

Cobertura máxima. Si el presupuesto no alcanza para cubrir todo, se maximiza lo cubierto. Aparece una variable de consecuencia: \(z_i = 1\) si el elemento \(i\) queda cubierto; 0 en otro caso. Con \(w_i\) la población de \(i\):

\[\max \sum_{i \in I} w_i\, z_i \quad \text{s.a.} \quad z_i \le \sum_{j \in J_i} x_j \;\; \forall i \in I, \qquad \sum_{j \in J} c_j\, x_j \le B\]

\(x_j\) decide dónde instalar; \(z_i\) registra quién quedó cubierto. El acoplamiento impide declarar cubierto a quien no lo está, y como el objetivo premia \(z_i\), el modelo la pone en 1 cada vez que puede.


6. Localización de instalaciones con costo fijo

Qué bodegas abrir (cada una con costo fijo \(f_i\)) y desde cuál atender a cada cliente \(j\) (demanda \(d_j\), costo por unidad \(c_{ij}\)). Es el costo fijo de la unidad 3 multiplicado por una asignación.

\[\min \sum_{i \in I} f_i\, y_i + \sum_{i \in I} \sum_{j \in J} c_{ij}\, d_j\, x_{ij} \quad \text{s.a.} \quad \sum_{i \in I} x_{ij} = 1 \;\; \forall j \in J, \qquad x_{ij} \le y_i \;\; \forall i \in I, j \in J\]

Agregada o desagregada. El acoplamiento \(\sum_j x_{ij} \le |J|\, y_i\) \(\forall i\) es correcto y tiene menos restricciones, pero en la relajación lineal deja abrir «un quinto» de bodega y atender igual a un cliente completo. El desagregado \(x_{ij} \le y_i\) obliga a abrir al menos tanto como se usa para cada cliente: su relajación queda casi pegada al óptimo entero (ejercicio 4.7).

Con capacidad. Si la bodega \(i\) despacha a lo más \(K_i\): \(\sum_j d_j\, x_{ij} \le K_i\, y_i\) \(\forall i\). Si además cada cliente debe atenderse desde una sola bodega, \(x_{ij}\) pasa a ser binaria (ejercicio 4.10).


7. Cuándo NO aplica


8. Ejemplo resuelto · El técnico de ascensores

Un técnico sale de la base de su empresa y tiene que revisar los ascensores de cinco edificios (una torre de oficinas, un edificio en la plaza, un liceo, un hotel y un mall) y volver. Las distancias en km por la ciudad:

Base Torre Plaza Liceo Hotel Mall
Base — 3 7 8 6 5
Torre 3 — 5 7 8 6
Plaza 7 5 — 2 6 8
Liceo 8 7 2 — 5 7
Hotel 6 8 6 5 — 2
Mall 5 6 8 7 2 —

Paso 1 · En palabras. Se decide en qué orden visitar los cinco edificios, saliendo de la base y volviendo a ella. Se busca el menor recorrido. Cada edificio se visita una vez, y la ruta tiene que ser una sola.

Paso 2 · Solo la asignación. Si se resuelve únicamente «salir una vez, entrar una vez», el óptimo mide 14 km y es esto:

Tres subtours de ida y vuelta: cada edificio con su vecino más cercano. Cumple todas las restricciones de la asignación y no es una ruta. Esos 14 km son una cota inferior del recorrido real.

A la izquierda, la solución de la asignación: tres subtours que suman 14 km. A la derecha, la ruta que deja MTZ: 22 km.

Paso 3 · El modelo completo en OPL (modelos/u04_tsp.mod). El mismo .mod sirve para el caso integrador de la sección 12; solo cambia el .dat.

/*********************************************
 * Unidad 4 · Vendedor viajero con eliminación de subtours MTZ
 * Un modelo para dos juegos de datos: u04_ascensores.dat (ejemplo resuelto)
 * y u04_ruta_camion.dat (caso integrador). Base abierta de ingeniería.
 *********************************************/

{string} Lugares = ...;              // la base y los lugares que hay que visitar
string   base    = ...;              // desde donde sale y adonde vuelve la ruta
float    d[Lugares][Lugares] = ...;  // km entre cada par de lugares

int n = card(Lugares);

dvar boolean x[Lugares][Lugares];    // 1 si la ruta va de i directo a j; 0 en otro caso
dvar float+  u[Lugares];             // posición del lugar en la ruta (la base es la 1)

dexpr float Km = sum(i in Lugares, j in Lugares: i != j) d[i][j] * x[i][j];

minimize Km;

subject to {
  forall(i in Lugares)
    SinLazo:
      x[i][i] == 0;
  forall(i in Lugares)
    Sale:
      sum(j in Lugares: j != i) x[i][j] == 1;
  forall(j in Lugares)
    Entra:
      sum(i in Lugares: i != j) x[i][j] == 1;
  // MTZ: si la ruta va de i a j (ninguno es la base), j queda al menos una posición después de i
  forall(i in Lugares, j in Lugares: i != base && j != base && i != j)
    MTZ:
      u[i] - u[j] + 1 <= (n - 1) * (1 - x[i][j]);
  PosicionBase:
    u[base] == 1;
  forall(i in Lugares: i != base)
    Posicion:
      2 <= u[i] <= n;
}

execute {
  writeln("km = ", Km);
  var ruta = base;
  var actual = base;
  for (var paso = 1; paso <= n; paso++) {
    for (var j in Lugares)
      if (x[actual][j] > 0.5) { actual = j; break; }
    ruta = ruta + "-" + actual;
  }
  writeln("ruta = ", ruta);
  for (var i in Lugares)
    writeln("u[", i, "] = ", u[i]);
}

El .dat (modelos/u04_ascensores.dat):

// Unidad 4 · ejemplo resuelto · visita del técnico de ascensores (km)

Lugares = {"Base", "Torre", "Plaza", "Liceo", "Hotel", "Mall"};
base    = "Base";

d = [
  [0 3 7 8 6 5]     // Base
  [3 0 5 7 8 6]     // Torre
  [7 5 0 2 6 8]     // Plaza
  [8 7 2 0 5 7]     // Liceo
  [6 8 6 5 0 2]     // Hotel
  [5 6 8 7 2 0]     // Mall
];

Paso 4 · La salida. OPL entrega km = 22 y la ruta Base, Mall, Hotel, Liceo, Plaza, Torre, Base, con \(u\) = 1, 2, 3, 4, 5, 6 en ese orden. Una fuerza bruta sobre las \(5! = 120\) rutas lo confirma: hay una sola ruta óptima, que se puede recorrer en los dos sentidos.

Paso 5 · Cuánto ayudan las MTZ en la relajación. Con seis lugares hay 20 restricciones MTZ.

Modelo Valor Distancia al óptimo de 22 km
Asignación entera (sin MTZ) 14 km 36,4 %
Relajación lineal con MTZ 17,2 km 21,8 %
Vendedor viajero entero 22 km —

Cómo se lee.


9. Errores típicos

Error Cómo evitarlo
Escribir el vendedor viajero solo con «sale una vez, entra una vez» eso es una asignación: acepta subtours; agrega MTZ o cortes DFJ
Incluir la base en las restricciones MTZ MTZ va solo para \(i, j \ne\) base; si no, la ruta tampoco podría cerrarse en la base
Definir \(u_i\) sin decir qué es «posición del lugar \(i\) en la ruta», con su rango \(2 \le u_i \le n\) y \(u_{\text{base}} = 1\)
Usar distancias directas en un mapa incompleto usa la ruta más corta entre cada par; el camión puede pasar por lugares que no visita
Olvidar \(x_{ii} = 0\) sin eso, «salir de \(i\) hacia \(i\)» cumple la asignación con costo 0
En ruteo, poner la carga como posición \(u_i\) es carga acumulada: \(u_j \ge u_i + q_j - Q(1 - x_{ij})\), con \(q_i \le u_i \le Q\)
Enumerar patrones de corte que no son maximales basta con los maximales; los otros solo agrandan el modelo
Exigir \(=\) en la demanda del corte es \(\ge\): un patrón trae piezas de más; con \(=\) el pedido suele quedar infactible
Usar \(\ge 1\) cuando el enunciado prohíbe el traslape (o \(= 1\) cuando lo permite) pregúntate: ¿hay que cubrir todo? ¿se permite el traslape? Eso decide el signo
Cobertura máxima sin la variable de consecuencia \(z_i\) registra quién quedó cubierto y se acopla con \(z_i \le \sum_{j \in J_i} x_j\)
Localización con el acoplamiento agregado «porque son menos restricciones» el desagregado \(x_{ij} \le y_i\) da una relajación mucho más ajustada
Escribir una familia sin su \(\forall\) o una variable sin su naturaleza cada restricción con su «para todo»; al final, \(x \in \{0,1\}\), \(u \ge 0\), con sus índices

10. Práctica

Diez ejercicios: 4.1 a 4.4 básicos, 4.5 a 4.8 intermedios, 4.9 y 4.10 de desafío. Las pautas están en la sección 11. Cada variable con sus tres piezas, cada restricción con su \(\forall\) y la naturaleza al final.

4.1 · ¿Qué estructura es? (básico). Di qué estructura clásica es cada caso y con qué signo o restricción característica se escribe. (a) Un hospital elige qué turnos de 12 horas contratar para que cada hora del día tenga al menos una matrona. (b) Un auditor visita las siete sucursales de un banco en un día y vuelve a la oficina. (c) Una imprenta corta pliegos de papel de 100 cm en etiquetas de tres anchos. (d) Un municipio asigna cada feria libre a exactamente un fiscalizador. (e) Un centro cultural acepta reservas de salas, cada una pidiendo varios bloques horarios, sin que dos reservas choquen. (f) Una cadena de farmacias decide qué bodegas abrir y desde cuál surtir cada local.

4.2 · Desfibriladores (básico). Una comuna evalúa siete sitios para instalar desfibriladores públicos. Un sitio cubre a las juntas de vecinos que quedan a menos de tres minutos a pie:

Sitio S1 S2 S3 S4 S5 S6 S7
Cubre a las juntas 1, 2, 4 2, 3, 5 1, 4, 7 3, 5, 6, 9 4, 7, 8 6, 8, 9 2, 5, 6
Costo (miles de pesos) 410 390 350 820 340 560 310

(a) Escribe los conjuntos \(J_i\) y el modelo de mínimo número de sitios. (b) Resuélvelo. (c) Ahora con costos: ¿cambia la solución? (d) Las juntas tienen 640, 410, 980, 520, 730, 870, 470, 590 y 690 vecinos (J1 a J9). Si el presupuesto es de $910.000, formula y resuelve la cobertura máxima de vecinos.

4.3 · Por qué MTZ corta los subtours (básico). Con cinco lugares (el 1 es la base) y \(n = 5\): (a) la asignación da \(1 \to 3 \to 1\) y \(2 \to 4 \to 5 \to 2\). Escribe las tres restricciones MTZ del segundo ciclo y muestra que juntas son imposibles. (b) Para la ruta \(1 \to 3 \to 2 \to 5 \to 4 \to 1\), calcula las posiciones \(u_i\) y verifica las restricciones MTZ de los arcos no usados \((4,2)\) y \((5,3)\). (c) ¿Por qué el lado derecho es \(n - 1\) y no un número cualquiera?

4.4 · Los patrones de una tabla (básico). Una mueblería corta tablas de 320 cm en piezas de 110 cm (A), 80 cm (B) y 50 cm (C). (a) Enumera los patrones maximales con su merma. (b) ¿Por qué basta con los maximales? (c) ¿Cuántos patrones habría contando también los no maximales?

4.5 · Los turnos de una clínica veterinaria (intermedio). Una clínica de urgencias divide el día en seis franjas de 4 horas (F1 a F6) y tiene siete turnos posibles:

Turno T1 T2 T3 T4 T5 T6 T7
Franjas F1, F2 F2, F3 F3, F4 F4, F5 F5, F6 F6, F1 F3, F4, F5
Costo diario $95.000 $82.000 $71.000 $76.000 $91.000 $108.000 $66.000
Veterinarios que lo prefieren 4 6 3 5 2 3 8

(a) Cobertura: cada franja con al menos un turno, al menor costo. (b) Partición: cada franja con exactamente un turno, al menor costo. ¿Cuánto cuesta la exactitud? (c) Empaquetamiento: sin cubrir todo, elegir turnos que no se traslapen y maximicen las preferencias. Formula los tres y resuélvelos.

4.6 · El pedido de la mueblería (intermedio). Con los patrones de 4.4, la mueblería necesita 40 piezas A, 65 piezas B y 90 piezas C. (a) Formula el modelo y resuélvelo (modelos/u04_e06_corte.mod). (b) ¿Cuántos centímetros se desperdician? Separa la merma de los patrones de las piezas cortadas de más. (c) ¿Cuál es la cota de «material pedido dividido por el largo de la tabla»? ¿Y la relajación lineal? ¿Qué dicen?

4.7 · Tres bodegas candidatas (intermedio). Una distribuidora evalúa bodegas en Norte, Río y Sur para atender a cinco clientes (modelos/u04_e07_bodegas.mod).

CLP por caja C1 C2 C3 C4 C5 Costo fijo mensual
Norte 1.800 2.600 4.150 3.350 5.200 $430.000
Río 3.400 1.900 2.300 4.550 3.100 $380.000
Sur 4.950 3.800 2.700 2.100 1.650 $410.000
Cajas al mes 120 85 145 65 105

(a) Formula la localización con el acoplamiento desagregado y resuélvela. (b) ¿Cuánto costaría operar con cada bodega sola? (c) Calcula la relajación lineal con el acoplamiento agregado (\(\sum_j x_{ij} \le 5\,y_i\)) y con el desagregado, y el gap de cada una.

4.8 · El caso sin MTZ (intermedio). Toma el .dat del caso integrador (sección 12). (a) Borra las restricciones MTZ y resuelve: ¿qué devuelve el modelo y cuánto mide? (b) ¿Por qué el resultado es una cota inferior de la ruta del camión? (c) Resuelve la relajación lineal del modelo completo con MTZ y compara las dos cotas con los 78 km.

4.9 · Dos camionetas (desafío). Estampa Sur evalúa reemplazar el camión por dos camionetas de 80 cajas. Las tiendas piden: Centro 31, Puerto 24, Lagos 19, Valle 36, Costa 14 y Cerro 22 cajas. Con las distancias del caso: (a) formula el ruteo con capacidad usando la carga acumulada; (b) resuélvelo (modelos/u04_e09_camionetas.mod); (c) ¿cuántos km más que el camión recorren entre las dos? (d) ¿Por qué ya no sirve una sola camioneta?

4.10 · Bodegas con capacidad (desafío). Retoma 4.7. Ahora cada bodega despacha como máximo 290 (Norte), 260 (Río) y 270 (Sur) cajas al mes, y cada cliente se atiende desde una sola bodega (modelos/u04_e10_capacidad.mod). (a) Formula y resuelve. (b) ¿Cuánto cuesta la regla de una sola bodega por cliente? Resuelve también permitiendo repartir clientes. (c) ¿Por qué ya no basta la bodega que ganó en 4.7?


11. Pautas

4.1. (a) Cobertura: cada hora \(\ge 1\) turno; el traslape se permite. (b) Vendedor viajero: asignación más eliminación de subtours. (c) Corte de piezas por patrones, con demanda \(\ge\). (d) Partición (es una asignación): cada feria \(= 1\) fiscalizador. (e) Empaquetamiento: cada bloque \(\le 1\) reserva elegida, maximizando lo aceptado. (f) Localización con costo fijo: \(y_i\) por bodega y \(x_{ij} \le y_i\). Lectura: el signo de la restricción sale de dos preguntas, ¿hay que atender a todos? y ¿se permite el traslape?

4.2. (a) \(J_1 = \{S1, S3\}\), \(J_2 = \{S1, S2, S7\}\), \(J_3 = \{S2, S4\}\), \(J_4 = \{S1, S3, S5\}\), \(J_5 = \{S2, S4, S7\}\), \(J_6 = \{S4, S6, S7\}\), \(J_7 = \{S3, S5\}\), \(J_8 = \{S5, S6\}\), \(J_9 = \{S4, S6\}\). Con \(x_j = 1\) si se instala en el sitio \(j\); 0 en otro caso, \(\forall j\): \(\min \sum_j x_j\) s.a. \(\sum_{j \in J_i} x_j \ge 1\) \(\forall i \in \{1, \dots, 9\}\); \(x_j \in \{0,1\}\) \(\forall j\). (b) Bastan 3 sitios, y hay dos formas: S1, S4, S5 o S2, S3, S6. El solver entrega S1, S4, S5. (c) Con costos, la más barata de las dos es S2, S3, S6, por $1.300.000; no hay cobertura más barata con más sitios. (d) Con \(z_i\) y el presupuesto, el óptimo instala en S3, S6, gasta $910.000 y cubre 3.780 de los 5.900 vecinos. Lectura: el mínimo número de sitios no decide entre empates; el costo sí, y el presupuesto obliga a dejar juntas sin cubrir.

4.3. (a) Para \(2 \to 4 \to 5 \to 2\), con \(x = 1\) en esos tres arcos: \(u_2 - u_4 + 1 \le 0\), \(u_4 - u_5 + 1 \le 0\), \(u_5 - u_2 + 1 \le 0\). Sumadas, las \(u\) se cancelan y queda \(3 \le 0\): imposible. (b) \(u_1 = 1\), \(u_3 = 2\), \(u_2 = 3\), \(u_5 = 4\), \(u_4 = 5\). Arco \((4,2)\), no usado: \(u_4 - u_2 + 1\) da \(3 \le 4\). Arco \((5,3)\): \(u_5 - u_3 + 1\) da \(3 \le 4\). (c) Porque \(n - 1\) es la mayor diferencia posible: con \(u_i = 5\) y \(u_j = 2\) el lado izquierdo vale 4. Es la gran M ajustada: más chica cortaría rutas válidas; más grande debilitaría la relajación.

4.4. (a) Los patrones maximales (piezas A, B, C, cm usados y merma):

A B C Usados (cm) Merma (cm)
2 1 0 300 20
2 0 2 320 0
1 2 1 320 0
1 1 2 290 30
1 0 4 310 10
0 4 0 320 0
0 3 1 290 30
0 2 3 310 10
0 1 4 280 40
0 0 6 300 20

Son 10 patrones maximales. (b) Si en la merma cabe otra pieza, cortarla nunca empeora: el patrón con la pieza extra cubre lo mismo y algo más. (c) Contando todos los que caben en la tabla (con al menos una pieza) son 32 patrones. Lectura: con tres largos se cuentan a mano; con veinte son millones, y por eso se generan solo los que convienen.

4.5. Con \(x_t = 1\) si se contrata el turno \(t\); 0 en otro caso, \(\forall t\), y \(T_f\) los turnos que cubren la franja \(f\). (a) \(\min \sum_t c_t x_t\) s.a. \(\sum_{t \in T_f} x_t \ge 1\) \(\forall f\): T1, T5, T7 por $252.000; la franja F5 queda con dos turnos. (b) Con \(= 1\): T1, T3, T5 por $257.000. La exactitud cuesta $5.000 al día: el turno largo y barato T7 se traslapa con T5 y la partición no lo deja. (c) \(\max \sum_t p_t x_t\) s.a. \(\sum_{t \in T_f} x_t \le 1\) \(\forall f\): T2, T4, T6, con 14 puntos de preferencia. T7, el más preferido, choca con T2 y T4 a la vez y deja menos. Lectura: misma matriz, tres signos, tres respuestas distintas.

4.6. (a) \(x_p\): tablas cortadas con el patrón \(p\), \(\forall p \in \{P1, \dots, P10\}\); \(\min \sum_p x_p\) s.a. \(\sum_p a_{pi} x_p \ge D_i\) \(\forall i \in \{A, B, C\}\); \(x_p \in \mathbb{Z}_0^+\). Se necesitan 45 tablas. Una solución óptima (hay otras con 45): 28 tablas con el patrón (1, 2, 1), 12 con (1, 0, 4) y 5 con (0, 2, 3). (b) Se compran \(45 \cdot 320 = 14{.}400\) cm y el pedido usa 14.100 cm: se desperdician 300 cm. En esa solución, 170 cm son merma de los patrones y 130 cm son una pieza B y una C cortadas de más; otra solución óptima puede repartirlos distinto, pero el total es el mismo. (c) La cota de material es \(14{.}100/320 = 44{,}06\) tablas y la relajación lineal da 44,58: las dos dicen que hacen falta al menos 45. Lectura: el óptimo alcanza la cota redondeada hacia arriba; no hay forma de cortar mejor.

4.7. (a) Con \(y_i\) y \(x_{ij}\) de la sección 6, el óptimo abre solo Río: $380.000 de costo fijo y $1.524.250 de despacho, total $1.904.250. (b) Solo Norte: $2.232.500; solo Río: $1.904.250; solo Sur: $2.028.250. Abrir una segunda bodega ahorra despacho, pero no tanto como su costo fijo. (c) La relajación desagregada da $1.902.250 (gap 0,1 %); la agregada, $1.422.750 (gap 25,3 %). La agregada abre «un quinto» de Norte (\(y = 0{,}2\)) y aun así puede despachar desde ahí un cliente completo, pagando un quinto del costo fijo. Lectura: las mismas soluciones enteras; una cota casi exacta contra una que queda un cuarto bajo el óptimo.

4.8. (a) Sin MTZ el modelo devuelve 64 km en tres subtours: Taller → Centro → Taller, Puerto → Costa → Puerto y Lagos → Valle → Cerro → Lagos. (b) Toda ruta es una asignación, así que la mejor asignación no puede medir más que la mejor ruta: 64 km es una cota inferior. (c) La relajación lineal con MTZ da 65,33 km. Las dos cotas quedan lejos de los 78 km: 17,9 % y 16,2 % bajo el óptimo. Lectura: las MTZ casi no mejoran la cota lineal; lo que hacen es prohibir, en el modelo entero, las soluciones con subtours.

4.9. (a) Con \(q_j\) los pedidos, \(Q = 80\) y \(K = 2\): \(x_{ij} = 1\) si una camioneta va de \(i\) directo a \(j\); 0 en otro caso; \(u_i\): cajas entregadas por esa camioneta hasta \(i\), inclusive. \(\min \sum d_{ij} x_{ij}\) s.a. a cada tienda se entra una vez y se sale una vez \(\forall\) tienda; \(\sum_j x_{\text{Taller},j} \le 2\) y vuelven las mismas que salen; \(u_j \ge u_i + q_j - 80(1 - x_{ij})\) \(\forall i, \forall j \ne \text{Taller}\), \(i \ne j\); \(q_i \le u_i \le 80\); \(u_{\text{Taller}} = 0\). (b) Una camioneta hace Taller, Centro, Puerto, Costa (40 km, 69 cajas) y la otra Taller, Lagos, Valle, Cerro (61 km, 77 cajas): 101 km. (c) Son 23 km más que la ruta del camión. (d) Las tiendas piden 146 cajas: una camioneta de 80 no alcanza. Lectura: la capacidad parte la ruta en dos, y cada vuelta extra a la base cuesta kilómetros.

4.10. (a) Con \(x_{ij} \in \{0,1\}\) y \(\sum_j d_j x_{ij} \le K_i y_i\) \(\forall i\): se abren Norte y Sur, con Norte: 270 cajas (C1, C2 y C4) y Sur: 250 cajas (C3 y C5); costo $2.059.500. (b) Permitiendo repartir clientes, $2.034.500: la regla de una sola bodega cuesta $25.000 al mes. (c) Los clientes piden 520 cajas y Río despacha a lo más 260: ninguna bodega sola alcanza, y la mejor pareja ya no incluye a Río. Lectura: la capacidad cambia qué se abre, no solo cuánto se despacha.


12. Caso integrador · La ruta del camión de Estampa Sur

Estampa Sur es el taller ficticio que sigue todo el ramo. En la unidad 3 decidió comprar una segunda máquina y hacer 136 cajas más. Ahora esas cajas hay que llevarlas: un camión sale del taller, visita las seis tiendas una vez y vuelve.

La red. Las tiendas y los caminos son ficticios. Cruce es un empalme de caminos, no una tienda: el camión puede pasar por él, pero no lo visita.

La red de caminos del caso, con los km de cada tramo. En naranjo, los tramos que recorre la ruta óptima; los números dentro de cada tienda son el orden de visita.

Las distancias que usa el modelo. Como no todas las tiendas tienen camino directo, la matriz es la de ruta más corta por los caminos (km). La calcula el script del caso; la unidad 8 enseña a hacerlo a mano con Dijkstra.

Taller Centro Puerto Lagos Valle Costa Cerro
Taller — 7 16 21 20 16 23
Centro 7 — 9 14 15 17 18
Puerto 16 9 — 12 22 8 27
Lagos 21 14 12 — 10 20 17
Valle 20 15 22 10 — 30 7
Costa 16 17 8 20 30 — 23
Cerro 23 18 27 17 7 23 —

El modelo es el mismo u04_tsp.mod de la sección 8. Solo cambia el .dat (modelos/u04_ruta_camion.dat):

// Unidad 4 · caso integrador · el camión de Estampa Sur y las seis tiendas
// km de ruta más corta por los caminos (sale de verificacion/caso_estampa_sur_red.py)

Lugares = {"Taller", "Centro", "Puerto", "Lagos", "Valle", "Costa", "Cerro"};
base    = "Taller";

d = [
  [ 0  7 16 21 20 16 23]     // Taller
  [ 7  0  9 14 15 17 18]     // Centro
  [16  9  0 12 22  8 27]     // Puerto
  [21 14 12  0 10 20 17]     // Lagos
  [20 15 22 10  0 30  7]     // Valle
  [16 17  8 20 30  0 23]     // Costa
  [23 18 27 17  7 23  0]     // Cerro
];

La corrida. OPL da km = 78 y la ruta Taller, Costa, Puerto, Lagos, Valle, Cerro, Centro, Taller. El script del caso la reporta en el otro sentido: Taller, Centro, Cerro, Valle, Lagos, Puerto, Costa, Taller. Es la misma ruta: con distancias simétricas, recorrerla al revés mide lo mismo. La fuerza bruta sobre las 720 rutas confirma que no hay otra de 78 km.

La ruta, tramo por tramo (en el sentido del script del caso):

Tramo km Por dónde va
Taller → Centro 7 directo
Centro → Cerro 18 por Cruce (6 + 12)
Cerro → Valle 7 directo
Valle → Lagos 10 directo
Lagos → Puerto 12 directo
Puerto → Costa 8 directo
Costa → Taller 16 directo

Total: 78 km.

Lectura.

La cadena. El verificador resuelve la ruta en Python, por fuerza bruta y con OPL, y exige que km y recorrido sean los del script del caso (CADENA: OK).

Lo que pasa a las unidades siguientes. La misma red alimenta la unidad 7 (los enlaces de radio de menor largo que conectan tiendas y taller) y la unidad 8 (la ruta más corta a cada tienda, que es la que llenó esta matriz). La unidad 11 vuelve a esta ruta con una heurística: vecino más cercano y 2-opt se quedan en 84 km, contra los 78 km de este óptimo.


13. Para seguir

En los libros del ramo.

Abierto y gratis.

Con el tutor. La carpeta tutor/ trae el contexto del ramo. Pégalo al inicio de la conversación y pide, por ejemplo: «Dame una matriz de distancias de cinco lugares cuya asignación forme subtours y guíame para escribir las restricciones MTZ que los eliminan».