← Volver al blog

Optimization with Python (SciPy)

Resolver un problema de optimización con restricciones en Python usando scipy.optimize.minimize. El ejemplo clásico: encontrar el punto más cercano al centro \((5, 5)\) dentro de un polígono definido por inecuaciones lineales.

\[\begin{aligned} \text{Minimizar: } \quad & f(x, y) = (x - 5)^2 + (y - 5)^2 \\[4pt] \text{Sujeto a: } \quad & x + y \le 8 \\ & -x + y \le 1 \\ & x - y \le 1 \\ & 2x + y \le 12 \\ & x \ge 0,\quad y \ge 0 \end{aligned}\]
import numpy as np
from scipy.optimize import minimize

#Objective Function
f = lambda x: (x[0] - 5)**2 + (x[1] - 5)**2

#Constraints
cons = [
    {'type': 'ineq', 'fun': lambda x: -x[0] - x[1] + 8},
    {'type': 'ineq', 'fun': lambda x:  x[0] - x[1] + 1},
    {'type': 'ineq', 'fun': lambda x: -x[0] + x[1] + 1},
    {'type': 'ineq', 'fun': lambda x: -2*x[0] - x[1] + 12},
]

#Bounds
bnds = ((0, None), (0, None))

#Starting point to find the minimum
x0 = np.array([1.0, 1.0])

#Minimize
result = minimize(f, x0, bounds=bnds, constraints=cons)

#Show the point that minimizes the Objective Function
print(f"The minimum point is: {result.x}")

Ejecutando obtenemos:

The minimum point is: [4. 4.]

El óptimo vive en la intersección de dos restricciones activas (\(x + y = 8\) y \(2x + y = 12\)), que es el punto del polígono factible más cercano al centro \((5, 5)\) del objetivo cuadrático.

Feasible region + objective contours

Cómo leer el gráfico: la región celeste es el espacio factible (todos los puntos que cumplen las 6 restricciones). Las curvas grises son isocontornos de la función objetivo — círculos concéntricos alrededor de \((5,5)\). La solución es el punto del polígono que toca el contorno más pequeño posible, marcado con la estrella roja.

Observaciones prácticas:

  • scipy.optimize.minimize convierte automáticamente todas las inecuaciones ineq al formato \(g(x) \ge 0\), por eso en el código aparecen negadas respecto al enunciado original.
  • Para problemas lineales puros es más eficiente scipy.optimize.linprog; minimize con SLSQP es adecuado cuando la función objetivo es no lineal (como aquí, que es cuadrática).
  • Si el problema crece en dimensión o tiene miles de restricciones, conviene mirar cvxpy — permite escribir el modelo casi igual al enunciado matemático.

Instalación:

pip install numpy scipy
← Volver al blog