
Mae SciPy (sai pie wedi'i ynganu) yn becyn mathemateg sy'n seiliedig ar numpy sydd hefyd yn cynnwys llyfrgelloedd C a Fortran. Mae SciPy yn troi eich sesiwn Python rhyngweithiol yn amgylchedd gwyddor data cyflawn fel MATLAB, IDL, Octave, R, neu SciLab.
Yn yr erthygl hon, byddwn yn edrych ar dechnegau sylfaenol rhaglennu mathemategol - datrys problemau optimization amodol ar gyfer swyddogaeth sgalar o sawl newidyn gan ddefnyddio'r pecyn scipy.optimize. Mae algorithmau optimeiddio anghyfyngedig eisoes wedi'u trafod yn . Gellir cael cymorth mwy manwl a chyfredol ar ffwythiannau scipy drwy ddefnyddio'r gorchymyn help(), Shift+Tab neu yn .
Cyflwyniad
Darperir rhyngwyneb cyffredin ar gyfer datrys problemau optimeiddio amodol a heb gyfyngiad yn y pecyn scipy.optimize gan y swyddogaeth minimize(). Fodd bynnag, mae'n hysbys nad oes dull cyffredinol ar gyfer datrys pob problem, felly mae'r dewis o ddull digonol, fel bob amser, yn disgyn ar ysgwyddau'r ymchwilydd.
Mae'r algorithm optimeiddio priodol wedi'i nodi gan ddefnyddio'r ddadl swyddogaeth minimize(..., method="").
Er mwyn optimeiddio swyddogaeth sawl newidyn yn amodol, mae gweithrediadau o'r dulliau canlynol ar gael:
trust-constr— chwilio am isafswm lleol yn y rhanbarth hyder. , ;SLSQP— rhaglennu cwadratig dilyniannol gyda chyfyngiadau, dull Newtonaidd ar gyfer datrys system Lagrange. .TNC- Newton cwtogi Nifer cyfyngedig o iteriadau, yn dda ar gyfer swyddogaethau aflinol gyda nifer fawr o newidynnau annibynnol. .L-BFGS-B— dull gan dîm Broyden-Fletcher-Goldfarb-Shanno, a weithredwyd gyda llai o ddefnydd cof oherwydd llwytho fectorau yn rhannol o'r matrics Hessian. , .COBYLA— Optimeiddio Cyfyngedig MARE Trwy Brasamcaniad Llinol, optimeiddio cyfyngedig gyda brasamcan llinol (heb gyfrifo graddiant). .
Yn dibynnu ar y dull a ddewiswyd, mae amodau a chyfyngiadau ar gyfer datrys y broblem yn cael eu gosod yn wahanol:
- gwrthrych dosbarth
Boundsar gyfer dulliau L-BFGS-B, TNC, SLSQP, trust-constr; - y rhestr
(min, max)ar gyfer yr un dulliau L-BFGS-B, TNC, SLSQP, trust-constr; - gwrthrych neu restr o wrthrychau
LinearConstraint,NonlinearConstraintar gyfer COBYLA, SLSQP, dulliau ymddiriedaeth-constr; - geiriadur neu restr o eiriaduron
{'type':str, 'fun':callable, 'jac':callable,opt, 'args':sequence,opt}ar gyfer COBYLA, dulliau SLSQP.
Amlinelliad o'r erthygl:
1) Ystyried defnyddio algorithm optimeiddio amodol yn y rhanbarth ymddiriedaeth (method="trust-constr") gyda chyfyngiadau wedi'u nodi fel gwrthrychau Bounds, LinearConstraint, NonlinearConstraint ;
2) Ystyried rhaglennu dilyniannol gan ddefnyddio'r dull sgwariau lleiaf (dull = "SLSQP") gyda chyfyngiadau wedi'u nodi ar ffurf geiriadur {'type', 'fun', 'jac', 'args'};
3) Dadansoddwch enghraifft o optimeiddio cynhyrchion gweithgynhyrchu gan ddefnyddio enghraifft stiwdio we.
Dull optimeiddio amodol = "trust-constr"
Gweithredu'r dull trust-constr yn seiliedig ar am broblemau gyda chyfyngiadau ffurf cydraddoldeb ac ymlaen am broblemau gyda chyfyngiadau ar ffurf anghydraddoldebau. Mae'r ddau ddull yn cael eu gweithredu gan algorithmau ar gyfer dod o hyd i leiafswm lleol yn y rhanbarth hyder ac maent yn addas iawn ar gyfer problemau ar raddfa fawr.
Ffurfio'r broblem o ddod o hyd i isafswm ar ffurf gyffredinol yn fathemategol:



Ar gyfer cyfyngiadau cydraddoldeb llym, mae'r arffin isaf wedi'i osod yn hafal i'r ffin uchaf
.
Ar gyfer cyfyngiad unffordd, gosodir y terfyn uchaf neu isaf np.inf gyda'r arwydd cyfatebol.
Gadewch iddo fod yn angenrheidiol i ddarganfod y lleiafswm o swyddogaeth Rosenbrock hysbys o ddau newidyn:

Yn yr achos hwn, gosodir y cyfyngiadau canlynol ar ei barth diffiniad:






Yn ein hachos ni, mae yna ateb unigryw ar y pwynt
, y mae'r cyfyngiad cyntaf a'r pedwerydd cyfyngiad yn unig yn ddilys ar ei gyfer.
Gadewch i ni fynd trwy'r cyfyngiadau o'r gwaelod i'r brig ac edrych ar sut y gallwn eu hysgrifennu yn scipy.
Cyfyngiadau
и
gadewch i ni ei ddiffinio gan ddefnyddio'r gwrthrych Bounds.
from scipy.optimize import Bounds
bounds = Bounds ([0, -0.5], [1.0, 2.0])Cyfyngiadau
и
Gadewch i ni ei ysgrifennu ar ffurf llinol:

Gadewch i ni ddiffinio'r cyfyngiadau hyn fel gwrthrych LlinellolConstraint:
import numpy as np
from scipy.optimize import LinearConstraint
linear_constraint = LinearConstraint ([[1, 2], [2, 1]], [-np.inf, 1], [1, 1])Ac yn olaf y cyfyngiad aflinol ar ffurf matrics:

Rydym yn diffinio matrics Jacobiaidd ar gyfer y cyfyngiad hwn a chyfuniad llinol o'r matrics Hessian â fector mympwyol
:


