SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

Tha SciPy (air fhuaimneachadh sai pie) na phasgan matamataigeach stèidhichte air àireamh a tha cuideachd a’ toirt a-steach leabharlannan C agus Fortran. Bidh SciPy a’ tionndadh do sheisean Python eadar-ghnìomhach gu àrainneachd saidheans dàta iomlan mar MATLAB, IDL, Octave, R, no SciLab.

San artaigil seo, seallaidh sinn ri dòighean bunaiteach prògramadh matamataigeach - a’ fuasgladh dhuilgheadasan optimization cumhach airson gnìomh scalar grunn chaochladairean a’ cleachdadh a’ phacaid scipy.optimize. Chaidh beachdachadh mu thràth air algorithms optimization gun bhacadh ann an an artaigil mu dheireadh. Faodar cuideachadh nas mionaidiche agus nas ùire fhaighinn air gnìomhan scipy an-còmhnaidh a’ cleachdadh an àithne cuideachaidh (), Shift + Tab no ann an sgrìobhainnean oifigeil.

Ro-ràdh

Tha eadar-aghaidh cumanta airson fuasgladh fhaighinn air duilgheadasan optimization gun chumhachan agus gun bhacadh anns a’ phacaid scipy.optimize air a thoirt seachad leis a’ ghnìomh minimize(). Ach, tha fios nach eil dòigh choitcheann ann airson fuasgladh fhaighinn air a h-uile duilgheadas, agus mar sin tha an roghainn dòigh iomchaidh, mar a tha e an-còmhnaidh, a 'tuiteam air guailnean an neach-rannsachaidh.
Tha an algairim optimization iomchaidh air a shònrachadh a’ cleachdadh an argamaid gnìomh minimize(..., method="").
Airson optimization cumhach air gnìomh grunn chaochladairean, tha buileachadh de na dòighean a leanas rim faighinn:

  • trust-constr - lorg ìre as ìsle san sgìre misneachd. Artaigil Wiki, artaigil air Habré;
  • SLSQP - prògramadh ceithir-cheàrnach sreath le cuingealachaidhean, dòigh Newtonian airson siostam Lagrange fhuasgladh. Artaigil Wiki.
  • TNC - Truncated Newton Cuingealaichte, àireamh cuibhrichte de dh’ itealain, math airson gnìomhan neo-loidhneach le àireamh mhòr de chaochladairean neo-eisimeileach. Artaigil Wiki.
  • L-BFGS-B - dòigh bhon sgioba Broyden - Fletcher - Goldfarb - Shanno, air a chuir an gnìomh le caitheamh cuimhne nas lugha mar thoradh air luchdachadh pàirt de vectaran bhon mhaitrix Hessian. Artaigil Wiki, artaigil air Habré.
  • COBYLA - Optimization cuibhrichte MARE le tuairmse sreathach, optimization cuibhrichte le tuairmse sreathach (às aonais àireamhachadh caisead). Artaigil Wiki.

A rèir an dòigh a chaidh a thaghadh, tha suidheachaidhean agus cuingealachaidhean airson fuasgladh fhaighinn air an duilgheadas air an suidheachadh ann an dòigh eadar-dhealaichte:

  • nì clas Bounds airson modhan L-BFGS-B, TNC, SLSQP, trust-constr;
  • an liosta (min, max) airson na h-aon dhòighean L-BFGS-B, TNC, SLSQP, trust-constr;
  • nì no liosta de nithean LinearConstraint, NonlinearConstraint airson COBYLA, SLSQP, dòighean earbsa-constr;
  • faclair neo liosta fhaclairean {'type':str, 'fun':callable, 'jac':callable,opt, 'args':sequence,opt} airson dòighean COBYLA, SLSQP.

Geàrr-chunntas artaigil:
1) Beachdaich air cleachdadh algorithm optimization cumhach anns an roinn earbsa (modh = ”trust-constr”) le cuingeadan air an sònrachadh mar nithean Bounds, LinearConstraint, NonlinearConstraint ;
2) Beachdaich air prògramadh sreath a’ cleachdadh an dòigh as lugha de cheàrnagan (modh = “SLSQP”) le cuingeachaidhean air an sònrachadh ann an cruth faclair {'type', 'fun', 'jac', 'args'};
3) Dèan sgrùdadh air eisimpleir de optimization de thoraidhean dèanta a’ cleachdadh eisimpleir stiùidio lìn.

Modh optimization cumhach = "trust-constr"

Cur an gnìomh a 'mhodh trust-constr Stèidhichte air EQSQP airson duilgheadasan le cuingeadan cruth co-ionannachd agus air adhart Trip airson duilgheadasan le cuingealachaidhean ann an cruth neo-ionannachd. Tha an dà dhòigh air an cur an gnìomh le algoirmean airson a bhith a 'lorg ìre as ìsle ionadail anns an roinn misneachd agus tha iad gu math freagarrach airson duilgheadasan mòra.

Cruthachadh matamataigeach den duilgheadas a bhith a’ lorg ìre as ìsle ann an cruth coitcheann:

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

