SciPy (pronunciado sai pie) es un paquete matemático basado en numpy que también incluye bibliotecas C y Fortran. SciPy convierte su sesión interactiva de Python en un entorno completo de ciencia de datos como MATLAB, IDL, Octave, R o SciLab.
En este artículo, veremos las técnicas básicas de programación matemática: resolver problemas de optimización condicional para una función escalar de varias variables utilizando el paquete scipy.optimize. Los algoritmos de optimización sin restricciones ya se han discutido en último artículo. Siempre se puede obtener ayuda más detallada y actualizada sobre las funciones de scipy usando el comando help(), Shift+Tab o en documentación oficial.
introducción
La función proporciona una interfaz común para resolver problemas de optimización condicional y sin restricciones en el paquete scipy.optimize. minimize(). Sin embargo, se sabe que no existe un método universal para resolver todos los problemas, por lo que la elección de un método adecuado, como siempre, recae sobre los hombros del investigador.
El algoritmo de optimización apropiado se especifica utilizando el argumento de la función. minimize(..., method="").
Para la optimización condicional de una función de varias variables, se encuentran disponibles implementaciones de los siguientes métodos:
SLSQP — programación cuadrática secuencial con restricciones, método newtoniano para resolver el sistema de Lagrange. artículo wiki.
TNC - Newton truncado Restringido, número limitado de iteraciones, bueno para funciones no lineales con una gran cantidad de variables independientes. artículo wiki.
L-BFGS-B — un método del equipo Broyden–Fletcher–Goldfarb–Shanno, implementado con un consumo de memoria reducido debido a la carga parcial de vectores de la matriz de Hesse. artículo wiki, artículo sobre Habré.
COBYLA — MARE Optimización restringida por aproximación lineal, optimización restringida con aproximación lineal (sin cálculo de gradiente). artículo wiki.
Dependiendo del método elegido, las condiciones y restricciones para resolver el problema se establecen de forma diferente:
objeto de clase Bounds para métodos L-BFGS-B, TNC, SLSQP, confianza-constr;
lista (min, max) para los mismos métodos L-BFGS-B, TNC, SLSQP, trust-constr;
un objeto o una lista de objetos LinearConstraint, NonlinearConstraint para COBYLA, SLSQP, métodos de control de confianza;
diccionario o lista de diccionarios {'type':str, 'fun':callable, 'jac':callable,opt, 'args':sequence,opt} para COBYLA, métodos SLSQP.
Esquema del artículo:
1) Considere el uso de un algoritmo de optimización condicional en la región de confianza (método=”trust-constr”) con restricciones especificadas como objetos Bounds, LinearConstraint, NonlinearConstraint ;
2) Considere la programación secuencial utilizando el método de mínimos cuadrados (método = "SLSQP") con restricciones especificadas en forma de diccionario. {'type', 'fun', 'jac', 'args'};
3) Analizar un ejemplo de optimización de productos fabricados utilizando el ejemplo de un estudio web.
Método de optimización condicional="trust-constr"
Implementación del método. trust-constr Residencia en EQSQP para problemas con restricciones de la forma de igualdad y en TRIP para problemas con restricciones en forma de desigualdades. Ambos métodos se implementan mediante algoritmos para encontrar un mínimo local en la región de confianza y son muy adecuados para problemas a gran escala.
Formulación matemática del problema de encontrar un mínimo en forma general:
Para restricciones de igualdad estrictas, el límite inferior se establece igual al límite superior .
Para una restricción unidireccional, el límite superior o inferior se establece np.inf con el signo correspondiente.
Sea necesario encontrar el mínimo de una función de Rosenbrock conocida de dos variables:
En este caso, se establecen las siguientes restricciones en su dominio de definición:
En nuestro caso, existe una solución única en el punto , para lo cual sólo son válidas las restricciones primera y cuarta.
Repasemos las restricciones de abajo hacia arriba y veamos cómo podemos escribirlas en scipy.
restricciones и Definámoslo usando el objeto Bounds.
Al calcular la matriz de Hesse requiere mucho esfuerzo, puedes usar una clase HessianUpdateStrategy. Las siguientes estrategias están disponibles: BFGS и SR1.
La matriz jacobiana para restricciones también se puede calcular utilizando diferencias finitas. Sin embargo, en este caso la matriz de Hesse no se puede calcular mediante diferencias finitas. El hessiano debe definirse como una función o utilizando la clase HessianUpdateStrategy.
Alternativamente, se pueden aproximar la primera y segunda derivadas de la función que se está optimizando. Por ejemplo, el hessiano se puede aproximar usando la función SR1 (aproximación cuasi-newtoniana). El gradiente se puede aproximar mediante diferencias finitas.
from scipy.optimize import SR1
res = minimize(rosen, x0, method='trust-constr', jac="2-point", hess=SR1(),
constraints=[linear_constraint, nonlinear_constraint],
options={'verbose': 1}, bounds=bounds)
print(res.x)
Método de optimización condicional="SLSQP"
El método SLSQP está diseñado para resolver problemas de minimización de una función en la forma:
Donde и — conjuntos de índices de expresiones que describen restricciones en forma de igualdades o desigualdades. — conjuntos de límites inferior y superior para el dominio de definición de la función.
Las restricciones lineales y no lineales se describen en forma de diccionarios con claves. type, fun и jac.
ineq_cons = {'type': 'ineq',
'fun': lambda x: np.array ([1 - x [0] - 2 * x [1],
1 - x [0] ** 2 - x [1],
1 - x [0] ** 2 + x [1]]),
'jac': lambda x: np.array ([[- 1.0, -2.0],
[-2 * x [0], -1.0],
[-2 * x [0], 1.0]])
}
eq_cons = {'type': 'eq',
'fun': lambda x: np.array ([2 * x [0] + x [1] - 1]),
'jac': lambda x: np.array ([2.0, 1.0])
}
La búsqueda del mínimo se realiza de la siguiente manera:
Optimization terminated successfully. (Exit mode 0)
Current function value: 0.34271757499419825
Iterations: 4
Function evaluations: 5
Gradient evaluations: 4
[0.41494475 0.1701105 ]
Ejemplo de optimización
En relación con la transición a la quinta estructura tecnológica, consideremos la optimización de la producción en el ejemplo de un estudio web, que nos aporta unos ingresos pequeños pero estables. Imaginémonos como el director de una galera que elabora tres tipos de productos:
x0 - venta de páginas de destino, desde 10 tr.
x1 - webs corporativas, desde 20 tr.
x2 - tiendas online, desde 30 tr.
Nuestro amigable equipo de trabajo incluye cuatro juniors, dos middles y un senior. Su fondo mensual de tiempo de trabajo:
Junios: 4 * 150 = 600 чел * час,
medios: 2 * 150 = 300 чел * час,
señor: 150 чел * час.
Deje que el primer junior disponible dedique (0, 1, 2) horas al desarrollo e implementación de un sitio del tipo (x10, x20, x30), medio - (7, 15, 20), senior - (5, 10, 15 ) horas del mejor momento de tu vida.
Como cualquier director normal, queremos maximizar las ganancias mensuales. El primer paso hacia el éxito es escribir la función objetivo. value como la cantidad de ingresos de los productos producidos por mes:
Y finalmente, la suposición más optimista es que, debido al bajo precio y la alta calidad, una cola de clientes satisfechos hace cola constantemente para recibirnos. Podemos elegir nosotros mismos los volúmenes de producción mensual, basándonos en resolver el problema de optimización restringida con scipy.optimize:
Redondeemos libremente a números enteros y calculemos la carga mensual de remeros con una distribución óptima de productos. x = (8, 6, 3) :
Junios: 8 * 10 + 6 * 20 + 3 * 30 = 290 чел * час;
medios: 8 * 7 + 6 * 15 + 3 * 20 = 206 чел * час;
señor: 8 * 5 + 6 * 10 + 3 * 15 = 145 чел * час.
Conclusión: para que el director reciba su merecido máximo, lo óptimo es crear 8 páginas de destino, 6 sitios medianos y 3 tiendas por mes. En este caso, el mayor debe arar sin levantar la vista de la máquina, la carga de los medianos será aproximadamente 2/3, los jóvenes menos de la mitad.
Conclusión
El artículo describe las técnicas básicas para trabajar con el paquete. scipy.optimize, utilizado para resolver problemas de minimización condicional. Personalmente uso scipy con fines puramente académicos, por lo que el ejemplo dado tiene un carácter tan cómico.
Se pueden encontrar muchas teorías y ejemplos virtuales, por ejemplo, en el libro de I. L. Akulich "Programación matemática en ejemplos y problemas". Aplicación más dura scipy.optimize para construir una estructura 3D a partir de un conjunto de imágenes (artículo sobre Habré) se puede ver en libro de cocina picante.
La principal fuente de información es docs.scipy.orgaquellos que deseen contribuir a la traducción de esta y otras secciones scipy Bienvenido a GitHub.
Gracias mefistófeles por participar en la preparación de la publicación.