Nawr gallwn ddiffinio cyfyngiad aflinol fel gwrthrych NonlinearConstraint:
from scipy.optimize import NonlinearConstraint
def cons_f(x):
return [x[0]**2 + x[1], x[0]**2 - x[1]]
def cons_J(x):
return [[2*x[0], 1], [2*x[0], -1]]
def cons_H(x, v):
return v[0]*np.array([[2, 0], [0, 0]]) + v[1]*np.array([[2, 0], [0, 0]])
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=cons_H)Os yw'r maint yn fawr, gellir nodi matricsau ar ffurf denau hefyd:
from scipy.sparse import csc_matrix
def cons_H_sparse(x, v):
return v[0]*csc_matrix([[2, 0], [0, 0]]) + v[1]*csc_matrix([[2, 0], [0, 0]])
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1,
jac=cons_J, hess=cons_H_sparse)neu fel gwrthrych LinearOperator:
from scipy.sparse.linalg import LinearOperator
def cons_H_linear_operator(x, v):
def matvec(p):
return np.array([p[0]*2*(v[0]+v[1]), 0])
return LinearOperator((2, 2), matvec=matvec)
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1,
jac=cons_J, hess=cons_H_linear_operator)Wrth gyfrifo'r matrics Hessian
angen llawer o ymdrech, gallwch ddefnyddio dosbarth . Mae’r strategaethau canlynol ar gael: BFGS и SR1.
from scipy.optimize import BFGS
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=BFGS())Gellir cyfrifo'r Hesian hefyd gan ddefnyddio gwahaniaethau meidraidd:
nonlinear_constraint = NonlinearConstraint (cons_f, -np.inf, 1, jac = cons_J, hess = '2-point')Gellir cyfrifo'r matrics Jacobiaidd ar gyfer cyfyngiadau hefyd gan ddefnyddio gwahaniaethau cyfyngedig. Fodd bynnag, yn yr achos hwn ni ellir cyfrifo matrics Hessian gan ddefnyddio gwahaniaethau meidraidd. Rhaid diffinio'r Hessian fel ffwythiant neu ddefnyddio'r dosbarth HessianUpdateStrategy.
nonlinear_constraint = NonlinearConstraint (cons_f, -np.inf, 1, jac = '2-point', hess = BFGS ())Mae'r ateb i'r broblem optimeiddio yn edrych fel hyn:
from scipy.optimize import minimize
from scipy.optimize import rosen, rosen_der, rosen_hess, rosen_hess_prod
x0 = np.array([0.5, 0])
res = minimize(rosen, x0, method='trust-constr', jac=rosen_der, hess=rosen_hess,
constraints=[linear_constraint, nonlinear_constraint],
options={'verbose': 1}, bounds=bounds)
print(res.x)`gtol` termination condition is satisfied.
Number of iterations: 12, function evaluations: 8, CG iterations: 7, optimality: 2.99e-09, constraint violation: 1.11e-16, execution time: 0.033 s.
[0.41494531 0.17010937]Os oes angen, gellir diffinio'r swyddogaeth ar gyfer cyfrifo'r Hessian gan ddefnyddio'r dosbarth LinearOperator
def rosen_hess_linop(x):
def matvec(p):
return rosen_hess_prod(x, p)
return LinearOperator((2, 2), matvec=matvec)
res = minimize(rosen, x0, method='trust-constr', jac=rosen_der, hess=rosen_hess_linop,
constraints=[linear_constraint, nonlinear_constraint],
options={'verbose': 1}, bounds=bounds)
print(res.x)neu gynnyrch yr Hessian a fector mympwyol trwy'r paramedr hessp:
res = minimize(rosen, x0, method='trust-constr', jac=rosen_der, hessp=rosen_hess_prod,
constraints=[linear_constraint, nonlinear_constraint],
options={'verbose': 1}, bounds=bounds)
print(res.x)Fel arall, gellir brasamcanu deilliadau cyntaf ac ail y swyddogaeth sy'n cael ei optimeiddio. Er enghraifft, gellir brasamcanu'r Hessian gan ddefnyddio'r ffwythiant SR1 (brasamcan lled-Newtonaidd). Gellir brasamcanu'r graddiant gan wahaniaethau cyfyngedig.
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)Dull optimeiddio amodol = "SLSQP"
Mae'r dull SLSQP wedi'i gynllunio i ddatrys problemau lleihau swyddogaeth yn y ffurf:




Lle
и
— setiau o fynegeion ymadroddion sy'n disgrifio cyfyngiadau ar ffurf cydraddoldebau neu anghydraddoldebau.
— setiau o ffiniau isaf ac uchaf ar gyfer parth diffinio'r swyddogaeth.
Disgrifir cyfyngiadau llinol ac aflinol ar ffurf geiriaduron gydag allweddi 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])
}Gwneir y chwiliad am yr isafswm fel a ganlyn:
x0 = np.array([0.5, 0])
res = minimize(rosen, x0, method='SLSQP', jac=rosen_der,
constraints=[eq_cons, ineq_cons], options={'ftol': 1e-9, 'disp': True},
bounds=bounds)
print(res.x)Optimization terminated successfully. (Exit mode 0)
Current function value: 0.34271757499419825
Iterations: 4
Function evaluations: 5
Gradient evaluations: 4
[0.41494475 0.1701105 ]Enghraifft Optimization
Mewn cysylltiad â'r newid i'r pumed strwythur technolegol, gadewch i ni edrych ar optimeiddio cynhyrchu gan ddefnyddio'r enghraifft o stiwdio we, sy'n dod ag incwm bach ond sefydlog i ni. Gadewch i ni ddychmygu ein hunain fel cyfarwyddwr gali sy'n cynhyrchu tri math o gynnyrch:
- x0 - gwerthu tudalennau glanio, o 10 tr.
- x1 - gwefannau corfforaethol, o 20 tr.
- x2 - siopau ar-lein, o 30 tr.
Mae ein tîm gwaith cyfeillgar yn cynnwys pedwar aelod iau, dau ganolwr ac un hŷn. Eu cronfa oriau gwaith misol:
- Mehefin:
4 * 150 = 600 чел * час, - canol:
2 * 150 = 300 чел * час, - senor:
150 чел * час.
Gadewch i'r iau cyntaf sydd ar gael dreulio (0, 1, 2) oriau ar ddatblygu a defnyddio un safle o'r math (x10, x20, x30), canol - (7, 15, 20), uwch - (5, 10, 15 ) oriau o amser gorau eich bywyd.
Fel unrhyw gyfarwyddwr arferol, rydym am wneud y mwyaf o elw misol. Y cam cyntaf i lwyddiant yw ysgrifennu'r swyddogaeth wrthrychol value fel swm yr incwm o gynhyrchion a gynhyrchir bob mis:
def value(x):
return - 10*x[0] - 20*x[1] - 30*x[2]Nid gwall yw hwn; wrth chwilio am yr uchafswm, mae'r swyddogaeth wrthrychol yn cael ei lleihau gyda'r arwydd gyferbyn.
Y cam nesaf yw gwahardd ein gweithwyr rhag gorweithio a chyflwyno cyfyngiadau ar oriau gwaith:

