SciPy (izgovorjeno sai pie) je matematični paket, ki temelji na numpyju in vključuje tudi knjižnici C in Fortran. SciPy vašo interaktivno sejo Python spremeni v popolno podatkovno znanstveno okolje, kot so MATLAB, IDL, Octave, R ali SciLab.
V tem članku si bomo ogledali osnovne tehnike matematičnega programiranja – reševanje problemov pogojne optimizacije za skalarno funkcijo več spremenljivk z uporabo paketa scipy.optimize. Algoritmi neomejene optimizacije so bili že obravnavani v zadnji članek. Podrobnejšo in posodobljeno pomoč pri funkcijah scipy lahko vedno dobite z uporabo ukaza help(), Shift+Tab ali v uradna dokumentacija.
Predstavitev
Skupni vmesnik za reševanje problemov pogojne in neomejene optimizacije v paketu scipy.optimize zagotavlja funkcija minimize(). Znano pa je, da univerzalne metode za reševanje vseh problemov ni, zato je izbira ustrezne metode kot vedno na ramenih raziskovalca.
Ustrezen optimizacijski algoritem je določen z uporabo argumenta funkcije minimize(..., method="").
Za pogojno optimizacijo funkcije več spremenljivk so na voljo izvedbe naslednjih metod:
SLSQP — zaporedno kvadratno programiranje z omejitvami, Newtonova metoda za reševanje Lagrangeovega sistema. Wiki članek.
TNC - Prisekano Newtonovo omejeno, omejeno število ponovitev, dobro za nelinearne funkcije z velikim številom neodvisnih spremenljivk. Wiki članek.
L-BFGS-B — metoda ekipe Broyden–Fletcher–Goldfarb–Shanno, implementirana z zmanjšano porabo pomnilnika zaradi delnega nalaganja vektorjev iz Hessove matrike. Wiki članek, članek na Habréju.
COBYLA — Omejena optimizacija MARE z linearno aproksimacijo, omejena optimizacija z linearno aproksimacijo (brez izračuna gradienta). Wiki članek.
Glede na izbrano metodo so različno postavljeni pogoji in omejitve za rešitev problema:
predmet razreda Bounds za metode L-BFGS-B, TNC, SLSQP, trust-constr;
seznam (min, max) za iste metode L-BFGS-B, TNC, SLSQP, trust-constr;
predmet ali seznam predmetov LinearConstraint, NonlinearConstraint za metode COBYLA, SLSQP, trust-constr;
slovar ali seznam slovarjev {'type':str, 'fun':callable, 'jac':callable,opt, 'args':sequence,opt} za metode COBYLA, SLSQP.
Oris članka:
1) Razmislite o uporabi algoritma pogojne optimizacije v območju zaupanja (method=”trust-constr”) z omejitvami, določenimi kot objekti Bounds, LinearConstraint, NonlinearConstraint ;
2) Razmislite o zaporednem programiranju z uporabo metode najmanjših kvadratov (metoda = "SLSQP") z omejitvami, določenimi v obliki slovarja {'type', 'fun', 'jac', 'args'};
3) Analiziraj primer optimizacije izdelanih izdelkov na primeru spletnega studia.
Metoda pogojne optimizacije="trust-constr"
Izvedba metode trust-constr temelji na EQSQP za težave z omejitvami oblike enakosti in na TRIP za probleme z omejitvami v obliki neenačb. Obe metodi izvajata algoritma za iskanje lokalnega minimuma v območju zaupanja in sta zelo primerni za probleme velikega obsega.
Matematična formulacija problema iskanja minimuma v splošni obliki:
Za stroge omejitve enakosti je spodnja meja enaka zgornji meji .
Za enosmerno omejitev je nastavljena zgornja ali spodnja meja np.inf z ustreznim znakom.
Naj bo treba najti minimum znane Rosenbrockove funkcije dveh spremenljivk:
V tem primeru so na domeni definicije določene naslednje omejitve:
V našem primeru gre za edinstveno rešitev , za katerega veljata samo prva in četrta omejitev.
Oglejmo si omejitve od spodaj navzgor in poglejmo, kako jih lahko zapišemo v scipy.
Omejitve и definirajmo ga z uporabo objekta Bounds.
Jacobijevo matriko za omejitve je mogoče izračunati tudi z uporabo končnih razlik. Vendar v tem primeru Hessove matrike ni mogoče izračunati z uporabo končnih razlik. Hessian mora biti definiran kot funkcija ali z uporabo razreda HessianUpdateStrategy.
Druga možnost je, da sta prvi in drugi odvod funkcije, ki se optimizira, aproksimirana. Hessian se lahko na primer približa s funkcijo SR1 (kvazi-Newtonov približek). Gradient je mogoče aproksimirati s končnimi razlikami.
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 pogojne optimizacije="SLSQP"
Metoda SLSQP je zasnovana za reševanje problemov minimiziranja funkcije v obliki:
kjer je и — nizi indeksov izrazov, ki opisujejo omejitve v obliki enakosti ali neenakosti. — nizi spodnjih in zgornjih meja za področje definicije funkcije.
Linearne in nelinearne omejitve so opisane v obliki slovarjev s ključ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 ]
Primer optimizacije
V povezavi s prehodom na peto tehnološko strukturo si poglejmo optimizacijo proizvodnje na primeru spletnega studia, ki nam prinaša majhen, a stabilen dohodek. Predstavljajmo si sebe kot direktorja kuhinje, ki proizvaja tri vrste izdelkov:
x0 - prodaja ciljnih strani, od 10 tr.
x1 - korporativne spletne strani, od 20 tr.
x2 - spletne trgovine, od 30 tr.
Našo prijazno delovno ekipo sestavljajo štirje mlajši, dva srednja in en starejši. Njihov mesečni fond delovnega časa:
junij: 4 * 150 = 600 чел * час,
sredina: 2 * 150 = 300 чел * час,
senor: 150 чел * час.
Naj prvi razpoložljivi mlajši porabi (0, 1, 2) ur za razvoj in uvajanje enega mesta tipa (x10, x20, x30), srednji - (7, 15, 20), višji - (5, 10, 15 ) ure najboljšega časa v vašem življenju.
Kot vsak običajen direktor, želimo maksimirati mesečni dobiček. Prvi korak do uspeha je zapis ciljne funkcije value kot znesek dohodka od proizvedenih izdelkov na mesec:
In končno, najbolj rožnata predpostavka je, da se zaradi nizke cene in visoke kakovosti za nas nenehno vije vrsta zadovoljnih strank. Mesečne količine proizvodnje lahko izbiramo sami, na podlagi reševanja problema omejene optimizacije z scipy.optimize:
Ohlapno zaokrožimo na cela števila in izračunamo mesečno obremenitev veslačev z optimalno porazdelitvijo zmnožkov x = (8, 6, 3) :
junij: 8 * 10 + 6 * 20 + 3 * 30 = 290 чел * час;
sredina: 8 * 7 + 6 * 15 + 3 * 20 = 206 чел * час;
senor: 8 * 5 + 6 * 10 + 3 * 15 = 145 чел * час.
Zaključek: da bi direktor prejel svoj zasluženi maksimum, je optimalno ustvariti 8 ciljnih strani, 6 srednje velikih mest in 3 trgovine na mesec. V tem primeru mora starejši orati, ne da bi dvignil pogled s stroja, obremenitev srednjih bo približno 2/3, mlajših manj kot polovica.
Zaključek
Članek opisuje osnovne tehnike dela s paketom scipy.optimize, ki se uporablja za reševanje problemov pogojne minimizacije. Osebno uporabljam scipy zgolj v akademske namene, zato je navedeni primer tako komičen.
Veliko teorije in virtualnih primerov lahko najdete na primer v knjigi I. L. Akulich "Matematično programiranje v primerih in problemih." Bolj zahtevna aplikacija scipy.optimize zgraditi 3D strukturo iz nabora slik (članek na Habréju) si lahko ogledate v scipy-kuharska knjiga.
Glavni vir informacij je docs.scipy.orgtiste, ki želijo prispevati k prevodu tega in drugih razdelkov scipy Dobrodošli v GitHub.
Hvala mefistofeji za sodelovanje pri pripravi publikacije.