Se tomará como base para explicar el proceso de modelado matemático
el ejemplo 2.1-1 de la página 12 del libro de Investigación de
Operaciones de Hamdy A. Taha (A.Taha,
2004), el cual se enuncia a continuación:
Resddy Mikks produce pintura para interiores y exteriores, \(M1\) y \(M2\). La tabla siguiente proporciona los
datos básicos del problema, expresados en toneladas.
| Pintura para exteriores | Pintura para interiores | Disponibilidad diaria máxima | |
|---|---|---|---|
| Materia prima M1 | 6 | 4 | 24 |
| Materia prima M2 | 1 | 2 | 6 |
| Utilidad por ton (x1000) | 5 | 4 |
Una encuesta de mercado indica que la demanda máxima diaria de pintura para interiores no puede ser mayor que una tonelada más que la pintura para exteriores. También, que la demanda máxima diaria de pintura para interiores es de 2 toneladas.
Reddy Miks desea determinar la mezcla óptima de productos para exteriores y para interiores tal que meximice la utilidad diaria total.
Comenzaremos el modelado matemático definiendo los conjuntos de los índices de las variables que se van a autilizar en el modelo matemático, aquí se deben enumerar los índices necesarios para poderlos asociar a las variables de decisión, en este caso, el número de variables necesarias para establecer las expresiones matemáticas es 2, dado que es el número de productos a programar, se establecen los conjuntos de la siguiente manera:
\[I=\{i:1,2\}\]
Una vez definido el conjunto de índice, procedemos a definir las variables de decisión, con ayuda de los índices, es importante en esta etapa ser claros tanto en la definición de la variable como en las unidades de medida. En este caso, las variables de decisión se definen de la siguiente manera:
\[{x_i}=~Toneladas~de~Pintura~i,~i=1,2\] \[1=~Pintura~para~exteriores\] \[2=~Pintura~para~interiores\]
Ya teniendo definidas las variables de decisión, procedemos a establecer la función objetivo, misma que debe estar en congruencia con las unidades del problema. Para el caso que estamos analizando, las unidades monetarias de la utilidad están asociadas a la cantidad de unidades a producir, es decir, por ejemplo, para el caso de la pintura para exteriores, tendríamos \(\$ 5000/toneladas~de~pintura~para~exteriores\), por lo que, se debe multiplicar por la cantidad de toneladas de pintura de esa misma clase para obtener solamente unidades monetarias, por lo que la función objetivo queda definida de la siguiente manera:
\[z=5{x_1}+4{x_2}\]
Como lo que se busca es obtener las utilidades máximas, entonces, reescribimos la funcion objetivo de la siguiente manera:
\[Max~z=5{x_1}+4{x_2}\]
Para el caso del sistema de restricciones, se procede de la misma manera, dejando siempre en claro que el modelo debe ser congruente, es decir, las unidades del vector de los coeficientes tecnológicos debe estar alineada con las de los coeficientes del sistema de restricciones multiplicados por las variables de decisión, por ejemplo, los requerimientos de materia prima \(M1\) para la pintura para exteriores son \(6~toneladas~de~materia~prima~M1/toneladas\), por lo que, al multiplicar este coeficiente por la cantidad de toneladas a producir, las unidades quedan alineadas a la disponibilidad diaria máxima de materia prima \(M1\).
Habiendo definido lo anterior, el sistema de restricciones queda escrito de la siguiente manera:
\[6{x_1}+4{x_2}~\leq~24\]
\[{x_1}+2{x_2}~\leq~6\]
\[-{x_1}+{x_2}~\leq~1\] \[{x_2}~\leq~2\] \[{x_2}~\geq~0~\forall~i=1,2\]
Ahora procederemos a codificar el modelo matemático en R, utilizando las librerías ROI,ROI.plugin.glpk,ompr,ompr.roi.dplyr, éstas nos ayudarán a resolver el modelo matemático, el código a utilizar se muestra a continuación:
library(ROI)
## ROI: R Optimization Infrastructure
## Registered solver plugins: nlminb, glpk, symphony.
## Default solver: auto.
library(ROI.plugin.glpk)
library(ompr)
library(ompr.roi)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
modelo=MIPModel()%>%
add_variable(x[i],i=1:2,type="continuous")%>%
set_objective(5*x[1]+4*x[2],sense = "max")%>%
add_constraint(6*x[1]+4*x[2]<=24)%>%
add_constraint(x[1]+2*x[2]<=6)%>%
add_constraint(-x[1]+x[2]<=1)%>%
add_constraint(x[2]<=2)%>%
add_constraint(x[i]>=0,i=1:2)
solucion=solve_model(modelo,with_ROI(solver="glpk",verbose=TRUE))
## <SOLVER MSG> ----
## GLPK Simplex Optimizer, v4.65
## 6 rows, 2 columns, 9 non-zeros
## * 0: obj = -0.000000000e+00 inf = 0.000e+00 (2)
## * 2: obj = 2.100000000e+01 inf = 0.000e+00 (0)
## OPTIMAL LP SOLUTION FOUND
## <!SOLVER MSG> ----
print(solucion$objective_value)
## [1] 21
get_solution(solucion,x[i])
## variable i value
## 1 x 1 3.0
## 2 x 2 1.5
f=function(x){5*x[1]+4*x[2]}
r1=function(x){6*x[1]+4*x[2]-24}
r2=function(x){x[1]+2*x[2]-6}
r3=function(x){-x[1]+x[2]-1}
r4=function(x){x[2]-2}
ngrid=250
x1=seq(0,6,length.out = ngrid)
x2=seq(0,6,length.out = ngrid)
x12=expand.grid(x1,x2)
col1=adjustcolor(col="blue",alpha.f = 0.5)
col2=adjustcolor(col="skyblue",alpha.f = 0.5)
col3=adjustcolor(col="purple",alpha.f = 0.5)
col4=adjustcolor(col="green",alpha.f = 0.5)
plot(x1,x2,type = "n",xaxs="i",yaxs="i",xlab = "Pintura para exteriores",ylab="Pintura para interiores",main="Espacio de soluciones")
contour(x1,x2,matrix(apply(x12,1,f),ngrid,ngrid),nlevels = 5,add=TRUE)
contour(x1,x2,matrix(apply(x12,1,r1),ngrid,ngrid),nlevels =1,add=TRUE)
contour(x1,x2,matrix(apply(x12,1,r2),ngrid,ngrid),nlevels =1,add=TRUE)
contour(x1,x2,matrix(apply(x12,1,r3),ngrid,ngrid),nlevels =1,add=TRUE)
contour(x1,x2,matrix(apply(x12,1,r4),ngrid,ngrid),nlevels =1,add=TRUE)
image(x1,x2,matrix(ifelse(apply(x12,1,r1)<=0,0,NA),ngrid,ngrid),col=col1,add = TRUE)
image(x1,x2,matrix(ifelse(apply(x12,1,r2)<=0,0,NA),ngrid,ngrid),col=col2,add = TRUE)
image(x1,x2,matrix(ifelse(apply(x12,1,r3)<=0,0,NA),ngrid,ngrid),col=col3,add = TRUE)
image(x1,x2,matrix(ifelse(apply(x12,1,r4)<=0,0,NA),ngrid,ngrid),col=col4,add = TRUE)
points(solucion$solution[1],solucion$solution[2],col="red",pch=5)