Beth sy'n cyfateb:

ineq_cons = {'type': 'ineq',
'fun': lambda x: np.array ([600 - 10 * x [0] - 20 * x [1] - 30 * x[2],
300 - 7 * x [0] - 15 * x [1] - 20 * x[2],
150 - 5 * x [0] - 10 * x [1] - 15 * x[2]])
}Cyfyngiad ffurfiol yw bod yn rhaid i allbwn cynnyrch fod yn gadarnhaol yn unig:
bnds = Bounds ([0, 0, 0], [np.inf, np.inf, np.inf])Ac yn olaf, y dybiaeth fwyaf poblogaidd yw, oherwydd y pris isel ac ansawdd uchel, bod ciw o gwsmeriaid bodlon yn gyson i ni. Gallwn ddewis y cyfrolau cynhyrchu misol ein hunain, yn seiliedig ar ddatrys y broblem optimeiddio gyfyngedig scipy.optimize:
x0 = np.array([10, 10, 10])
res = minimize(value, x0, method='SLSQP', constraints=ineq_cons, bounds=bnds)
print(res.x)[7.85714286 5.71428571 3.57142857]Gadewch i ni dalgrynnu'n llac i rifau cyfan a chyfrifo'r llwyth misol o rwyfwyr gyda'r dosbarthiad gorau posibl o gynhyrchion x = (8, 6, 3) :
- Mehefin:
8 * 10 + 6 * 20 + 3 * 30 = 290 чел * час; - canol:
8 * 7 + 6 * 15 + 3 * 20 = 206 чел * час; - senor:
8 * 5 + 6 * 10 + 3 * 15 = 145 чел * час.
Casgliad: er mwyn i'r cyfarwyddwr dderbyn ei uchafswm haeddiannol, mae'n well creu 8 tudalen lanio, 6 safle canolig a 3 siop y mis. Yn yr achos hwn, mae'n rhaid i'r uwch aredig heb edrych i fyny o'r peiriant, bydd llwyth y canol tua 2/3, yr iau yn llai na hanner.
Casgliad
Mae'r erthygl yn amlinellu'r technegau sylfaenol ar gyfer gweithio gyda'r pecyn scipy.optimize, a ddefnyddir i ddatrys problemau lleihau amodol. Yn bersonol dwi'n defnyddio scipy at ddibenion academaidd yn unig, a dyna pam fod yr enghraifft a roddir mor ddigrif ei natur.
Gellir dod o hyd i lawer o theori ac enghreifftiau rhithwir, er enghraifft, yn y llyfr gan IL Akulich “Rhaglennu mathemategol mewn enghreifftiau a phroblemau.” Mwy o gais craidd caled scipy.optimize i adeiladu strwythur 3D o set o ddelweddau () gellir ei weld yn .
Y brif ffynhonnell wybodaeth yw rhai sy'n dymuno cyfrannu at gyfieithu'r adran hon ac adrannau eraill scipy Croeso i .
Diolch ar gyfer cymryd rhan yn y gwaith o baratoi'r cyhoeddiad.
Ffynhonnell: hab.com
