Cuando formulamos un modelo para compañías grandes, frecuentemente encontrará que no están limitadas a una sola planta para producir los productos. Además en esta sesión usted creará un modelo de planificación de la producción que incluye múltiples plantas. Tomará el modelo de la sesión previa y le agregará otros índices plantas, los cuales representan a todas las plantas disponibles para producir los productos. Luego irá a través del modelo, paso a paso y actualizará todos los vectores variables y restricciones para explicar el nuevo índice.
Los Indices de Localización son bastante comunes cuando se formula modelos de planificación de la producción. Un ejemplo de un Indice de Localización, debe ser para representar las plantas donde la compañía produce los productos. Otros ejemplos deben incluír Almacenes, Fábricas, Centros de Distribución, etc.
Esto es común, cuando se trabaja con modelos que incluyen índices de localización, donde el embarque es permitido entre localizaciones. Esos modelos a menudo son llamados modelos de Distribución o modelos de transporte y serán cubiertos más tarde en otras sesiones.
Cuando se formula modelos pequeños y sencillos, es razonable dejar las definiciones de datos dentro del modelo. Tan pronto como empieze a trabajar con modelos multidimensionales, llegan las dificultades de su manejo y es necesario mover los datos a archivos separados. Mantenga los datos separados del modelo, mejore la legibilidad del modelo y haga más fácil el mantenimiento de los datos.
El modelo que está creando en esta sesión tiene múltiples índices, producto, mes y planta , y vectores de datos tal como la demanda, que es bidemensional y puede ser movido a un archivo de datos separado. En el modelo, en lugar de listar todos los elementos para el vector de datos, puede usar la palabra clave DATAFILE y luego usar el nombre de los archivos de datos como se muestran abajo:
demand[product, month] := DATAFILE("Demand.dat");
En esta sesión, usted creará la formulación de un nuevo modelo de Planificación de la Producción que incluye múltiples plantas así como períodos múltiples, los cuales fueron presentados en la sesión 4. Lo que usted quiere, es decidir cuánto producir de cada producto, para cada mes, en cada planta, así como cuánto almacenar y cuánto vender, para cada mes, en cada planta.
En este nuevo problema tendrá cuatro diferentes plantas p1, p2, p3, and p4. Cualquiera de esas plantas puede producir los tres productos. Cree un índice llamado plants(Plantas) que contiene las cuatro diferentes plantas, y luego actualice el modelo de acuerdo a como vaya agregando al índice los vectores aplicables.
Como en la sesión previa, los precios de venta permanecen iguales para cada producto $120.00, $100.00, y $150.00, respectivamente. La demanda de los productos también permanecen iguales como en la sesión previa. Refiérase a la tabla de demanda en la Sesión 3 para los datos necesarios.
Ahora que tiene múltiples plantas, los costos de producción son diferentes para cada planta. Estos datos se presentan en la tabla de abajo.
Production Cost | A1 | A2 | A3 |
---|---|---|---|
plant 1 | $73.30 | $52.90 | $65.40 |
plant 2 | $79.00 | $52.00 | $66.80 |
plant 3 | $75.80 | $52.10 | $50.90 |
plant 4 | $82.70 | $63.30 | $53.80 |
The production rate for each product is also different for each plant as shown in the table below:
Production Rate | A1 | A2 | A3 |
---|---|---|---|
plant 1 | 500 | 450 | 450 |
plant 2 | 550 | 450 | 300 |
plant 3 | 450 | 350 | 300 |
plant 4 | 550 | 400 | 350 |
El listado de abajo es el modelo completo de la formulación para Planning 5 . Los agregados al modelo son resaltados en negritas para hacerle más fácil ver los cambios con respecto al modelo de la sesión 4.
TITLE Production_Planning5; INDEX product := (A1, A2, A3); month := (Jan, Feb, Mar, Apr); plant := (p1, p2, p3, p4); DATA Price[product] := (120.00, 100.00, 115.00); Demand[product, month] := DATAFILE("Demand.dat"); ProdCost[plant, product] := DATAFILE("ProdCost.dat"); ProdRate[plant, product] := DATAFILE("ProdRate.dat"); ProdDaysAvail[month] := (23, 20, 23, 22); InvtCost[product] := (3.50, 4.00, 3.00); InvtCapacity := 800; VARIABLES Produce[plant, product, month] -> Prod; Inventory[product, month] -> Invt; Sales[product, month] -> Sale; MACROS TotalRevenue := SUM(product, month: Price * Sales); TotalProdCost := SUM(plant, product, month: ProdCost * Produce); TotalInvtCost := SUM(product, month: InvtCost * Inventory); TotalCost := TotalProdCost + TotalInvtCost; MODEL MAX Profit = TotalRevenue - TotalCost; SUBJECT TO ProdCapacity[plant, month] -> PCap: SUM(product: Produce / ProdRate) <= ProdDaysAvail; InvtBal[product, month] -> IBal: SUM(plant: Produce) + Inventory[month-1] = Sales + Inventory; MaxInventory[month] -> MaxI: SUM(product: Inventory) <= InvtCapacity; BOUNDS Sales <= Demand; END
Inicie la aplicación MPL.
Elija File (Archivo) | Open ( Abrir) y abra el modelo de la sesión previa Planning4.mpl.
Elija File (Archivo) | Save As (Guardar Como) para guardar el nuevo modelo Planning5.mpl.
Cambie el Título del modelo para que se refleje que usted trabajando con el modelo Planning5:
TITLE Production_Planning5;
En este ejemplo, tiene cuatro localizaciones de planta diferentes. Cree un nuevo índice al que llamará plant (planta). Este índice tendrá cuatro elementos p1, p2, p3, y p4 para representar cada período de los cuatro meses planificados como períodos. Agregue la siguiente definición para el índice plant (planta) a la sección INDEX (INDICE):
INDEX product := (A1, A2, A3); month := (Jan, Feb, Mar, Apr); plant := (p1, p2, p3, p4);
En esta sesión, moverá los valores de los datos del vector de datos bidimensional al archivo externo de datos. Cuando se trabaja con vectores de datos que tienen dos dimensiones o más, a menudo es buena idea mover los valores de los datos a un archivo externo de datos en lugar de listar todos los números directamente en el archivo del modelo. Esto mantiene los datos separados del modelo, mejorando la legibilidad del modelo, y hace más fácil el mantenimeinto de los datos.
El primer vector de datos que usted quiere mover a un archivo externos de datos es el vector Demand. En la sección DATA (DATOS), use el comando Cut (Cortar) del menú Edit para remover la lista de los números para el vector demanda y luego ingrese la palabra clave DATAFILE (Archivo de Datos) y el archivo Demand.dat se colocará como sigue:
DATA Price[product] := (120.00, 100.00, 115.00); Demand[product, month] := DATAFILE("Demand.dat");
El próximo paso es crear el archivo de datos Demand.dat. Primero, abra una nueva ventana del editor del modelo eligiendo New (Nuevo) en el menú File (Archivo). Sí usted usó el comando Edit (Editar) | Cut(Cortar) en el Paso 4 anterior para retirar los valores de datos, ahora puede usar el comando Edit(Editar) | Paste(Pegar) para colocar nuevamente los datos dentro del archivo de datos. De otra manera, usted puede usar la tabla de datos de la demanda de la descripción del problema en la sesión 3 para ingresar los valores de los datos dentro del archivo de datos como sigue:
! Demand.dat - Demand per month for each product ! ! Demand[product,month]: ! ! Jan Feb Mar Apr ! ---------------------------- 4300, 4200, 6400, 5300, 4500, 5400, 6500, 7200, 5400, 6700, 7800, 8200
Las líneas que empiezan con marcas de exclamación " ! "son comentarios usados para mejorar su lectura. Los números en el archivo de datos pueden ser separados por una coma o espacio o ambos. Después que ha ingresado todos los datos guarde el archivo como Demand.dat en el folder del tutor.
Dos de los Vectores de Datos, ProdCost y ProdRate, necesitan aumentarse para incluir el índice plant. El vector de datos ProdCost es definido ahora por dos índices dominio, plant (planta) y product (producto) y los valores de los datos serán obtenidos desde un archivo de datos externo. Los valores del vector de datos ProdRate también se obtendrán desde un archivo de datos. En el editor del modelo, agregue el índice, plant, para ambas declaraciones de los vectores de datos ProdCost y ProdRate, y siga con los nombres de archivos de datos ProdCost.dat y ProdRate.dat respectivamente como sigue:
ProdCost[plant, product] := DATAFILE("ProdCost.dat"); ProdRate[plant, product] := DATAFILE("ProdRate.dat"); ProdDaysAvail[month] := (23, 20, 23, 22); InvtCost[product] := (3.50, 4.00 3.00); InvtCapacity := 800;
Ahora abra una nueva ventana del editor seleccionando en el menú File(Archivo) | New(Nuevo) para ingresar el archivo de datos. Escriba los datos desde la tabla Production Cost en la descripción del problema como sigue:
! ! ProdRate.dat - Items produced per day ! ! ProdRate[plant, product]: ! ! A1 A2 A3 ! ------------------ 500, 450, 450, 550, 450, 300, 450, 350, 300, 550, 400, 350
Otra vez, las líneas que empiezan con las marcas de exclamación "!", son comentarios usados para facilitar su lectura. Después que ha ingresado todos los datos, guarde el archivo usando el nombre ProdCost.dat.
Para la tasa de producción cree un nuevo archivo de datos llamado ProdRate.dat, usando los valores de la tabla en la descripción del problema.
! ! ProdRate.dat - Items produced per day ! ! ProdRate[plant, product]: ! ! A1 A2 A3 ! ------------------ 500, 450, 450, 550, 450, 300, 450, 350, 300, 550, 400, 350
Para determinar cuánto quiere producir de cada producto, en cada planta, usted necesita agregar el índice plant (planta) a la definición del vector de la variable Produce (producción) como sigue:
VARIABLES Produce[plant, product, month] -> Prod; Inventory[product, month] -> Invt; Sales[product, month] -> Sale;
Puesto que la variable vector Produce(producción) ahora incluye el nuevo índice plant, el cálculo del costo total de producción en la sección MACROS necesita también ser actualizada para incluir el índice plant:
MACROS TotalRevenue := SUM(product, month: Price * Sales); TotalProdCost := SUM(plant, product, month: ProdCost * Produce) ; TotalInvtCost := SUM(product, month: InvtCost * Inventory); TotalCost := TotalProdCost + TotalInvtCost;
La función objetivo no cambia por si misma cuando usted está usando la misma macro de la sesión anterior.
El cambio para la restricción capacidad de producción es muy sencilla. Agregue el índice plant a la declaración de la capacidad de producción y el resto de la restricción permanece igual.
SUBJECT TO ProdCapacity[plant, month] -> PCap: SUM(product: Produce / ProdRate) <= ProdDaysAvail;
Ahora usted puede producir los productos en cualquiera de las cuatro plantas, además, usted necesita actualizar la restricción de equilibrio del inventario para incluir una sumatoria, sobre todas las plantas, de la variable vector Produce.
InvtBal[product, month] -> IBal: SUM(plant: Produce) + Inventory[month-1] = Sales + Inventory;
Después que ha terminado de ingresar el modelo, usted debe guardarlo eligiendo Save(Guardar) del menú File(Archivo).
Puesto que hemos agregado más índices al modelo, el número de variables ha incrementado considerablemente. Normalmente, cuando se trabaja con modelos grandes, el modelador quiere incluir solo algunos de los valores en la solución. En nuestro caso, para reducir el resultado, incluiremos solo las variables que tienen valor en la solución diferentes de cero. MPL tiene un número de cuadro de diálogos de opciones en el menú Options (Opciones) donde usted puede cambiar los parámetros pre establecidos del programa. Uno de los cuadros de diálogo es el Solution File Options (Opciones del Archivo de Soluciones) donde usted puede ajustar lo que está incluído en el archivo de la solución. Para cambiar lo pre establecido, tal que incluya solo valores diferentes de cero en el archivo de la solución, haga lo siguiente:
Del menú Options(Opciones) elija Solution File(Archivo de Soluciones) para abrir el cuadro de diálogo Options mostrado abajo:
Cuadro de Diálogo Opciones del Archivo de soluciones
Marque la opción Nonzero Values Only (Solo valores diferentes de cero) haciendo Click sobre él.
Cierre el Cuadro de Diálogo, presionando el botón OK.
Después que ha cambiado la opción Nonzero Values Only (Solo Valores diferentes de cero) , el próximo paso es resolver el modelo eligiendo Solve CPLEX del menú Run (Ejecutar). Si todo está bien MPL visualizará el mensaje "Optimal Solution Found"(Solución Optima Encontrada). Si hubiera algún mensaje de error de sintáxis, por favor verifique la formulación del modelo ingresada anteriormente en esta sesión.
Como los modelos que está trabajando serán muy grandes, usted tenderá a ver ciertas partes de la solución en lugar del archivo completo de la solución. Esta vez, en lugar de listar el archivo completo de la solución, estaremos usando la ventana del árbol de definiciones del modelo para ver solo las partes de la solución que nos interesa.
La ventana de definiciones del modelo le permite ver todos los items definidos en la formulación del modelo en un árbol jerárquico donde cada rama corresponde a la sección en el modelo. En MPL normalmente es una buena idea dejar la ventana de árbol abierta todo el tiempo. MPL actualizará automáticamente su contenido cada vez que usted guarda su modelo. Para ver las definiciones del modelo Planning5, elija Model Definitions (Definiciones del Modelo) del menú View(Ver).
Ventana Definiciones del Modelo para el modelo Planning5 model
Desde la ventana de árbol usted puede seleccionar alguno de los items definidos en el modelo para ver sus valores actuales de ese item. Por ejemplo, para ver los valores de la variable Produce, haga doble click sobre el item Produce en el árbol, o seleccionelo y presione el botón View(Ver). Esto visualizará una ventana conteniendo solo los valores de la variable Produce(Producción).
VARIABLE Produce[plant,product,month] : plant product month Activity Reduced Cost ----------------------------------------------------------- p1 A1 Jan 4300.0000 0.0000 p1 A1 Feb 4200.0000 0.0000 p1 A1 Mar 6400.0000 0.0000 p1 A1 Apr 5300.0000 0.0000 p2 A2 Jan 4500.0000 0.0000 p2 A2 Feb 5400.0000 0.0000 p2 A2 Mar 6500.0000 0.0000 p2 A2 Apr 7200.0000 0.0000 p3 A3 Jan 5400.0000 0.0000 p3 A3 Feb 6000.0000 0.0000 p3 A3 Mar 6900.0000 0.0000 p3 A3 Apr 6600.0000 0.0000 p4 A3 Feb 700.0000 0.0000 p4 A3 Mar 900.0000 0.0000 p4 A3 Apr 1600.0000 0.0000 -----------------------------------------------------------
Sí usted está mirando los valores de las actividades para la variable Produce (Producción), verá que esta vez estamos satisfaciendo la demanda para todos los productos, puesto que ahora tenemos suficiente capacidad. El modelo decide qué plantas y para qué productos son usadas. Por ejemplo, la planta p1 es usada para producir el producto A1, la planta p2 es usada para el producto A2, y la planta p3 y p4 son usadas para el producto A3.
Sí usted va a la ventana de árbol otra vez y abre una ventana para la restricción ProdCapacity usted obtendrá los siguientes valores como solución.
CONSTRAINT ProdCapacity[plant,month] : plant month Slack Shadow Price -------------------------------------------------- p1 Jan 14.4000 0.0000 p1 Feb 11.6000 0.0000 p1 Mar 10.2000 0.0000 p1 Apr 11.4000 0.0000 p2 Feb 8.0000 0.0000 p2 Mar 8.5556 0.0000 p2 Apr 6.0000 0.0000 p3 Jan 5.0000 0.0000 p4 Jan 23.0000 0.0000 p4 Feb 18.0000 0.0000 p4 Mar 20.4286 0.0000 p4 Apr 17.4286 0.0000 --------------------------------------------------
Aquí hay mucha holgura para cada planta y cada mes en la restricción de la capacidad de producción. Esto puede ser interpretado como que nosotros podemos producir una cantidad más de los productos, pero ello no es necesario cuando ya estamos satisfaciendo la demanda. Puesto que la restricción de la capacidad de la producción usa los días de producción como una unidad de medida, los valores de holgura representan cuántos días por mes cada una de las plantas está inactiva u ociosa.