1 Diseño de Mezclas

Un problema típico de investigación de operaciones es el diseño de mezclas, en el cual normalmente la función objetivo se enfoca en minimizar los costos de producción de la mezcla optimizando las proporciones de las características de interés contenidas en los ingredientes de la misma, para ejemplificar este caso, modelaremos el problema 2.2-2 del libro de Investigación de Operaciones de Hamdy A. Taha, mismo que se encuentra en la página 18 de dicho documento, el cual a la letra dice:

En Granjas Modelo se usa diariamente un mínimo de 800 libras de un alimento especial, que es una mezcla de maíz y soya, la información referente a los contenidos de proteína y fibra, en libras por cada libra de alimento, se muestra en la siguiente tabla (A.Taha, 2004):

Alimento Proteínas Fibras Costo(\(\frac{\$}{lb}\))
Maíz 0.09 0.02 0.3
Soya 0.6 0.06 0.9

Las necesidades dietéticas del alimento especial son un mínimo de 30% de proteínas y un máximo de 5% de fibras. Granjas Modelo desea determinar las proporciones de alimento que produzcan un costo diario máximo.

1.1 Modelado Matemático

Comenzaremos definiendo el conjunto de índices con que se modelarán las variables de decisión, para este caso, lo que debe programarse son las libras de los ingredientes tal que se cumplan con los requerimientos nutricionales y se genere un costo mínimo; para el caso de análisis, son dos ingredientes, por lo tanto se requiere que el número de índices del conjunto sea de medida 2, quedando definidos de la siguiente manera:

\[I=\{i|1,2\}\]

Para establecer entonces las variables de decisión, es importante resaltar que el tipo de variable a utilizar es una de tipo continuo, dado que el limitar a unidades enteras las libras de ingredientes pudiera provocar que no se encuentre una solución óptima y factible; por lo que las variables de decisión de fijarán se la siguiente manera:

\[{x_i}=~Libras~del~ingrediente~i,~i=1,2\]

Donde el índice 1 corresponde a las libras de maíz y el índice 2 a las libras de soya.
Para fijar la función objetivo en términos de las variables de decisión, debemos considerar los costos reportados en la tabla de datos, los cuales son unitarios dado que se reportan como \(\frac{\$}{libra}\), y al ser multiplicados por las libras de alimento, solo se mantienen las unidades monetarias, lo que es congruente con el objetivo del problema.
La función objetivo queda definida de la siguiente manera:

\[Min~z=0.3{x_1}+0.9{x_2}\]

Para modelar el sistema de restricciones, debe tomarse en cuenta las especificaciones del alimento; es decir, para el caso de la proteína, el almiento debe contener un mínimo de 30%, pero las unidades reportadas en la tabla de datos están dadas en \(\frac{libras_{proteína}}{libras_{ingrediente}}\), por lo que al multiplicar por las variables de decisión, que están fijadas en términos de las libras del ingrediente, se tendría como resultado las libras de proteína, y esto no sería congruente con el 30% solicitado en el problema; entonces, para modelar un porcentaje, la función que define las libras de proteína debe ser dividida entre el total de libras del alimento, quedando definida de la siguiente manera:

\[\frac{0.09{x_1}+0.6{x_2}}{x_1+x_2}~{\geq}~0.3\] Realizando un procedimiento algebraico, se reescribe la inecuación, fijándose de la siguiente manera:

\[0.09{x_1}+0.6{x_2}{\geq}{0.3({x_1}+{x_2})}\] \[-0.21{x_1}+0.3{x_2}~{\geq}~0\] Para el caso de la fibra, se procede bajo la misma lógica, quedando escrita la restricción de la siguiente manera:

\[\frac{0.02{x_1}+0.06{x_2}}{{x_1}+{x_2}}~{\leq}~{0.05}\] Se reescribe la expresión:

\[-0.03{x_1}+0.01{x_2}~{\leq}~0\] Como última restricción se fijará la cantidad de alimento producido, la cual es más de 800 libras, quedando modelado de la siguiente forma:

\[{x_1}+{x_2}~{\geq}~800\] El modelo matemático queda definido:

\[Min~z=0.3{x_1}+0.9{x_2}\] \[s.a.\] \[-0.21{x_1}+0.3{x_2}~{\geq}~0\] \[-0.03{x_1}+0.01{x_2}~{\leq}~0\] \[{x_1}+{x_2}~{\geq}~800\] \[{x_i}~{\geq}~0~\forall~i=1,2\]

1.2 Código en lenguaje R

Para resolver el planteamiento anterior, se procede bajo las siguientes líneas de comandos:

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_GM=MIPModel()%>%
  add_variable(x[i],i=1:2,type="continuous")%>%
  set_objective(0.3*x[1]+0.9*x[2],sense = "min")%>%
  add_constraint(-0.21*x[1]+0.3*x[2]>=0)%>%
  add_constraint(-0.03*x[1]+0.01*x[2]<=0)%>%
  add_constraint(x[1]+x[2]>=800)%>%
  add_constraint(x[i]>=0,i=1:2)
solucion=solve_model(modelo_GM,with_ROI(solver = "glpk",verbose=TRUE))
## <SOLVER MSG>  ----
## GLPK Simplex Optimizer, v4.65
## 5 rows, 2 columns, 8 non-zeros
##       0: obj =   0.000000000e+00 inf =   8.000e+02 (1)
##       2: obj =   4.376470588e+02 inf =   0.000e+00 (0)
## OPTIMAL LP SOLUTION FOUND
## <!SOLVER MSG> ----
objective_value(solucion)
## [1] 437.6471
get_solution(solucion,x[i])
##   variable i    value
## 1        x 1 470.5882
## 2        x 2 329.4118

1.3 Interpretación de la salida del modelo

Como resultado del proceso realizado, la sugerencia del modelo matemático es:

Variable Valor Unidades
\({x_1^*}\) 470.5882 Libras de maíz
\({x_2^*}\) 329.4118 Libras de soya
\(z^*\) $437.6471 Costo total óptimo

Es decir, que se adquieran 470.5882 libras de maíz y 329.4118 libras de soya, para realizar la mezcla asegurando los requerimientos nutricionales a un costo mínimo de $437.6471.

1.4 Solución Gráfica

f=function(x){0.3*x[1]+0.9*x[2]}
r1=function(x){-0.21*x[1]+0.3*x[2]}
r2=function(x){-0.03*x[1]+0.01*x[2]}
r3=function(x){x[1]+x[2]-800}
ngrid=250
x1=seq(0,1000,length.out = ngrid)
x2=seq(0,1000,length.out = ngrid)
x12=expand.grid(x1,x2)
col1=adjustcolor(col="blue",alpha.f = 0.1)
col2=adjustcolor(col="skyblue",alpha.f = 0.1)
col3=adjustcolor(col="purple",alpha.f = 0.1)
plot(x1,x2,type = "n",xaxs="i",yaxs="i",xlab = "Libras de maíz",ylab="Libras de soya",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)
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)
points(solucion$solution[1],solucion$solution[2],col="red",pch="+")

A.Taha, H. (2004). Investigación de operaciones (7th ed.). Pearson Education.