Oscar Riveros — Obras Completas, Vol. I — 2026-08-25
Este catálogo describe una selección de problemas reales — con énfasis en logística y distribución, última milla, industria, mezclas y problemas atípicos — que pueden modelarse y resolverse con SATX, con especificaciones formales, detalles de codificación y guías de escala. Cada ficha indica el kernel recomendado:
| Kernel | Clase de problema | Salida |
|---|---|---|
| SLIME (CDCL) | Decisión SAT / UNSAT, testigo | modelo booleano |
| BASILISK | Conteo exacto de modelos (#SAT) | número exacto de soluciones |
| PIXIE | Programación lineal (LP) y mixta (MIP) | primal/dual continuo |
| WMIBO | Híbrido booleano-lineal con restricciones duras y blandas | óptimo + penalizaciones |
- ¿Solo importa si existe una solución? → SLIME (decisión), con
--symmetryactivo por defecto para romper simetrías de forma sonora. - ¿Cuántas soluciones hay exactamente? → BASILISK (
count,count_projectedpara marginales). - ¿Todo es continuo y lineal? → PIXIE (LP).
- ¿Hay enteros o binarios con costo/objetivo? → PIXIE (MIP) o WMIBO si además hay restricciones blandas ponderadas.
- ¿El problema es booleano pero con preferencias ponderadas? → WMIBO (cláusulas suaves + duras).
- ¿La estructura es no lineal (calidad de mezcla, trigonometría)? → discretizar con la aritmética de punto fijo de SATX (CBE) y resolver por SAT, o linealizar por tramos en WMIBO.
Regla de oro: todos estos problemas son NP-completos en su versión de optimización. Trabajar con instancias acotadas (ventanas temporales, horizonte corto, granularidad gruesa) y crecer iterativamente; usar
use_symmetry = 1, suposiciones para fijar decisiones de negocio y sesiones para refinar el mismo modelo.
- Kernel: PIXIE (MIP). Tipo: optimización de costo.
- Descripción: decidir qué almacenes abrir y qué clientes atiende cada uno, minimizando apertura + transporte.
-
Especificación:
- Datos: almacenes
$W$ , clientes$C$ , costo fijo$f_w$ , costo de servicio$c_{w,c}$ , demanda$d_c$ , capacidad$Q_w$ . - Variables:
$y_w\in{0,1}$ (abrir$w$ ),$x_{w,c}\in{0,1}$ (servir$c$ desde$w$ ), o continuas si se permite fraccionar. - Restricciones:
- cada cliente:
$\sum_w x_{w,c} = 1$ ; - capacidad:
$\sum_c d_c,x_{w,c} \le Q_w,y_w$ ; - acoplamiento:
$x_{w,c}\le y_w$ .
- cada cliente:
- Objetivo:
$\min \sum_w f_w y_w + \sum_{w,c} c_{w,c} d_c x_{w,c}$ .
- Datos: almacenes
- Codificación SATX:
#include <satx/satx.hpp>
satx::solver::pixie::model m;
for (auto& w : warehouses) m.add_binary("y_" + w); // 1 = abrir
for (auto& [w, c] : pairs) m.add_binary("x_" + w + "_" + c); // servir c desde w
for (auto& c : clients) {
satx::solver::pixie::expr e;
for (auto& w : warehouses) e += m.variable_at(idx(w, c)); // x_{w,c}
m.add_constraint(e, satx::solver::pixie::compare::eq, 1.0);
}
// capacidad: Σ_c d_c·x_{w,c} ≤ Q_w·y_w ; objetivo: min Σ f_w·y_w + Σ c·d·x
m.set_objective(/*expr de costo*/, satx::solver::pixie::sense::min);
auto sol = m.solve(); // valores por variable (sol.*(v)) y sol.objective()- Escala: cientos de almacenes × miles de clientes es rutinario en LP relajado; la versión entera con 50–200 binarias resuelve en segundos.
- Variantes: multi-producto, almacenes por niveles (central–regional), incertidumbre (escenarios con suposiciones).
- Kernel: WMIBO (MIP híbrido) para el óptimo; SLIME para factibilidad con horizonte fijo.
-
Especificación:
- Datos: depósito 0, clientes
$1..n$ con demanda$d_i$ , flota$K$ con capacidad$Q$ , distancias$t_{i,j}$ . - Variables:
$x_{i,j,k}\in{0,1}$ (el vehículo$k$ viaja$i\to j$ );$u_i\in[0,n]$ (orden de visita, MTZ). - Restricciones:
- grado:
$\sum_j x_{i,j,k}=\sum_j x_{j,i,k}=$ 1 si$i$ cliente,$k$ único; - eliminar subciclos (MTZ):
$u_i-u_j+1\le n(1-x_{i,j,k})$ ; - capacidad:
$\sum_{i\ne0} d_i\sum_j x_{i,j,k}\le Q$ ; - cada cliente atendido por un vehículo:
$\sum_{k,j}x_{i,j,k}=1$ .
- grado:
- Objetivo:
$\min\sum_{k,i,j}t_{i,j}x_{i,j,k}$ .
- Datos: depósito 0, clientes
- Codificación SATX (WMIBO):
satx::solver::wmibo::model m;
for (int k = 0; k < K; ++k)
for (auto& [i, j] : arcs)
m.add_boolean("x_" + std::to_string(i) + "_" + std::to_string(j) + "_" + std::to_string(k));
// capacidad por vehículo (restricción dura), usando referencias guardadas:
for (int k = 0; k < K; ++k) {
satx::solver::wmibo::expr cap;
for (auto& [i, j] : arcs) if (i != 0) cap += d[i] * m.variable_at(idx(i, j, k));
m.add_constraint(cap, satx::solver::wmibo::compare::le, Q);
}
m.set_objective(/* Σ t_ij · x_ijk */, satx::solver::wmibo::sense::min);- Escala: hasta ~50 clientes con MTZ; para más, codificación SAT pura con tiempos de visita (Time-indexed) o particionar por clúster (cluster-first, route-second: resolver 1.1 y luego CVRP por clúster).
- Variantes: ventanas de tiempo (1.4), flota heterogénea, retornos (backhauls), pick-up & delivery.
- Kernel: SLIME (decisión) con WMIBO si se optimiza volumen sobrante.
-
Especificación (2D guillotinable):
- Datos: paletas
$P$ , cajas con dimensiones$(w_i,h_i)$ , contenedor$W\times H$ . - Variables:
$x_{i,p}\in{0,1}$ (caja$i$ en paleta$p$ ); coordenadas discretizadas$cx_i, cy_i$ sobre la rejilla. - Restricciones:
- cada caja, una paleta: AMO sobre
${x_{i,p}}_p$ ; - no solapamiento: para cada par
$(i,j)$ en la misma paleta,$cx_i+w_i\le cx_j \lor cx_j+w_j\le cx_i \lor$ (análogo en$y$ ) — codificado con literales auxiliares; - límites:
$cx_i + w_i \le W$ ,$cy_i + h_i \le H$ (con aritmética CBE o cotas pre-codificadas).
- cada caja, una paleta: AMO sobre
- Datos: paletas
- Codificación SATX (esqueleto):
satx::engine e;
auto box_in = [&](int i, int p) { return e.add_variable(); }; // x_{i,p}
// exactamente-uno: cláusulas por pares (AMO) + al-menos-uno (ALO)
for (int i = 0; i < n; ++i) {
for (int p1 = 0; p1 < P; ++p1)
for (int p2 = p1 + 1; p2 < P; ++p2)
e.add_clause({satx::core::neg(box_in(i, p1)), satx::core::neg(box_in(i, p2))});
e.add_clause({/* ALO: todos los box_in(i,·) */});
}
// no solapamiento dentro de la paleta con variables de posición en rejilla...
auto sol = satx::solver::solve(e);- Escala: decenas de cajas por contenedor; la rejilla domina el tamaño (granularidad 1 cm → miles de literales; granularidad 5–10 cm → segundos).
- Variantes: 3D, orientación/rotación permitida, fragilidad, peso por eje (centro de gravedad), carga mixta camión–contenedor.
- Kernel: SLIME (time-indexed) o WMIBO.
-
Especificación:
- Datos: muelles
$D$ , camiones$T$ , ventanas de llegada$[a_t,b_t]$ , duración de descarga$p_t$ , incompatibilidades (refrigerado, peligroso). - Variables:
$x_{t,d,s}\in{0,1}$ (camión$t$ en muelle$d$ inicia en el instante$s$ ). - Restricciones:
- cada camión, una vez:
$\sum_{d,s}x_{t,d,s}=1$ (dentro de su ventana); - sin solapamiento por muelle:
$\sum_t\sum_{s'\in(s-p_t,s]}x_{t,d,s'}\le1$ para cada$(d,s)$ (cardinalidad ≤ 1); - incompatibilidad:
$\neg x_{t,d,s}\lor\neg x_{t',d,s'}$ si$(t,t')$ incompatibles y los intervalos se tocan.
- cada camión, una vez:
- Objetivo (WMIBO): minimizar
$\sum s\cdot x_{t,d,s}$ o el makespan con una variable entera auxiliar$z\ge s+p_t$ para cada asignación activa.
- Datos: muelles
-
Escala: 10 muelles × 50 camiones × horizonte 24 h (granularidad 15 min)
→ ~10⁵ literales; resuelve en segundos con
--symmetry. - Variantes: prioridades de cliente, cross-docking (transbordo entre camiones de larga distancia y reparto), recursos compartidos (bandas, montacargas).
- Kernel: SLIME / WMIBO.
- Descripción: emparejar llegadas y salidas de camiones para minimizar el tiempo de permanencia y las cargas movidas, respetando capacidades de puerta y compatibilidades de producto.
-
Variables:
$y_{i,j}$ (la carga de llegada$i$ alimenta la salida$j$ ),$s_i$ (instante de inicio en puerta). -
Restricciones: balance de flujo por producto, capacidad de puerta
(una operación a la vez), precedencia
$s_i+p_i\le s_j$ cuando$y_{i,j}=1$ y se exige secuencia (big-M en WMIBO). -
Objetivo: minimizar
$\sum(s_i+p_i)$ (tiempo total) o el número de puertas usadas. - Variantes: productos fríos (cadena de frío, precedencia estricta), consolidación multi-origen.
- Kernel: SLIME (decisión) / WMIBO (costo).
-
Especificación:
- Datos: pedidos con ventanas
$[e_i,l_i]$ , flota con capacidades y costos por km distintos, zonas restringidas. - Variables:
$x_{i,j,k}$ (arco por vehículo),$t_i$ (instante de llegada). - Restricciones:
- rutas por vehículo (grado) y capacidad;
- ventanas:
$e_i\le t_i\le l_i$ ; continuidad:$t_j\ge t_i+p_i+t_{i,j}-M(1-x_{i,j,k})$ ; - zona:
$x_{i,j,k}=0$ si$k$ no opera la zona de$j$ .
- Objetivo: minimizar costo total (distancia + vehículos usados); en WMIBO, cláusulas blandas penalizan entregas fuera de ventana.
- Datos: pedidos con ventanas
- Escala: 100–200 paradas por ruta en decisión pura; para el óptimo, resolver por zonas (1.1) y luego 2.1 por zona.
- Variantes: entregas fallidas y reintentos, depósitos móviles, ventanas acordadas con cliente (elección de franja → oferta comercial).
- Kernel: WMIBO.
- Descripción: agrupar pedidos de un almacén en oleadas de picking de modo que se minimice el recorrido total y se respeten los plazos.
-
Variables:
$y_{i,b}$ (pedido$i$ en oleada$b$ ); enteras$u_b$ (inicio de oleada). -
Restricciones: cada pedido en una oleada; capacidad de carro;
deadline:
$u_b + T_b \le l_i$ para pedidos urgentes (big-M). -
Objetivo: minimizar
$\sum_b f_b$ (costo de oleada, con cláusulas blandas por pedido tardío con peso por cliente). - Escala: miles de pedidos × decenas de oleadas; las cláusulas blandas permiten infactibilidades parciales negociadas (el cliente paga la prioridad).
- Kernel: SLIME / WMIBO.
- Descripción: asignar pedidos a casilleros (lockers) o tiendas de recogida minimizando la distancia peatonal del cliente y las colisiones de uso simultáneo.
-
Variables:
$x_{p,l}$ (pedido$p$ al casillero$l$ );$y_{p,t}$ (el pedido ocupa el casillero en el turno$t$ ). - Restricciones: un casillero por pedido y turno (AMO), capacidad por casillero, incompatibilidad de productos (frío/seco), reservas preexistentes (suposiciones fijas).
- Objetivo: minimizar la distancia total o el número de casilleros usados; #SAT (BASILISK) cuenta las configuraciones admisibles para dimensionar la red.
- Variantes: ubicación óptima de casilleros nuevos (combinar con 1.1: candidatos como "almacenes" sin costo fijo de apertura).
- Kernel: SLIME (decisión) / WMIBO (costo y blandas).
-
Especificación:
- Datos: servicios con duración, ventana y habilidad requerida
$h(s)\in H$ ; técnicos con habilidades, horarios y zonas. - Variables:
$x_{t,s}$ (técnico$t$ atiende servicio$s$ );$o_{s,s',t}$ (orden de atención);$u_s$ (instante de inicio). - Restricciones: cobertura
$\sum_t x_{t,s}=1$ ; habilidad$x_{t,s}=0$ si$h(s)\notin H_t$ ; sin solapamiento por técnico (intervalos disjuntos); ventanas; descansos y turnos legales (máximo de horas, pausa obligada).
- Datos: servicios con duración, ventana y habilidad requerida
- Objetivo: minimizar desplazamientos + horas extra; blandas: preferencia de técnico por zona, cliente preferente.
- Escala: 20 técnicos × 100 servicios por día en decisión; horizonte diario para acotar.
- Variantes: mantenimiento preventivo periódico (1.9 combinado), emergencias con prioridad (blandas de alto peso).
- Kernel: WMIBO / SLIME.
-
Descripción: un camión con
$k$ drones realiza entregas; los drones despegan y aterrizan en el camión solo en paradas. -
Variables:
$x_{i,j}$ (ruta del camión),$d_{l,i,j}$ (el dron$l$ va de la parada$i$ a la parada$j$ entregando el paquete$p$ ),$t_i$ (tiempo de llegada del camión). -
Restricciones: cada paquete entregado por camión o dron; autonomía
(batería → cota de distancia); sincronización: el dron sale y vuelve
solo cuando el camión está en la parada (
$t$ -indexado). - Objetivo: minimizar el makespan (tiempo total de ruta).
- Escala: 1 camión + 2–4 drones + 20–50 paquetes como referencia de complejidad; es fuertemente NP-completo — usar descomposición.
- Kernel: SLIME (time-indexed, decisión de makespan ≤ B) / WMIBO.
-
Especificación:
- Datos: trabajos
$J$ , máquinas$M$ , procesamientos$p_{j,m}$ , secuencia tecnológica (orden de máquinas por trabajo). - Variables:
$x_{j,m,t}$ (el trabajo$j$ se procesa en$m$ iniciando en$t$ ). - Restricciones:
- cada operación se ejecuta una vez:
$\sum_t x_{j,m,t}=1$ ; - capacidad por máquina:
$\sum_j\sum_{t'\in(t-p_{j,m},t]}x_{j,m,t'}\le1$ ; - precedencia tecnológica: la operación siguiente no inicia antes de
$t+p_{j,m}$ ; - makespan:
$t+p_{j,m}\le B$ para todo$(j,m,t)$ activo.
- cada operación se ejecuta una vez:
- Objetivo: minimizar
$B$ (búsqueda binaria sobre$B$ con SLIME, o variable entera en WMIBO).
- Datos: trabajos
-
Escala: 10 trabajos × 10 máquinas × horizonte 100 → ~10⁴ variables;
con
--symmetryse rompen máquinas idénticas. - Variantes: tiempos de preparación dependientes de la secuencia (changeover), recursos renovables (operarios), paradas de máquina (mantenimiento planificado como trabajos bloqueantes).
- Kernel: WMIBO.
- Descripción: planificar qué aleación se funde en cada horno y en qué orden, minimizando costos de cambio (limpieza de crisol) y atrasos.
-
Variables:
$y_{c,t}$ (aleación$c$ en el período$t$ ),$z_{c,c',t}$ (cambio de$c$ a$c'$ en$t$ ), inventario entero$I_{c,t}$ . -
Restricciones:
- un producto por horno y período;
- balance de inventario
$I_{c,t}=I_{c,t-1}+q_{c,t}-d_{c,t}$ ; - lote mínimo (si se produce,
$q_{c,t}\ge q^{\min}_c$ ); - cambio:
$z_{c,c',t}\ge y_{c,t-1}+y_{c',t}-1$ .
- Objetivo: minimizar $\sum c^{\text{cambio}}_{c,c'}z+\sum c^{\text{almacén}}c I{c,t}$ + blandas por atraso de pedido.
- Escala: 10 aleaciones × 30 períodos → MIP pequeño, segundos.
- Variantes: dos hornos paralelos (sincronización), tiempos de calentamiento dependientes del producto.
- Kernel: PIXIE (LP columna) o SLIME (patrones exactos).
- Descripción: cortar rollos o planchas estándar en piezas demandadas minimizando el desperdicio.
-
Variables (enumeración de patrones):
$x_p$ = número de planchas cortadas con el patrón$p$ (patrones generados con SLIME). -
Restricciones:
$\sum_p a_{i,p}x_p \ge d_i$ (demanda por pieza);$x_p\in\mathbb{Z}_{\ge0}$ . -
Objetivo: minimizar
$\sum_p x_p$ (o el área sobrante). - Escala: generación de patrones con SLIME (decisión "¿existe un patrón con estas piezas en una plancha?") + LP maestro con PIXIE; iteración de generación de columnas.
- Variantes: 2D no guillotinable (relacionado con 1.3), restos reaprovechables como inventario.
- Kernel: SLIME (time-indexed).
- Descripción: calendarizar tareas de mantenimiento con periodicidad máxima, precedencias y recursos (cuadrillas, repuestos).
-
Variables:
$x_{m,t}$ (mantenimiento de máquina$m$ inicia en$t$ );$r_{k,t}$ (recurso$k$ ocupado en$t$ ). -
Restricciones:
- periodicidad: entre dos tareas consecutivas de
$m$ ,$\Delta\le P_m$ (ventanas deslizantes:$\sum_{t'=t}^{t+P_m}x_{m,t'}\ge1$ ); - duración y recursos:
$\sum_{m,t'\in(t-p_m,t]}x_{m,t'}\le R_k$ ; - no interrumpir producción crítica (bloqueos declarados).
- periodicidad: entre dos tareas consecutivas de
- Objetivo: minimizar intervenciones (o maximizar disponibilidad con WMIBO y blandas).
- Escala: 50 máquinas × horizonte anual por semanas → factible; es el problema de mantenimiento con periodicidad (clásico).
- Kernel: SLIME (nativo).
- Descripción: (a) verificar equivalencia de dos circuitos (miter: XOR de salidas → UNSAT ⟹ equivalentes); (b) generar un vector de prueba que distinga (SAT del miter); (c) atascos (stuck-at): distinguir el circuito sano del circuito con la falla.
- Codificación: las compuertas se codifican con cláusulas de Tseitin
(la infraestructura
satx::engineya genera circuitos aritméticos con CBE: cada compuerta es un bloque de cláusulas). - Objetivo: decisión SAT/UNSAT; #SAT (BASILISK) cuenta los vectores que detectan una falla (cobertura de test).
- Escala: circuitos con decenas de miles de compuertas; añadir
--symmetrypara circuitos con subbloques repetidos.
- Kernel: SLIME.
- Descripción: decidir el patrón de cajas por capa de paleta y el número de capas, con estabilidad y peso máximo.
-
Variables:
$x_{i,pos}$ (caja$i$ en posición de la rejilla de capa);$L_c$ (capa$c$ activa). - Restricciones: rejilla con solapamiento prohibido (como 1.3), peso acumulado por columna ≤ máximo, capas contiguas (sin huecos intermedios para estabilidad).
- Objetivo: maximizar cajas por paleta (o minimizar paletas con WMIBO).
- Variantes: cajas de varios tamaños, capas alternadas (trabazón).
- Kernel: PIXIE (LP).
-
Especificación:
- Datos: ingredientes con costo
$c_i$ y nutrientes$a_{n,i}$ ; mínimos y máximos nutricionales$[L_n,U_n]$ . - Variables:
$x_i\ge0$ (cantidad de ingrediente$i$ ). - Restricciones:
$L_n\le\sum_i a_{n,i}x_i\le U_n$ para cada nutriente; proporciones ($x_i\le p\cdot\sum_j x_j$ ). - Objetivo:
$\min\sum_i c_i x_i$ .
- Datos: ingredientes con costo
- Escala: cientos de ingredientes × decenas de nutrientes: milisegundos.
- Variantes: enteros (paquetes discretos → MIP), sensibilidad (rangos de costos donde la solución no cambia — análisis dual).
- Kernel: PIXIE (MIP) / WMIBO.
-
Especificación:
- Datos: pilas de mineral con calidades
$q_{i,k}$ (ley, humedad, ceniza, azufre) y disponibilidad$A_i$ ; pedidos con bandas de calidad$[L_{p,k},U_{p,k}]$ y tonelaje$D_p$ . - Variables:
$x_{i,p}\ge0$ (toneladas de pila$i$ al pedido$p$ );$y_{i,p}\in{0,1}$ si se exige lote mínimo. - Restricciones:
- cumplimiento:
$\sum_i x_{i,p}=D_p$ ; - disponibilidad:
$\sum_p x_{i,p}\le A_i$ ; - calidad por pedido:
$L_{p,k}D_p\le\sum_i q_{i,k}x_{i,p}\le U_{p,k}D_p$ (¡la restricción es lineal en$x$ !). - lote mínimo:
$x_{i,p}\ge q^{\min}y_{i,p}$ ,$x_{i,p}\le A_i y_{i,p}$ .
- cumplimiento:
- Objetivo: minimizar el costo de uso de material noble, o el tonelaje de la pila más barata; WMIBO: blandas para pedidos que toleran bandas.
- Datos: pilas de mineral con calidades
- Escala: 100 pilas × 20 pedidos × 10 calidades → MIP mediano, segundos a minutos; los lotes mínimos binarios son la parte dura.
- Variantes: múltiples períodos (agotamiento de pilas), mezclas en línea (nivel de silo).
- Kernel: WMIBO (linealizado por tramos) o SLIME (discretización aritmética exacta con CBE).
- Descripción: combinar crudos para cumplir especificaciones de refino (densidad, azufre, octanaje de cortes) cuando las propiedades no se mezclan linealmente (p. ej. índice de viscosidad, octanaje).
-
Especificación:
- Variables:
$x_i$ (fracción de crudo$i$ ), con$\sum x_i=1$ ; - propiedad
$k$ :$P_k = g_k(x)$ con$g_k$ cóncava/convexa → aproximación por tramos:$P_k=\sum_\ell \lambda_\ell g_k(x_\ell)$ con SOS2. - Restricciones: bandas de producto
$[L_k,U_k]$ , disponibilidad y compatibilidad de crudos (corrosivos, ácidos).
- Variables:
-
Codificación SATX (discretización exacta): fijar un paso de mezcla
(p. ej. 1 %) y modelar
$\sum x_i=1$ sobre enteros con las restricciones aritméticas delengine; la no linealidad se evalúa tabla a tabla (g_kprecalculada), generando una cláusula por celda inválida. - Escala: 10 crudos × 5 propiedades × paso 1 % → ~10⁴ celdas; SAT decide en segundos; #SAT cuenta las recetas factibles (espacio de diseño).
- Variantes: multiperíodo con inventario de tanques, mezclas de gasolina con RVP/oxigenados.
- Kernel: SLIME / WMIBO.
- Descripción: formular un lote con concentraciones objetivo e incompatibilidades binarias (reactivos que no pueden coexistir).
-
Variables:
$x_i$ continuas (o discretizadas) de cada componente;$y_i$ binarias (componente presente). -
Restricciones: balance de masa, pureza
$\sum_i p_i x_i \ge P\cdot \sum_i x_i$ , incompatibilidad$\neg y_i \lor \neg y_j$ , estabilidad (vida útil conjunta ≥ mínimo). - Objetivo: minimizar costo; blandas: preferencia por proveedor, restricción de stock.
- Kernel: SLIME.
- Descripción: asignar turnos (D/E/N, libre) a enfermeras por día cumpliendo cobertura, contratos y reglas.
-
Variables:
$x_{n,d,s}\in{0,1}$ . -
Restricciones:
- cobertura:
$\sum_n x_{n,d,s}\ge \text{req}_{d,s}$ (cardinalidad); - exactamente un turno por enfermera y día;
- no N seguido de D; máximo de noches consecutivas; descanso tras noche;
- horas contractuales mensuales (sumas con CBE o cardinalidad).
- cobertura:
- Objetivo: factibilidad; WMIBO con blandas (peticiones de día libre, equidad de fines de semana).
- Escala: 20 enfermeras × 28 días → ~10⁴ literales, segundos; es un benchmark clásico de SAT competitivo.
- Kernel: SLIME / WMIBO.
-
Descripción: programar una liga de
$n$ equipos (impar → fantasma) con localía alternada, derbis no coincidentes, estadios compartidos, TV. -
Variables:
$x_{i,j,r}\in{0,1}$ (en la ronda$r$ ,$i$ recibe a$j$ );$h_{i,r}$ (localía de$i$ ). - Restricciones: todos contra todos (exactamente una vez por par, en alguna ronda), un partido por equipo y ronda, límite de partidos de local consecutivos, pares que no coinciden en casa (estadio compartido).
- Escala: 20 equipos × 19 rondas → decenas de miles de variables; es el clásico de la literatura de "break minimization" (WMIBO: minimizar cambios de localía con blandas).
- Kernel: BASILISK (#SAT) + SLIME.
-
Descripción: encontrar el mínimo conjunto de pruebas que cubre toda
combinación de
$t$ parámetros (fuerza$t$ ), clave en pruebas de software y de configuración industrial. -
Variables:
$x_{r,p,v}$ (fila de prueba$r$ , parámetro$p$ , valor$v$ ). -
Restricciones:
- un valor por parámetro y fila;
- cobertura: para cada
$t$ -tupla$(p_1..p_t, v_1..v_t)$ , al menos una fila la realiza:$\bigvee_r \bigwedge x_{r,p_i,v_i}$ (generar con BASILISK por enumeración o con SLIME incremental).
- Objetivo: minimizar filas (búsqueda binaria); #SAT cuenta diseños admisibles para evaluar margen.
- Escala: fuerza 2 con 10 parámetros × 5 valores → decenas de filas.
- Kernel: SLIME.
-
Descripción: generar mapas de videojuego que cumplan reglas: sala
inicial y final conectadas, llaves antes que puertas,
$k$ enemigos con distancia mínima, simetría estética. -
Variables:
$c_{x,y}$ (celda = muro/suelo),$r_i$ (sala$i$ ),$d_e$ (distancia entre entidades, con CBE). - Restricciones: conectividad (flujo o alcanzabilidad por pasos), precedencia llave–puerta (camino sin la puerta), cotas de dificultad (número de celdas transitables).
- Salida: cada modelo es un mapa válido; re-ejecutar con suposiciones distintas (semilla) produce variantes; BASILISK cuenta cuántos mapas existen (dimensionamiento de contenido).
- Escala: mapas de 20×20 con presupuesto de distancia → segundos.
- Kernel: SLIME / BASILISK.
- Descripción: generar melodías y progresiones que cumplen reglas de contrapunto o estilo: notas en escala, resolución de sensibles, prohibición de quintas paralelas, forma (ABA).
-
Variables:
$n_{t,p}$ (nota$p$ en el pulso$t$ );$ch_{c,t}$ (acorde$c$ en el compás$t$ ). -
Restricciones: exactamente una nota por pulso; consonancia con el
acorde activo; movimientos prohibidos entre pulsos consecutivos
(cláusulas
$\neg n_{t,p}\lor\neg n_{t+1,q}$ ); repetición temática (ABA:$n_{t,p}=n_{T-t,p}$ ). - Salida: BASILISK enumera las composiciones del estilo (espacio creativo medible); SLIME devuelve una por semilla.
- Kernel: SLIME / BASILISK.
-
Ejemplos: Sudoku
$n^2\times n^2$ , Nonogramas, Slitherlink, rompecabezas tipo Einstein/Zebra, cripto-aritmética (SEND+MORE=MONEY con sumadores CBE). -
Codificación: variables
$x_{i,j,d}$ (celda$(i,j)$ con dígito$d$ ); AMO/ALO por celda, fila, columna y caja; BASILISK determina si la solución es única (unicidad de la pista) contando modelos. -
Escala: Sudoku 9×9 → 729 variables, instantáneo; 25×25 → miles de
variables, segundos con
--symmetry(simetrías de dígitos rotas automáticamente por el pase de simetrías de SATX).
-
Kernel: SLIME (ya en los ejemplos:
gaussian_integer_factorization). -
Descripción: factorizar
$z=a+bi$ en$\mathbb{Z}[i]$ modelando la multiplicación como circuito CBE (negabinario para signos sin sesgo) y resolviendo por SAT. - Variables: bits de los factores; cláusulas del multiplicador.
- Escala: enteros de 16–32 bits por factor → segundos; la complejidad crece como el tamaño del circuito (no es criptográficamente competitivo, pero ilustra SAT sobre aritmética exacta).
-
Kernel: SLIME (ejemplo
quantum_learning). -
Descripción: dado un dato medido (OTOC) de un circuito cuántico,
reconstruir la compuerta desconocida
$B$ modelada con coeficientes simbólicos, unitaridad y realidad, de modo que el eco reproduzca el dato. -
Variables: bits de los coeficientes de
$B$ (punto fijo W,F); la evolución del circuito se compila a restricciones SAT (CBE/CORDIC). -
Salida: la matriz
$B$ aprendida verifica contra el oráculo numérico.
- Kernel: SLIME.
- Descripción: mover un robot (o brazo) en una rejilla con obstáculos, evitando colisiones y minimizando pasos.
-
Variables:
$x_{t,celda}$ (el robot está en la celda en el paso$t$ ); AMO por paso; transición válida entre pasos (adyacencia libre); obstáculos fijos. - Objetivo: factibilidad con horizonte acotado (búsqueda binaria del mínimo); multi-robot con colisión mutua (AMO sobre celdas por paso).
- Variantes: brazos articulados (configuraciones como celdas de un C-space discretizado), rutas con zonas de exclusión temporal.
- Kernel: SLIME / WMIBO.
- Descripción: menú semanal (desayuno/almuerzo/cena) con variedad, presupuesto, alergias y balance nutricional (combinar con 4.1).
-
Variables:
$x_{d,m,p}$ (plato$p$ el día$d$ en la comida$m$ ). -
Restricciones: un plato por comida; no repetir el mismo plato más de
$k$ veces por semana; alergias del comensal excluyen platos; presupuesto semanal (suma de costos); nutrientes agregados (ventanas). - Salida: WMIBO pondera preferencias como blandas (platos favoritos).
- Kernel: WMIBO.
- Descripción: plan de rutas (como 1.2/2.1) con objetivo multi-criterio: distancia, consumo (dependiente de carga → tramos con costo incremental), emisiones por zona (LEZ), ventanas.
-
Modelo: cláusulas duras de factibilidad; blandas:
$w_1$ ·km +$w_2$ ·CO₂ +$w_3$ ·retrasos; explorar el frente variando pesos (re-ejecuciones con suposiciones de presupuesto por métrica). - Salida: planes Pareto-comparables para el decisor.
| # | Problema | Sección | Kernel típico | Tipo |
|---|---|---|---|---|
| 1 | Facility location | 1.1 | PIXIE MIP | opt |
| 2 | CVRP | 1.2 | WMIBO | opt |
| 3 | Cubicaje 2D/3D | 1.3 | SLIME | dec/opt |
| 4 | Muelles de carga | 1.4 | SLIME | dec/opt |
| 5 | Cross-docking | 1.5 | SLIME/WMIBO | dec/opt |
| 6 | Ventanas + flota | 2.1 | SLIME/WMIBO | dec/opt |
| 7 | Order batching | 2.2 | WMIBO | opt |
| 8 | Casilleros | 2.3 | SLIME/BASILISK | dec/count |
| 9 | Técnicos + habilidades | 2.4 | SLIME/WMIBO | dec/opt |
| 10 | TSP-D | 2.5 | WMIBO | opt |
| 11 | Job shop | 3.1 | SLIME/WMIBO | dec/opt |
| 12 | Coladas/changeover | 3.2 | WMIBO | opt |
| 13 | Cutting stock | 3.3 | PIXIE+SLIME | opt |
| 14 | Mantenimiento | 3.4 | SLIME | dec |
| 15 | Circuitos/pruebas | 3.5 | SLIME/BASILISK | dec/count |
| 16 | Paletización | 3.6 | SLIME | dec/opt |
| 17 | Dieta | 4.1 | PIXIE LP | opt |
| 18 | Minerales/carbón | 4.2 | PIXIE MIP | opt |
| 19 | Crudos no lineales | 4.3 | WMIBO/SLIME | dec/opt |
| 20 | Química/reactividad | 4.4 | SLIME/WMIBO | dec/opt |
| 21 | Nurse rostering | 5.1 | SLIME | dec |
| 22 | Deportes | 5.2 | SLIME/WMIBO | dec/opt |
| 23 | Covering arrays | 5.3 | BASILISK | count |
| 24 | Mapas procedurales | 5.4 | SLIME/BASILISK | dec/count |
| 25 | Música con reglas | 5.5 | SLIME/BASILISK | dec/count |
| 26 | Rompecabezas | 5.6 | SLIME/BASILISK | dec/count |
| 27 | Gaussianos | 5.7 | SLIME | dec |
| 28 | Cuántica inversa | 5.8 | SLIME | dec |
| 29 | Robot path | 5.9 | SLIME | dec |
| 30 | Menús | 5.10 | SLIME/WMIBO | dec/opt |
| 31 | CO₂ | 5.11 | WMIBO | opt |
-
Acotar siempre: horizonte, granularidad de tiempo/rejilla y
$B$ de presupuesto dominan el tamaño; empezar grueso y refinar (la solución gruesa guía la fina con suposiciones). -
Simetrías: muchos de estos problemas (muelles idénticos, máquinas
idénticas, dígitos de Sudoku, vehículos homogéneos) tienen simetrías
masivas; el pase de rompimiento de simetrías de la raíz (
use_symmetry, activo por defecto) las elimina de forma sonora. -
Conteo para dimensionar: usar BASILISK (
count_projected) para contar configuraciones admisibles (red de casilleros, mapas, diseños de experimento) en lugar de enumerar con un solver. - Blandas para negociar: WMIBO permite declarar restricciones negociables con peso; el óptimo reporta qué se sacrificó y a qué costo.
-
Sesiones: refinamientos interactivos (fijar una decisión, re-resolver
sin reconstruir) mediante
satx::solver::session; recordar que las sesiones no aplican rompimiento de simetrías (se fuerzause_symmetry=0). -
Pruebas de UNSAT:
--proofgenera DRAT para verificación independiente de infactibilidad (importante en diseño de circuitos y planificación legal).