Conversión de una distribución en una grilla




Las distribuciones en Envision son prácticas, porque están respaldadas por un álgebra completa de distribuciones. Sin embargo, para generar decisiones de inventario, generalmente es necesario transformar esas distribuciones de nuevo en una grilla, es decir, una tabla que enumera los valores de la distribución, generalmente en forma de probabilidades. Al utilizar una grilla de este tipo, resulta posible crear la tabla final que contiene las cantidades de pedido de compra sugeridas o los movimientos de inventario sugeridos. Aquí veremos en detalle cómo puede utilizarse la función extend.distrib() para este fin.


Grillas vs distribuciones

Una grilla es una tabla simple que contiene una lista de cubos (buckets) de histograma, un histograma por distribución original, y una línea por cubo dentro del histograma, La representación genérica de una grilla es una tabla con cuatro campos:

  • Id que identifica el artículo
  • Min, el límite inclusivo menor del cubo de histograma
  • Max, el límite inclusivo mayor del cubo de histograma
  • Value, el valor asociado con el cubo de histograma

Para un determinado artículo, la grilla puede contener una serie de cubos que representan el histograma completo de la distribución. Si la distribución es una variable aleatoria, el valor del cubo puede interpretarse como la probabilidad de la distribución sobre el segmento cubierto por el cubo.

Las grillas no son tan flexibles como las distribuciones. Para lograr el nivel de rendimiento necesario, a menudo no es posible mantener cubos que tengan un ancho de 1. Por este motivo, se utilizan, en cambio, cubos más grandes para hacer que los requisitos de memoria se mantengan gestionables dentro de Lokad. Los cubos sin unidad complican los cálculos que se realizan en las grillas. Además, por su diseño, las grillas tienen soporte compacto (en el sentido matemático): sus valores diferentes de cero solo se definen para una cantidad finita de puntos.

Por otra parte, las grillas son tablas simples que pueden procesarse en otras tablas a través de los operadores de Envision habituales. Como regla general, Envision adopta un abordaje en el que todo el modelado económico y probabilístico se realiza con distribuciones, dejando la transformación en grillas solo como uno de los pasos finales, justo antes de generar las decisiones de cadena de suministro sugeridas finales.

Sintaxis de extend.distrib()

Las distribuciones de Envision ofrecen un álgebra potente, que puede utilizarse para evitar los cálculos complicados de probabilidades en listas. Sin embargo, existen situaciones en las que tener una lista de probabilidades sin procesar es adecuado e incluso deseable. La extensión de distribución extend.distrib() convierte a un vector de distribuciones en una tabla, como lo ilustra la sintaxis a continuación:
table T = extend.distrib(D)
T.Probability = int(D, T.Min, T.Max)
show table "Distribution details" with 
  Id
  T.Min
  T.Max
Se espera que el argumento D sea un vector de distribuciones, como habitualmente lo genera el motor de pronóstico probabilístico de Lokad. La tabla T es escribe como una extensión de la tabla originaria, la tabla Items implícita en el script anterior. La tabla T se rellena con tres campos:

  • T.Min: El límite inferior integral inclusivo del segmento
  • T.Max: el ĺimite superior integral inclusivo del segmento

Para distribuciones relativamente compactas, los segmentos tienen una longitud de 1 y, por lo tanto, T.Min == T.Max. Sin embargo, si la distribución abarca valores más altos, los segmentos de longitud igual a 1 acabarían generando posiblemente millones de líneas, algo que se vuelve imposible de gestionar. Por lo tanto, al enfrentarse a distribuciones con valores tan grandes, Envision autoagrega estas distribuciones en torno a segmentos más grandes. Los algoritmos se adaptan de consecuencia para mantener la dimensión de las tablas generadas dentro de parámetros gestionables.

Por diseño, extend.distrib() siempre identifica el segmento cero. Como resultado, el segmento [0;0] siempre obtiene su propia línea en la tabla generada. Este comportamiento es útil en muchas situaciones de negocios en las que la demanda cero representa un caso extremo, como una cobertura de existencias infinita, que requiere una lógica específica.

Luego, se proporcionan otras tres sobrecargas para extend.distrib() para obtener más control sobre la granularidad específica de la tabla generada.

Opción de brecha

La primera sobrecarga está pensada para ayudar a construir una lista de priorización de compra al tiempo que tiene en cuenta los niveles de stock actuales. La sintaxis es la siguiente:
table T = extend.distrib(D, S)
El primer argumento D es el mismo que se definió anteriormente. Se espera que el segundo argumento S sea un número entero. Cuando este segundo argumento está presente, la tabla generada siempre incluye dos líneas dedicadas a los dos segmentos [0;0] y [1;S]. Como se mostraba antes, se autogeneran más segmentos comenzando desde S+1. Cuando no se especifica, el valor predeterminado de este argumento es cero.

En la práctica, el argumento S a menudo se define como la suma del stock disponible más el stock pedido. Al reordenar, solo deberían considerarse las probabilidades de demanda que exceden el nivel de stock actual.

Opción de multiplicador

La segunda sobrecarga está pensada para situaciones que involucran multiplicadores de lotes. En estas situaciones, la tabla debería iterar sobre segmentos de dimensiones específicas. La sintaxis es la siguiente:
table T = extend.distrib(D, S, M)
Los argumentos D y S son los que se definieron anteriormente. Se espera que el tercer argumento, M, sea un número entero, que representa la longitud del segmento deseada. Así, la tabla incluye la lista de segmentos [0;0], [1;S], [S+1;S+M] [S+M+1;S+2M] … Si M es cero, la función recurre al dimensionamiento automático de los segmentos.

En la práctica, el forzado de los segmentos cuya longitud es igual a 1 probablemente generaría problemas de rendimiento, debido a que la dimensión de la tabla podría resultar arbitrariamente grande. Así, Envision tiene la posibilidad, en cambio, valerse de un múltiplo de M. El uso de un múltiplo asegura que la lógica de multiplicador de lote siga funcionando, al tiempo que se preservan límites sensatos en el número de líneas por generar.

Como regla general, le sugerimos no utilizar esta sobrecarga específica a menos que haya multiplicadores de lotes involucrados; y cuando así fuera, se recomienda mantener M en cero para todo artículo que no tenga un multiplicador de lote específico.

Opción de alcance

La tercera sobrecarga está pensada para situaciones que involucran MOQ. En estas situaciones, la tabla debería iterar lo suficiente como para alcanzar determinados valores deseados. La sintaxis es la siguiente:
table T = extend.distrib(D, S, M, R)
Los argumentos D, S y M son los que se definieron anteriormente. Se espera que el cuarto argumento, R, sea un número entero no negativo. Representa el valor máx que se desea alcance la grilla, lo que significa que habrá una línea en la que T.Max es mayor o igual que R. Cuando no se especifica, el valor predeterminado de este argumento es cero.

En la práctica, este argumento se utiliza para gestionar limitaciones grandes de cantidades de pedido mínimas (MOQ) que solo pueden satisfacerse si las distribuciones generadas tienen un alcance suficiente como para alcanzar los valores de MOQ.

Como regla general, sugerimos no utilizar esta sobrecarga a menos que haya MOQ específicas que alcanzar. Si así fuera, se sugiere mantener R lo menor posible. Un valor R pequeño no evita que la tabla T alcance valores mayores, solo asegura que se alcancen valores más grandes.