Airson cuingealachaidhean co-ionannachd teann, tha an ìre as ìsle air a shuidheachadh co-ionann ris a 'chrìoch àrd SciPy, optimization le cumhachan.
Airson cuingealachadh aon-shligheach, tha an ìre as àirde no as ìsle air a shuidheachadh np.inf leis an t-soidhne fhreagarrach.
Biodh e riatanach an ìre as lugha de ghnìomh Rosenbrock aithnichte de dhà chaochladair a lorg:

SciPy, optimization le cumhachan

Anns a 'chùis seo, tha na cuingeadan a leanas air an suidheachadh air an raon mìneachaidh aige:

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

Anns a 'chùis againn, tha fuasgladh sònraichte aig a' phuing SciPy, optimization le cumhachan, airson nach eil ach a’ chiad agus an ceathramh bacadh dligheach.
Rachamaid tro na cuingeachaidhean bho bhonn gu mullach agus coimhead air mar as urrainn dhuinn an sgrìobhadh ann an scipy.
Srian SciPy, optimization le cumhachan и SciPy, optimization le cumhachan mìnichidh sinn e a’ cleachdadh an nì Bounds.

from scipy.optimize import Bounds
bounds = Bounds ([0, -0.5], [1.0, 2.0])

Srian SciPy, optimization le cumhachan и SciPy, optimization le cumhachan Sgrìobhamaid e ann an cruth loidhneach:

SciPy, optimization le cumhachan

Nach mìnich sinn na cuingeadan sin mar nì LinearConstraint:

import numpy as np
from scipy.optimize import LinearConstraint
linear_constraint = LinearConstraint ([[1, 2], [2, 1]], [-np.inf, 1], [1, 1])

Agus mu dheireadh an cuingealachadh neo-loidhneach ann an cruth matrix:

SciPy, optimization le cumhachan

Bidh sinn a’ mìneachadh matrix nan Seumasach airson a’ bhacadh seo agus measgachadh sreathach de mhaitrix Hessian le vectar neo-riaghailteach SciPy, optimization le cumhachan:

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

A-nis is urrainn dhuinn cuingealachadh neo-loidhneach a mhìneachadh mar nì 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)

Ma tha am meud mòr, faodar matrices a shònrachadh ann an cruth gann:

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)

no mar nì 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)

Nuair a thathar a’ tomhas matrix Hessian SciPy, optimization le cumhachan feumach air tòrr oidhirp, faodaidh tu clas a chleachdadh HessianUpdateStrategy. Tha na ro-innleachdan a leanas rim faighinn: BFGS и SR1.

from scipy.optimize import BFGS

nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=BFGS())

Faodar an Hessian a thomhas cuideachd a’ cleachdadh eadar-dhealachaidhean cuibhrichte:

nonlinear_constraint = NonlinearConstraint (cons_f, -np.inf, 1, jac = cons_J, hess = '2-point')

Faodar matrix Jacobian airson cuingeadan a thomhas cuideachd a’ cleachdadh eadar-dhealachaidhean cuibhrichte. Ach, anns a’ chùis seo chan urrainnear matrix Hessian a thomhas a’ cleachdadh eadar-dhealachaidhean cuibhrichte. Feumaidh an Hessian a bhith air a mhìneachadh mar ghnìomh no a’ cleachdadh clas HessianUpdateStrategy.

nonlinear_constraint = NonlinearConstraint (cons_f, -np.inf, 1, jac = '2-point', hess = BFGS ())

Tha am fuasgladh don duilgheadas optimization a ’coimhead mar seo:

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]

Ma tha feum air, faodar a’ ghnìomh airson an Hessian obrachadh a-mach a mhìneachadh a’ cleachdadh a’ chlas 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)

no toradh an Hessian agus vectar neo-riaghailteach tron ​​​​paramadair 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)

Air an làimh eile, faodar tuairmse a dhèanamh air a’ chiad agus an dàrna toradh den ghnìomh a thathar ag ùrachadh. Mar eisimpleir, faodar an Hessian a thomhas a’ cleachdadh a’ ghnìomh SR1 (tuairmse leth-Newtonian). Faodar an caisead a thomhas le eadar-dhealachaidhean cuibhrichte.

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)

Modh optimization cumhach = "SLSQP"

Tha an dòigh SLSQP air a dhealbhadh gus fuasgladh fhaighinn air duilgheadasan le bhith a’ lughdachadh gnìomh ann an cruth:

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

SciPy, optimization le cumhachan

Càite SciPy, optimization le cumhachan и SciPy, optimization le cumhachan - seataichean de chlàran-innse abairtean a’ toirt cunntas air cuingeachaidhean ann an cruth co-ionannachdan no neo-ionannachdan. SciPy, optimization le cumhachan - seataichean de chrìochan ìosal is àrd airson raon mìneachadh na gnìomh.

Thathas a’ toirt iomradh air cuingeadan sreathach agus neo-loidhneach ann an cruth fhaclairean le iuchraichean 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])
          }

Tha an rannsachadh airson an ìre as ìsle air a dhèanamh mar a leanas:

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 ]

