Problema de programación lineal a partir de inecuaciones

Se resuelve un problema tipo de programación lineal en el que se pide que se obtenga el máximo y mínimo de la función objetivo en una región convexa acotada del plano. Con el fichero LyX/pythontex y las librerías sympy y Sympy Plotting Backends’s de python podemos resolver cualquier problema a partir de introducir los puntos que determinan la región convexa o bien obtener estos de forma aleatoria estableciendo solo el número de puntos que deseemos.

Existen librerías de python que permiten resolver este tipo de cuestiones, por ejemplo linprog de scipy, pero mi intención no es tanto el de obtener la solución como el de ejemplificar todo el proceso seguido para hacer el ejercicio. Como he comentado, está resuelto solo para regiones convexas del plano acotadas.

Para que las tablas de valores de las rectas ajusten bien las alturas de las filas, en vez de usar un entorno tabular de LaTeX se usa el entorno tblr del paquete tabularray.

Creo que merece la pena destacar la nota que se pone cuando se definen las variables de sympy:

#Es importante poner real=True para que no use símbolos diferentes
#para el paquete Geometry de los símbolos de las funciones.
x,y=symbols('x y',real=True)

La cuestión reside en que si no ponemos real=True y las definimos como siempre, los símbolos \(x\) e \(y\) que aparecen en la inecuaciones/rectas y demás elementos geométricos que genera el módulo geometry son distintos de los símbolos que, por ejemplo, usamos en la función objetivo (aunque aparentemente sean los mismos).

Para que matploblib cambie el tamaño de las fuentes de las leyendas se introduce al inicio del fichero el código:

#Para controlar el tamaño de las fuentes en las leyendas
import matplotlib.pyplot as plt
plt.rc('legend',fontsize=5) # tamaño en puntos

En el código del programa se detecta si los puntos determinan una región convexa acotada y en caso contrario no permite encontrar la solución, para ello se hace uso de la función convex_hull del módulo Geometry de sympy, con ella podemos determinar la envolvente convexa de una serie de puntos.

Podemos modificar la forma de trabajar del fichero que podemos descargar al final del artículo a partir de las variables:

#Para tener un polígono convexo el número de puntos deber ser mayor o igual que 3
#Se sobreescribe este valor si optamos por puntos "a mano"
np=5

# Valores mínimos y máximos para las coordenadas aleatorias de los puntos.
# Sí el número de puntos pasa de 5 o 6 habría que aumentar estos valores
#para que se puedan encontar con más facilidad polígonos convexos aleatorios
#entre ellos
vm=-3
vM=7

#Amplitud extra para representar los ejes de las rectas y las inecuaciones
amp=1

#Amplitud extra para representar los ejes del gráfico solución final
am=1

#Función objetivo
FO=2*x+3*y

#Valores mínimos y máximos para tabla de valores de las rectas
ntv0=-1
ntv1=4

#Puede ser aleatorio o manual, si no se pone "m" es aleatorio
tipo="a"

Solo comentare lo más significativo. Con:

np
establecemos el número de puntos, que se obtendrán de forma aleatoria, y a partir de ellos se construyen las inecuaciones que delimitan la región convexa.
vm y vM
se explica en el propio código, en el caso de optar por puntos aleatorios se obtendrán sus coordenadas entre esos valores.
FO
función objetivo a minimizar/maximizar
tipo

si optamos por no poner \(m\) se hace de forma aleatoria, si se opta por \(m\) debemos poner a mano nuestros puntos en

if tipo=="m":
    #Podemos optar por poner los puntos de forma manual
    Puntos=[Point(2,6),Point(4,1),Point(5,5),Point(1,3)]
...

añadiendo puntos en ese formato o modificando los valores que se ponen por defecto.

Todos los elementos que aparecen al compilar el fichero (inecuaciones, tablas de valores, gráficos, …) se construyen de forma dinámica a partir de los valores iniciales anteriormente comentados. En el código se detectan las ecuaciones paralelas a los ejes y se adecúa la forma de actuar con ellas a la hora de obtener sus tablas de valores o para resolver los sistemas de ecuaciones así como el caso de que el máximo o mínimo de la función objetivo se alcance en dos vértices.

El ejemplo del enunciado que hay por defecto en la plantilla optando por la opción de \(m\) es:

Ejercicio

  1. Representa el recinto limitado por las siguientes restricciones, calculando sus vértices:

    \(2x+3y-11\geq0\),     \(-4x+y+15\geq0\), \(-x-3y+20\geq0\),     \(-3x+y\leq0\)

  2. Halla los puntos de esta región donde la función \(F(x,y)=2x+3y\) alcanza los valores máximo y mínimo, calculando dichos valores.

La solución que se obtiene al compilar el fichero LyX para ese enunciado es similar a los gráficos:

image1

image2

image3

image4