Cheaf Docs
Package Building

Configuración del Algoritmo de Packing

Este documento explica los diferentes parámetros que se pueden configurar en el algoritmo de packing para optimizar la selección y asignación de productos en bolsas dadas ciertas restricciones de negocio.

1. Opciones del Modelo (model_options)

Estas son configuraciones técnicas para el motor de optimización que utiliza el algoritmo. Generalmente, no necesitan ser modificadas por usuarios no técnicos. Afectan cómo el algoritmo busca la mejor solución (por ejemplo, timeLimit define el tiempo máximo en segundos que el algoritmo puede usar).

Ejemplo:

"model_options": {
    "timeLimit": 30,
    "msg": false,
    "gapRel": 0.0,
    "cuts": true,
    "threads": 4
}
  • timeLimit: 30: El algoritmo tiene 30 segundos para encontrar la mejor solución.

2. Estrategias de Agrupación y Packing

El algoritmo utiliza diferentes "estrategias" para decidir cómo agrupar productos y aplicar las reglas de cap. La configuración permite elegir la estrategia más adecuada para cada situación.

2.1. Estrategia por Defecto (default_strategy)

Define la estrategia de packing que se usará para todas las categorías de productos, a menos que se especifique una diferente en custom_strategies.

Valores Comunes:

  • "subrubro": Agrupa por Subcategoría. Esta estrategia es útil cuando se quiere controlar cuántos productos de una misma subcategoría van juntos en una bolsa. Aplica los caps definidos (cap_rules) a nivel de subcategoría.
  • "sku": Control por Producto Individual (SKU). Esta estrategia trata cada producto (identificado por su SKU) de forma independiente. Es útil para un control más granular. Aplica los caps a nivel de SKU individual y además intenta balancear el valor dentro de la bolsa, evitando que un solo producto muy caro ocupe la mayor parte del valor permitido. Fomenta una mayor variedad de SKUs distintos dentro de cada bolsa.

Ejemplo:

"default_strategy": "subrubro"

  • Por defecto, el algoritmo agrupará y aplicará caps basados en las subcategorías de los productos.

2.2. Estrategias Personalizadas (custom_strategies)

Permite anular la estrategia por defecto para categorías específicas.

Ejemplo:

"custom_strategies": {
    "28": "sku"
}
  • Aunque la estrategia por defecto sea "subrubro", para los productos de la categoría "28", se usará la estrategia "sku", aplicando caps por producto individual y buscando balancear el valor y la variedad de SKUs en las bolsas que contengan productos de esta categoría.

4. Reglas de Cap con Jerarquía (cap_rules)

Esta es la sección principal para definir cuántas unidades de ciertos tipos de productos se pueden incluir como máximo. Las reglas se aplican por categoría siguiendo una jerarquía estricta que resuelve automáticamente conflictos de configuración.

4.1. Estructura de cap_rules

{
  "cap_rules": {
    "categories": {
      "5": {
        "default_cap": 2,
        "barcode_exceptions": { /* productos específicos */ },
        "subrubro_exceptions": { /* subcategorías */ },
        "price_exceptions": [ /* reglas por precio */ ]
      }
    },
    "group_rules": {
      "categories": {
        "5": [ /* reglas de grupo */ ]
      }
    }
  }
}

4.2. Jerarquía de Aplicación de Reglas (FUNDAMENTAL)

El sistema aplica las reglas siguiendo una jerarquía estricta donde las reglas más específicas siempre tienen prioridad:

1. barcode_exceptions     (PRIORIDAD MÁS ALTA - Producto específico)
2. subrubro_exceptions    (Subcategoría completa)  
3. price_exceptions       (Basado en precio)
4. default_cap           (PRIORIDAD MÁS BAJA - Valor por defecto)

Principio Fundamental: Si un producto tiene configuraciones en múltiples niveles, SIEMPRE se usa la regla del nivel más alto en la jerarquía.

