SciPy (vyslovováno sai pie) je matematický balíček založený na numpy, který také obsahuje knihovny C a Fortran. SciPy promění vaši interaktivní relaci Pythonu na kompletní prostředí pro vědu o datech, jako je MATLAB, IDL, Octave, R nebo SciLab.
V tomto článku se podíváme na základní techniky matematického programování - řešení podmíněných optimalizačních problémů pro skalární funkci několika proměnných pomocí balíčku scipy.optimize. O neomezených optimalizačních algoritmech již byla řeč poslední článek. Podrobnější a aktuální nápovědu k funkcím scipy lze vždy získat pomocí příkazu help(), Shift+Tab nebo v oficiální dokumentace.
úvod
Společné rozhraní pro řešení podmíněných i neomezených optimalizačních problémů v balíčku scipy.optimize poskytuje funkce minimize(). Je však známo, že neexistuje univerzální metoda pro řešení všech problémů, takže výběr adekvátní metody jako vždy leží na bedrech výzkumníka.
Vhodný optimalizační algoritmus je specifikován pomocí argumentu funkce minimize(..., method="").
Pro podmíněnou optimalizaci funkce několika proměnných jsou k dispozici implementace následujících metod:
SLSQP — sekvenční kvadratické programování s omezeními, Newtonova metoda pro řešení Lagrangeova systému. Wiki článek.
TNC - Zkrácený Newton Constrained, omezený počet iterací, vhodný pro nelineární funkce s velkým počtem nezávislých proměnných. Wiki článek.
L-BFGS-B — metoda od týmu Broyden–Fletcher–Goldfarb–Shanno, implementovaná se sníženou spotřebou paměti díky částečnému načítání vektorů z hessovské matice. Wiki článek, článek o Habrém.
COBYLA — MARE Constrained Optimization By Linear Approximation, omezená optimalizace s lineární aproximací (bez výpočtu gradientu). Wiki článek.
V závislosti na zvolené metodě jsou podmínky a omezení pro řešení problému nastaveny odlišně:
objekt třídy Bounds pro metody L-BFGS-B, TNC, SLSQP, trust-constr;
seznam (min, max) pro stejné metody L-BFGS-B, TNC, SLSQP, trust-constr;
objekt nebo seznam objektů LinearConstraint, NonlinearConstraint pro metody COBYLA, SLSQP, trust-constr;
slovník nebo seznam slovníků {'type':str, 'fun':callable, 'jac':callable,opt, 'args':sequence,opt} pro metody COBYLA, SLSQP.
Přehled článku:
1) Zvažte použití podmíněného optimalizačního algoritmu v oblasti důvěryhodnosti (method=”trust-constr”) s omezeními určenými jako objekty Bounds, LinearConstraint, NonlinearConstraint ;
2) Zvažte sekvenční programování pomocí metody nejmenších čtverců (metoda = "SLSQP") s omezeními specifikovanými ve formě slovníku {'type', 'fun', 'jac', 'args'};
3) Analyzujte příklad optimalizace vyráběných produktů na příkladu webového studia.
Metoda podmíněné optimalizace="trust-constr"
Implementace metody trust-constr na základě EQSQP pro problémy s omezeními formy rovnosti a dále TRIP pro problémy s omezeními v podobě nerovností. Obě metody jsou implementovány pomocí algoritmů pro nalezení lokálního minima v oblasti spolehlivosti a jsou vhodné pro rozsáhlé problémy.
Matematická formulace problému hledání minima v obecné podobě:
Pro přísná omezení rovnosti je dolní mez nastavena stejně jako horní mez .
Pro jednosměrné omezení je nastavena horní nebo dolní mez np.inf s odpovídajícím znakem.
Nechť je třeba najít minimum známé Rosenbrockovy funkce dvou proměnných:
V tomto případě jsou na její definiční doménu nastavena následující omezení:
V našem případě jde o unikátní řešení , pro které platí pouze první a čtvrté omezení.
Projdeme si omezení zdola nahoru a podíváme se, jak je můžeme napsat ve scipy.
Omezení и pojďme jej definovat pomocí objektu Bounds.
Jakobiánskou matici pro omezení lze také vypočítat pomocí konečných rozdílů. V tomto případě však nelze Hessovu matici vypočítat pomocí konečných rozdílů. Hessian musí být definován jako funkce nebo pomocí třídy HessianUpdateStrategy.
Alternativně lze první a druhou derivaci funkce, která se optimalizuje, aproximovat. Pomocí funkce lze například aproximovat Hessian SR1 (kvazi-newtonská aproximace). Gradient lze aproximovat konečnými rozdíly.
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)
Metoda podmíněné optimalizace="SLSQP"
Metoda SLSQP je navržena pro řešení problémů minimalizace funkce ve tvaru:
Kde и — soubory indexů výrazů popisujících omezení ve formě rovnosti nebo nerovností. — množiny dolní a horní meze pro definiční obor funkce.
Lineární a nelineární omezení jsou popsána ve formě slovníků s klíči 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])
}
Optimization terminated successfully. (Exit mode 0)
Current function value: 0.34271757499419825
Iterations: 4
Function evaluations: 5
Gradient evaluations: 4
[0.41494475 0.1701105 ]
Příklad optimalizace
V souvislosti s přechodem na pátou technologickou strukturu se podívejme na optimalizaci výroby na příkladu webového studia, které nám přináší malý, ale stabilní příjem. Představme si sami sebe jako ředitele kuchyně, která vyrábí tři druhy produktů:
x0 - prodej vstupních stránek, od 10 tr.
x1 - firemní weby, od 20 tr.
x2 - internetové obchody, od 30 tr.
Náš přátelský pracovní tým tvoří čtyři junioři, dva střední a jeden senior. Jejich měsíční fond pracovní doby:
června: 4 * 150 = 600 чел * час,
středy: 2 * 150 = 300 чел * час,
senor: 150 чел * час.
Nechte prvního dostupného juniora strávit (0, 1, 2) hodin vývojem a nasazením jednoho webu typu (x10, x20, x30), střední - (7, 15, 20), senior - (5, 10, 15 ) hodiny nejlepšího období vašeho života.
Jako každý normální ředitel chceme maximalizovat měsíční zisky. Prvním krokem k úspěchu je zapsat si účelovou funkci value jako výše příjmu z produktů vyrobených za měsíc:
A nakonec nejrůžovějším předpokladem je, že kvůli nízké ceně a vysoké kvalitě se na nás neustále staví fronta spokojených zákazníků. Můžeme si sami zvolit měsíční objemy výroby na základě vyřešení problému s omezenou optimalizací scipy.optimize:
Volně zaokrouhleme na celá čísla a spočítejme si měsíční zátěž veslařů s optimálním rozložením produktů x = (8, 6, 3) :
června: 8 * 10 + 6 * 20 + 3 * 30 = 290 чел * час;
středy: 8 * 7 + 6 * 15 + 3 * 20 = 206 чел * час;
senor: 8 * 5 + 6 * 10 + 3 * 15 = 145 чел * час.
Závěr: aby ředitel dostal své zasloužené maximum, je optimální vytvořit 8 vstupních stránek, 6 středně velkých webů a 3 obchody měsíčně. V tomto případě musí senior orat bez zvednutí od stroje, zatížení středů bude přibližně 2/3, juniorů méně než polovina.
Závěr
Článek nastiňuje základní techniky práce s balíčkem scipy.optimize, který se používá k řešení problémů podmíněné minimalizace. Osobně používám scipy čistě pro akademické účely, a proto je uvedený příklad tak komického charakteru.
Spoustu teorie a virtuálních příkladů lze nalézt například v knize I. L. Akulicha „Matematické programování v příkladech a problémech“. Více hardcore aplikace scipy.optimize vytvořit 3D strukturu ze sady obrázků (článek o Habrém) si můžete prohlédnout v scipy-kuchařka.
Hlavním zdrojem informací je docs.scipy.orgkteří chtějí přispět k překladu této a dalších částí scipy Vítejte v GitHub.