Eisimpleir optimization

Ann an co-cheangal ris a’ ghluasad chun chòigeamh structar teicneòlais, leig dhuinn sùil a thoirt air optimization cinneasachaidh a’ cleachdadh eisimpleir de stiùidio lìn, a bheir dhuinn teachd-a-steach beag ach seasmhach. Smaoinich sinn fhìn mar stiùiriche air birlinn a bhios a’ dèanamh trì seòrsaichean toraidh:

  • x0 - a 'reic duilleagan tighinn air tìr, bho 10 tr.
  • x1 - làraichean-lìn corporra, bho 20 tr.
  • x2 - stòran air-loidhne, bho 30 tr.

Tha an sgioba obrach càirdeil againn a’ toirt a-steach ceithir òigridh, dà mheadhanach agus aon àrd. Am maoin ùine-obrach mìosail aca:

  • Ògmhios: 4 * 150 = 600 чел * час,
  • meadhan: 2 * 150 = 300 чел * час,
  • seanair: 150 чел * час.

Leig leis a’ chiad fhear òg a tha ri fhaighinn uairean a chaitheamh (0, 1, 2) air leasachadh agus cleachdadh aon làrach den t-seòrsa (x10, x20, x30), meadhan - (7, 15, 20), àrd - (5, 10, 15). ) uairean den àm as fheàrr de do bheatha.

Coltach ri stiùiriche àbhaisteach sam bith, tha sinn airson prothaidean mìosail a mheudachadh. Is e a’ chiad cheum gu soirbheachas an gnìomh amas a sgrìobhadh sìos value mar an teachd a-steach bho thoraidhean a chaidh a dhèanamh gach mìos:

def value(x):
    return - 10*x[0] - 20*x[1] - 30*x[2]

Chan e mearachd a tha seo; nuair a thathar a’ lorg an ìre as àirde, tha an gnìomh amas air a lughdachadh leis an t-soidhne eile.

Is e an ath cheum casg a chuir air ar luchd-obrach bho bhith ag obair cus agus casg a chuir air uairean obrach:

SciPy, optimization le cumhachan

Dè tha co-ionann:

SciPy, optimization le cumhachan

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]])
            }

Is e cuingealachadh foirmeil nach fheum toradh toraidh a bhith ach deimhinneach:

bnds = Bounds ([0, 0, 0], [np.inf, np.inf, np.inf])

Agus mu dheireadh, is e a’ bharail as rosy, air sgàth a’ phrìs ìosal agus càileachd àrd, ciudha de luchd-ceannach riaraichte an-còmhnaidh a’ tighinn thugainn. Is urrainn dhuinn na meudan toraidh mìosail a thaghadh sinn fhìn, stèidhichte air fuasgladh fhaighinn air an duilgheadas optimization cuibhrichte le 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]

Bheir sinn timcheall gu socair gu àireamhan slàn agus obraich a-mach an luchd mìosail de ràimh leis an cuairteachadh as fheàrr de thoraidhean x = (8, 6, 3) :

  • Ògmhios: 8 * 10 + 6 * 20 + 3 * 30 = 290 чел * час;
  • meadhan: 8 * 7 + 6 * 15 + 3 * 20 = 206 чел * час;
  • seanair: 8 * 5 + 6 * 10 + 3 * 15 = 145 чел * час.

Co-dhùnadh: gus am faigh an stiùiriche an ìre as àirde airidh air, tha e nas fheàrr 8 duilleagan tighinn air tìr, 6 làraich meadhanach mòr agus 3 stòran a chruthachadh gach mìos. Anns a 'chùis seo, feumaidh an àrd-neach treabhadh gun a bhith a' coimhead suas bhon inneal, bidh an luchd meadhanach timcheall air 2/3, na h-òigridh nas lugha na leth.

co-dhùnadh

Tha an artaigil a’ mìneachadh nan dòighean bunaiteach airson a bhith ag obair leis a’ phacaid scipy.optimize, air a chleachdadh gus fuasgladh fhaighinn air duilgheadasan lughdachadh cumhach. Gu pearsanta bidh mi a’ cleachdadh scipy dìreach airson adhbharan acadaimigeach, agus is e sin as coireach gu bheil an eisimpleir a chaidh a thoirt seachad cho èibhinn.

Gheibhear tòrr teòiridh agus eisimpleirean brìgheil, mar eisimpleir, anns an leabhar le IL Akulich “Prògramadh matamataigeach ann an eisimpleirean agus duilgheadasan.” Iarrtas nas cruaidhe scipy.optimize gus structar 3D a thogail bho sheata de dhealbhan (artaigil air Habré) ri fhaicinn ann an leabhar còcaireachd scipy.

Tha am prìomh thùs fiosrachaidh docs.scipy.organ fheadhainn a tha airson cur ris an eadar-theangachadh air seo agus earrannan eile scipy Fàilte gu GitHub.

Спасибо mephistophees airson com-pàirteachadh ann an ullachadh an fhoillseachaidh.

Source: www.habr.com

Cuir beachd ann