Ejemplo de Resolución de Conflictos:

Producto: barcode="7804676940218", subrubro="J0401023106", precio=18000

Configuración:

{
  "barcode_exceptions": {"7804676940218": 1},
  "subrubro_exceptions": {"J0401023106": 3}, 
  "price_exceptions": [{"condition": "less_than", "value": 20000, "cap": 4}],
  "default_cap": 2
}

RESULTADO: cap = 1 (barcode_exceptions gana sobre todas las demás)

4.3. Tipos de Reglas Detalladas

4.3.1. barcode_exceptions (Prioridad 1 - MÁS ALTA)

Permite definir caps específicos para productos individuales identificados por su código de barras.

"barcode_exceptions": {
  "7804676940218": 1,    // Este producto específico: máximo 1 unidad
  "1234567890123": 3     // Este otro producto: máximo 3 unidades
}

Uso: Para casos especiales de productos que requieren límites únicos.

4.3.2. subrubro_exceptions (Prioridad 2)

Define caps para subcategorías completas de productos.

"subrubro_exceptions": {
  "J0401023106": 1,    // Todos los productos de este subrubro: máximo 1
  "J0401023107": 3     // Todos los productos de este subrubro: máximo 3
}

Uso: Para controlar subcategorías completas (ej: lácteos, bebidas).

4.3.3. price_exceptions (Prioridad 3)

Aplica caps basados en el precio del producto.

"price_exceptions": [
  {
    "condition": "less_than",
    "value": 20000,
    "cap": 4              // Productos baratos más permisivos
  }
]

Uso: Para dar más flexibilidad a productos de menor valor.

4.3.4. default_cap (Prioridad 4 - MÁS BAJA)

Valor por defecto para productos que no tienen excepciones configuradas.

"default_cap": 2        // Si no aplica ninguna excepción: máximo 2

4.4. Comportamiento por Estrategia

Estrategia "subrubro" (SubrubroCapStrategy)

  • Caps individuales: Se respetan las jerarquías para cada producto
  • Restricciones de subrubro: Se agregan automáticamente basadas en los caps individuales
  • Barcode exceptions: Se respetan a nivel individual Y se reflejan en restricciones de subrubro
  • Consistencia conceptual: Si configuras subrubro_exceptions, se aplican restricciones de subcategoría

Ejemplo:

"subrubro_exceptions": {"J0401023106": 1}
  • Cada producto del subrubro: máximo 1 unidad individual
  • Total del subrubro: máximo 1 unidad por bolsa
  • Ambas restricciones se aplican simultáneamente

Estrategia "sku" (SkuCapStrategy)

  • Caps individuales: Se aplican directamente a cada SKU
  • Subrubro exceptions: Además del cap individual, se agregan restricciones de subcategoría automáticamente
  • Balanceador de valor: Evita que un SKU domine el valor de la bolsa
  • Mayor variedad: Incentiva diversidad de productos

Ejemplo:

"subrubro_exceptions": {"J0401023106": 1}
  • Cada producto del subrubro: máximo 1 unidad individual
  • Total del subrubro: máximo 1 unidad por bolsa (se agrega automáticamente)
  • Se mantiene consistencia conceptual

4.5. Reglas de Cap por Grupos (group_rules)

Las reglas de grupo permiten controlar la cantidad total de productos relacionados que se incluyen en cada bolsa, trabajando junto con los caps individuales.

Estructura:

{
  "group_rules": {
    "categories": {
      "5": [
        {
          "key": "subrubro",
          "values": ["J0401023106", "J0401023107"],
          "cap": 2,
          "description": "Máximo 2 productos lácteos total"
        }
      ]
    }
  }
}

Parámetros:

ParámetroDescripciónEjemplo
capCantidad máxima TOTAL del grupo por bolsa2
keyCriterio de agrupación"subrubro"
valuesCódigos que definen el grupo["J0401023106", "J0401023107"]

