Un problema de programación lineal (PPL) es una situación compleja en la que el responsable debe tomar decisiones del tipo:
de modo que se cumpla con ciertas limitaciones, como:
y de manera que, tanto la función objetivo (a maximizar o minimizar), como las limitaciones se pueden escribir como ecuaciones lineales en las variables de decisión.
Una forma estándar en la que todo PPL puede escribirse es:
\[ \begin{array}{rrrrrrrrc} \text{max } z = &c_1 x_1 & + & c_2 x_2 & + & \cdots & + & c_n x_n & &\\ \text{s.a:} & & & & & & & & & \\ &a_{11} x_1 & + &a_{12} x_2 & + &\cdots & + &a_{1n} x_n & = &b_1 \\ &a_{21} x_1 & + & a_{22} x_2 & + & \cdots & + & a_{2n} x_n & = & b_2 \\ & \vdots & \vdots &\vdots & \vdots &\ddots & \vdots &\vdots & \vdots &\vdots \\ &a_{m1} x_1 & +& a_{m2} x_2 & + &\cdots & +& a_{mn} x_n & =& b_m \\ & x_1, & & x_2, & & \ldots, & & x_n & \geq & 0 \end{array} \]
donde:
La resolución “manual” de un PPL pasa por:
Se llama región factible al conjunto de valores de todas las variables de decisión que cumplen las restricciones del PPL. Se denota con la letra \(F\)
El algoritmo Simplex (George B. Dantzig, 1947) se basa en esto último. Mediante sencillas operaciones:
Existen muchas implementaciones del algoritmo simplex, y algunos permiten tratar el PPL sin estar en forma estándar, lo cual quita trabajo al usuario.
Este algoritmo no está exento de inestabilidad numérica, ya que se calculan divisiones con valores que pueden ser muy pequeños en el denominador.
simplex()
del package boot
Sirve para problemas de tamaño no muy grande (leer Nota en la ayuda
help(simplex)
). Instalar y cargar package previamente.
simplex(a, A1, b1, A2, b2, A3, b3, maxi, n.iter, eps)
a
: vector de coeficientes de la función objetivoA1
: matriz de coeficientes de las restricciones de tipo
\(\leq\) (sólo la parte de
coeficientes)b1
: vector de términos independientes de las
restricciones de tipo \(\leq\)
(correspondientes a la matriz A1
)A2
: idem con restricciones de tipo \(\geq\)b2
: idem correspondientes a la matriz
A2
A3
: idem con restricciones de tipo \(=\)b3
: idem correspondientes a la matriz
A3
maxi
: Poner a TRUE
si se desea maximizar
la función objetivo (por defecto es FALSE
)n.iter
: número máximo de iteraciones en cada fase (usa
método de dos fases)eps
: tolerancia de coma flotantesimplex
, que es una
lista con componentes (entre otras):
$soln
: solución óptima, si se alcanza. Vector con los
valores de las variables$solved
: código de terminación:
1
indica solución óptima encontrada0
indica que se ha alcanzado el número máximo de
iteraciones sin acabar-1
indica que no existe solución factible$value
: valor de la función objetivo en la solución
$soln
$val.aux
: valor de las variables artificiales en el
óptimolp()
del package lpSolve
Se trara de otra función para resolver PPLs, pero más completa pues admite variables enteras (programación entera) y variables binarias (programación 0-1). Para usarla hay que instalar y cargar el package previamente.
lp (direction, objective.in, const.mat, const.dir, const.rhs, int.vec, binary.vec)
direction
: por defecto vale 'min'
. Cambiar
a 'max'
si se quiere maximizar la función objetivoobjective.in
: vector con coeficientes de la función
objetivoconst.mat
: matriz de coeficientes de las
restriccionesconst.dir
: vector (de cadenas"<="
,
"=="
o ">="
) indicando la dirección de cada
restricción dada por las filas de la matriz const.mat
const.rhs
: vector de términos independientes de las
restriccionesint.vec
: vector indicando la posición de las variables
que deben ser de valores enterosbinary.vec
: Vector indicando la posición de las
variables que deben ser de valores binarios (0 o 1)lp
, que es una lista
con componentes (entre otras):
$objval
: valor de la función objetivo en el óptimo$solution
: solución óptima, si se alcanza. Vector con
los valores de las variables$status
: indicador numérico:
0
: éxito2
: no hay solución factible\[ \begin{array}{rl} \text{max} &x_1 + 5x_2 - x_3 \\ \text{s.a} & \\ & x_1 + x_2 + x_3 \geq 100 \\ & 5x_1 - x_2 + 8x_3 \leq 500 \\ & - x_1 + x_2 + 2x_3 = 0 \\ & 2x_1 + x_2 + 12x_3 \leq 800 \\ & x_1, x_2, x_3 \geq 0 \end{array} \] 4.1.1 Resuelve el PPL con las dos funciones de R: escribe el valor óptimo de la función objetivo y los valores de las variables de decisión que consiguen ese óptimo.
library(boot)
library(lpSolve)
# AQUÍ TU CÓDIGO
ESCRIBE LA SOLUCIÓN (VARIABLES Y SUS VALORES) Y EL VALOR ÓPTIMO ENCONTRADO, O BIEN SI NO SE ENCUENTRA, COMENTAR LO QUE HA PASADO
4.1.2 Resuelve el PPL con las dos funciones de R, SI EL OBJETIVO FUERA MINIMIZAR LA FUNCIÓN OBJETIVO (valga la redundancia)
# AQUÍ TU CÓDIGO
ESCRIBE LA SOLUCIÓN (VARIABLES Y SUS VALORES) Y EL VALOR ÓPTIMO ENCONTRADO, O BIEN SI NO SE ENCUENTRA, COMENTAR LO QUE HA PASADO
4.1.3 Resuelve (como sea posible) el PPL DE MINIMIZAR, SUPONIENDO ADEMÁS QUE LAS VARIABLES \(x_1\) Y \(x_2\) REPRESENTAN NÚMEROS DE PERSONAS, Y NO PUEDEN TOMAR VALORES NO ENTEROS.
# AQUÍ TU CÓDIGO
ESCRIBE LA SOLUCIÓN (VARIABLES Y SUS VALORES) Y EL VALOR ÓPTIMO ENCONTRADO, O BIEN SI NO SE ENCUENTRA, COMENTAR LO QUE HA PASADO
\[ \begin{array}{rl} \text{min} &15 x + 10y\\ \text{s.a} & \\ & y \leq 50 \\ & 1.5 x - y \geq 20 \\ & x_1, x_2 \geq 0 \end{array} \]
4.2.1 Resuelve el PPL con las dos funciones de R el PPL: escribe el valor óptimo de la función objetivo y los valores de las variables de decisión que consiguen ese óptimo.
# AQUÍ TU CÓDIGO
ESCRIBE LA SOLUCIÓN (VARIABLES Y SUS VALORES) Y EL VALOR ÓPTIMO ENCONTRADO, O BIEN SI NO SE ENCUENTRA, COMENTAR LO QUE HA PASADO
4.2.2 Resuelve el PPL con las dos funciones de R, SI EL OBJETIVO FUERA MAXIMIZAR LA FUNCIÓN OBJETIVO (valga la redundancia)
# AQUÍ TU CÓDIGO
ESCRIBE LA SOLUCIÓN (VARIABLES Y SUS VALORES) Y EL VALOR ÓPTIMO ENCONTRADO, O BIEN SI NO SE ENCUENTRA, COMENTAR LO QUE HA PASADO
4.2.3 Como se trata de tan solo dos variables, representa gráficamente la región factible y la curva de nivel \(z=0\) y comenta los resultados obtenidos en 4.2.1 y 4.2.2.
Ayuda: la función abline(a,b,h,v)
añade rectas a un
plot, que se pueden indicar con término independiente y pendiente
(a
, b
) o bien con la ordenada en el origen, si
es horizontal (h
) o bien con la abcisa, si es vertical
(v
).
# AQUÍ TU CÓDIGO
plot(x=0, y=0, xlim=c(0,100), ylim=c(0,100))
# LA RECTA x=0
# LA RECTA y=0
# LA RECTA y=50
# LA RECTA 1.5x-y=20
# LA CURVA DE NIVEL z=0 PARA z=15x+10y
COMENTARIO DE LOS RESULTADOS DE 4.2.1 Y 4.2.2 A PARTIR DE LA FIGURA.