Interacción con Caps Individuales:

AMBAS restricciones se aplican simultáneamente:

{
  "subrubro_exceptions": {"J0401023106": 2},  // Individual: máx 2 por producto
  "group_rules": [
    {"key": "subrubro", "values": ["J0401023106"], "cap": 1}  // Grupo: máx 1 total
  ]
}

Resultado: Máximo 1 producto del subrubro por bolsa (la restricción más estricta se respeta).

4.6. Validación Automática de Configuración

El sistema detecta automáticamente problemas de configuración:

Conflictos Detectados:

⚠️  "Category 5: Conflict - subrubro 'J0401023106' has individual cap 3 but group cap is 1"

Redundancias Detectadas:

⚠️  "Category 5: Redundant - subrubro 'J0401023107' has same cap as default_cap (2)"

4.7. Ejemplo Completo con Jerarquía

{
  "default_strategy": "subrubro",
  "custom_strategies": {
    "5": "subrubro",
    "6": "sku"
  },
  "cap_rules": {
    "categories": {
      "5": {
        "default_cap": 2,
        "barcode_exceptions": {
          "7804676940218": 1      // Producto específico MUY restrictivo
        },
        "subrubro_exceptions": {
          "J0401023106": 1,       // Leches restrictivas
          "J0401023107": 3        // Quesos permisivos
        },
        "price_exceptions": [
          {
            "condition": "less_than",
            "value": 20000,
            "cap": 4              // Productos baratos más permisivos
          }
        ]
      }
    },
    "group_rules": {
      "categories": {
        "5": [
          {
            "key": "subrubro",
            "values": ["J0401023106", "J0401023107"],
            "cap": 2,              // Máximo 2 lácteos total por bolsa
            "description": "Grupo lácteos"
          }
        ]
      }
    }
  }
}

Casos de Aplicación:

  1. Producto con barcode="7804676940218": cap = 1 (barcode_exception)
  2. Producto del subrubro "J0401023106" sin barcode_exception: cap = 1 (subrubro_exception)
  3. Producto precio 18000 del subrubro "J0401023999": cap = 4 (price_exception)
  4. Producto precio 25000 sin excepciones: cap = 2 (default_cap)
  5. Total de lácteos (J0401023106 + J0401023107): máximo 2 por bolsa (group_rule)

5. Objetivo del Algoritmo: ¿Qué Busca Optimizar?

El núcleo del algoritmo es un motor de optimización matemática que intenta encontrar la "mejor" forma de llenar las bolsas según las reglas configuradas.

  1. Maximizar la Variedad de Productos: El objetivo primordial es incluir la mayor cantidad posible de productos diferentes (SKUs únicos) dentro de cada bolsa y en el conjunto total de bolsas. El algoritmo recibe un "bono" muy significativo por cada producto distinto que añade.
    • Énfasis según la Estrategia: Ambas estrategias (sku y subrubro) han sido ajustadas para dar un peso muy alto a este bono de variedad, convirtiéndolo en el factor dominante en la optimización.
  2. Maximizar el Valor Total Empaquetado (Secundario): Aunque sigue siendo importante, la maximización del valor monetario total de los productos empacados es un objetivo secundario frente a la variedad. El algoritmo puede optar por una solución con un valor total ligeramente inferior si consigue una diversidad de productos significativamente mayor.
  3. Cumplir Estrictamente Todas las Reglas: La optimización siempre se realiza respetando todas las restricciones definidas en la configuración:
    • Rango de precio total por bolsa (mínimo y máximo) - VIENE DEL API.
    • Disponibilidad de inventario de cada producto.
    • Caps máximos por categoría, subrubro o SKU (según cap_rules y la estrategia aplicada).
    • Reglas de grupo (group_rules).
    • Otras reglas internas (como el balance de valor en la estrategia sku, que también ayuda a la variedad).

Proceso Resumido:

El algoritmo toma la lista de productos disponibles, analiza la configuración (estrategias, caps jerárquicos, group_rules) y utiliza su motor de optimización para encontrar la asignación de productos a bolsas que mejor cumpla con el objetivo principal de maximizar la variedad, y luego, secundariamente, el valor, sin romper ninguna regla. El resultado final es:

  • Las bolsas creadas con los productos asignados (esperablemente más diversas).
  • La lista de productos que no pudieron ser empaquetados (merma).
  • Métricas de rendimiento (ej. porcentaje del valor total utilizado, número de SKUs únicos por bolsa).

Esta configuración permite controlar:

  • Cómo el optimizador busca soluciones.
  • Cómo se agrupan los productos (por subrubro, SKU, etc.).
  • Cuántas unidades de cada categoría/subrubro/producto específico se permiten como máximo.
  • Cómo se comportan los grupos de productos relacionados.

Esto da flexibilidad para ajustar el comportamiento del algoritmo según las necesidades del negocio y las características de los productos.

Evolución del Algoritmo de Packing

Tabla Comparativa

CaracterísticaAlgoritmo v1Algoritmo Actual
Estrategia baseReglas empíricas manualesOptimización matemática basada en programación lineal mixta (MILP)
Enfoque de variedadManual (por subrubro y número mínimo de SKUs)Variedad como objetivo primario en función objetivo con peso alto
Control por SKU/SubrubroHeurístico, por reglas de capsDefinido por estrategia "sku" o "subrubro" con reglas configurables
Rango de precioRango fijo, ajustes manuales si no se logra cumplirRango dinámico pasado desde el API (min_price, max_price)
Motor de decisiónLógica secuencial con muchas excepcionesOptimizador con parámetros como gapRel, cuts, threads, timeLimit
Personalización por categoríaManual, embebida en códigoConfigurable por custom_strategies por categoría
Métricas por boxIncluidas manualmenteCalculadas automáticamente (valor, SKUs únicos, subrubros únicos, etc.)
Adaptabilidad a nuevas reglasRequiere reescribir lógicaBasta con actualizar configuración
Tratamiento de productos fuera de rangoAjustes post-hoc (reordenamientos, etc.)Productos fuera de rango se excluyen al inicio según lógica matemática
Transparencia para operacionesBaja, dependiente de lectura del códigoAlta, a través de configuración documentada y clara
Resolución de conflictosManual, inconsistenteJerarquía automática con validación
Reglas de grupoNo disponibleConfigurable con group_rules

Mejoras Introducidas en el Algoritmo Actual

  1. Jerarquía de Caps con Resolución Automática de Conflictos:

    • Sistema jerárquico estricto: barcode → subrubro → price → default
    • Validación automática de configuraciones inconsistentes
    • Warnings para configuraciones redundantes o conflictivas
  2. Reglas de Grupo (group_rules):

    • Control de productos relacionados a nivel de grupo
    • Restricciones que trabajan junto con caps individuales
    • Evita saturación de bolsas con productos similares
  3. Uso de Programación Lineal Mixta (MILP):

    • El algoritmo actual formaliza el problema como un modelo matemático con restricciones y función objetivo, lo que permite:
      • Optimizar simultáneamente variedad y valor.
      • Asegurar el cumplimiento estricto de caps y precios sin necesidad de excepciones manuales.
      • Obtener resultados reproducibles y auditables.
  4. Separación de lógica y configuración:

    • Permite cambiar reglas de negocio sin tocar el código.
    • Facilita mantenimiento y colaboración con stakeholders no técnicos.
  5. Control más fino de variedad y balance de productos:

    • El modelo puede balancear productos caros y baratos automáticamente.
    • Incentiva bolsas diversas con valor razonable.
  6. Mayor claridad operativa:

    • Toda la lógica de caps, rangos de precios, y estrategias por categoría está centralizada y documentada.
    • Facilita explicación, auditoría y ajustes según necesidades comerciales.