SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy (lafazin sai pie) kunshin lissafin tushen lissafi ne wanda kuma ya haɗa da ɗakunan karatu na C da na Fortran. SciPy yana juya zaman Python ɗin ku na mu'amala zuwa cikakken yanayin kimiyyar bayanai kamar MATLAB, IDL, Octave, R, ko SciLab.

A cikin wannan labarin, za mu dubi ainihin dabarun shirye-shiryen lissafi - warware matsalolin inganta yanayin yanayi don aikin scalar na masu canji da yawa ta amfani da kunshin scipy.optimize. An riga an tattauna algorithms ingantawa marasa ƙarfi a ciki labarin karshe. Ana iya samun ƙarin cikakkun bayanai da na yau da kullun akan ayyukan scipy ta amfani da umarnin taimako(), Shift+Tab ko a ciki takardun shaida.

Gabatarwar

Alamar gama gari don magance matsalolin haɓakawa na sharadi da marasa ƙarfi a cikin fakitin scipy.optimize yana samar da aikin. minimize(). Duk da haka, an san cewa babu wata hanya ta duniya don magance duk matsalolin, don haka zaɓin hanyar da ta dace, kamar kullum, yana kan kafadu na mai bincike.
An ƙayyade ingantaccen ingantaccen algorithm ta amfani da hujjar aikin minimize(..., method="").
Don inganta yanayin yanayin aiki na masu canji da yawa, ana samun aiwatar da hanyoyin masu zuwa:

  • trust-constr - bincika mafi ƙarancin gida a cikin yankin amincewa. Labarin Wiki, labarin kan Habre;
  • SLSQP - shirye-shirye na quadratic na jere tare da ƙuntatawa, hanyar Newtonian don warware tsarin Lagrange. Labarin Wiki.
  • TNC - Truncated Newton Constrained, iyakance adadin maimaitawa, mai kyau ga ayyukan da ba na layi ba tare da adadi mai yawa na masu canji masu zaman kansu. Labarin Wiki.
  • L-BFGS-B - wata hanya daga ƙungiyar Broyden-Fletcher-Goldfarb-Shanno, wanda aka aiwatar tare da rage yawan amfani da ƙwaƙwalwar ajiya saboda wani ɓangare na lodawa na vectors daga matrix Hessian. Labarin Wiki, labarin kan Habre.
  • COBYLA - Ƙuntataccen Ƙarfafa MARE Ta Hanyar Ƙimar layi, ƙayyadaddun ingantawa tare da ƙima na layi (ba tare da lissafi ba). Labarin Wiki.

Dangane da hanyar da aka zaɓa, yanayi da ƙuntatawa don magance matsalar an saita su daban:

  • abu aji Bounds don hanyoyin L-BFGS-B, TNC, SLSQP, amincewa-constr;
  • lissafin (min, max) don hanyoyin guda ɗaya L-BFGS-B, TNC, SLSQP, amincewa-constr;
  • abu ko jerin abubuwa LinearConstraint, NonlinearConstraint don COBYLA, SLSQP, hanyoyin dogara-constr;
  • ƙamus ko jerin ƙamus {'type':str, 'fun':callable, 'jac':callable,opt, 'args':sequence,opt} don COBYLA, hanyoyin SLSQP.

Bayanin labarin:
1) Yi la'akari da amfani da ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun abubuwa a cikin yankin amintaccen (hanyar = "trust-constr") tare da ƙuntatawa da aka ƙayyade azaman abubuwa. Bounds, LinearConstraint, NonlinearConstraint ;
2) Yi la'akari da shirye-shiryen jeri ta amfani da mafi ƙarancin hanyar murabba'i (hanyar = "SLSQP") tare da ƙuntatawa da aka ƙayyade a cikin nau'i na ƙamus {'type', 'fun', 'jac', 'args'};
3) Yi nazarin misali na inganta samfuran da aka ƙera ta amfani da misalin gidan yanar gizo.

Hanyar inganta sharadi = "trust-constr"

Aiwatar da hanyar trust-constr bisa EQSQP ga matsaloli tare da ƙuntatawa na nau'i na daidaito da kuma a kan TAFIYA ga matsaloli tare da ƙuntatawa a cikin nau'i na rashin daidaituwa. Dukkan hanyoyin biyu ana aiwatar da su ta hanyar algorithms don nemo mafi ƙarancin gida a cikin yankin amincewa kuma sun dace da manyan matsaloli.

Ƙirƙirar lissafi na matsalar gano mafi ƙanƙanta a cikin sigar gabaɗaya:

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

Don ƙaƙƙarfan ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun iyaka an saita shi daidai da na sama SciPy, ingantawa tare da yanayi.
Don takura ta hanya ɗaya, an saita iyaka na sama ko ƙasa np.inf tare da alamar da ta dace.
Bari ya zama dole a nemo mafi ƙarancin sanannen aikin Rosenbrock na masu canji guda biyu:

SciPy, ingantawa tare da yanayi

A wannan yanayin, an saita ƙuntatawa masu zuwa akan yankin ma'anarsa:

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

A cikin yanayinmu, akwai mafita na musamman a wurin SciPy, ingantawa tare da yanayi, wanda kawai na farko da na hudu ƙuntatawa suna aiki.
Bari mu bi ta cikin ƙuntatawa daga ƙasa zuwa sama mu duba yadda za mu iya rubuta su a cikin scipy.
Ƙuntatawa SciPy, ingantawa tare da yanayi и SciPy, ingantawa tare da yanayi bari mu ayyana shi ta amfani da abu Bonds.

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

Ƙuntatawa SciPy, ingantawa tare da yanayi и SciPy, ingantawa tare da yanayi Bari mu rubuta shi a sigar madaidaiciya:

SciPy, ingantawa tare da yanayi

Bari mu ayyana waɗannan ƙuntatawa azaman abu na LinearConstraint:

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

Kuma a ƙarshe ƙuntatawar da ba ta dace ba a cikin sigar matrix:

SciPy, ingantawa tare da yanayi

Mun ayyana matrix na Yakubu don wannan takurawa da haɗin kai tsaye na matrix na Hessian tare da madaidaicin ra'ayi. SciPy, ingantawa tare da yanayi:

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

Yanzu za mu iya ayyana takura mara tushe a matsayin abu 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)

Idan girman yana da girma, kuma ana iya ƙayyade matrices a cikin sigar da ba ta da yawa:

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)

ko a matsayin abu 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)

Lokacin ƙididdige matrix Hessian SciPy, ingantawa tare da yanayi yana buƙatar ƙoƙari mai yawa, zaka iya amfani da aji HessianUpdateStrategy. Akwai dabaru masu zuwa: BFGS и SR1.

from scipy.optimize import BFGS

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

Hakanan ana iya lissafin Hessian ta amfani da bambance-bambance masu iyaka:

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

Hakanan ana iya ƙididdige matrix na Yakubu don ƙuntatawa ta amfani da bambance-bambance masu iyaka. Koyaya, a wannan yanayin ba za a iya ƙididdige matrix na Hessian ta amfani da bambance-bambance masu iyaka ba. Dole ne a ayyana Hessian azaman aiki ko amfani da ajin HessianUpdateStrategy.

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

Maganin matsalar ingantawa yayi kama da haka:

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]

Idan ya cancanta, ana iya ayyana aikin don ƙididdige Hessian ta amfani da ajin 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)

ko samfurin Hessian da vector na sabani ta hanyar siga 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)

A madadin, na farko da na biyu abubuwan da ake inganta aikin ana iya kimanta su. Misali, ana iya kimanta Hessian ta amfani da aikin SR1 (ƙimar Newtonian). Za a iya kusantar da gradient ta ƙarancin bambance-bambance.

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)

Hanyar inganta sharadi = "SLSQP"

An tsara hanyar SLSQP don magance matsalolin rage aiki a cikin nau'i:

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

SciPy, ingantawa tare da yanayi

Inda SciPy, ingantawa tare da yanayi и SciPy, ingantawa tare da yanayi - jeri na fihirisar maganganu masu bayyana hani a cikin nau'i na daidaito ko rashin daidaituwa. SciPy, ingantawa tare da yanayi - saitin ƙananan iyakoki da na sama don yankin ma'anar aikin.

An siffanta ƙuntatawa na layi da marasa kan layi a cikin nau'in ƙamus tare da maɓalli 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])
          }

Ana gudanar da binciken mafi ƙanƙanta kamar haka:

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 ]

Misalin Ingantawa

Dangane da sauye-sauye zuwa tsarin fasaha na biyar, bari mu kalli inganta samarwa ta hanyar amfani da misalin gidan yanar gizo, wanda ke kawo mana karancin kudin shiga. Bari mu yi tunanin kanmu a matsayin darektan jirgin ruwa mai samar da kayayyaki iri uku:

  • x0 - sayar da shafukan sauka, daga 10 tr.
  • x1 - gidajen yanar gizon kamfanoni, daga 20 tr.
  • x2 - shagunan kan layi, daga 30 tr.

Tawagar aikin mu na abokantaka sun haɗa da yara huɗu, na tsakiya biyu da babba ɗaya. Asusun lokacin aiki na wata-wata:

  • Yuni: 4 * 150 = 600 чел * час,
  • tsakiya: 2 * 150 = 300 чел * час,
  • senor: 150 чел * час.

Bari ƙananan yara na farko su ciyar (0, 1, 2) sa'o'i akan haɓakawa da tura rukunin yanar gizo guda ɗaya (x10, x20, x30), tsakiya - (7, 15, 20), babba - (5, 10, 15). ) sa'o'i mafi kyawun lokacin rayuwar ku.

Kamar kowane darektan al'ada, muna son haɓaka ribar kowane wata. Mataki na farko don samun nasara shine rubuta aikin haƙiƙa value kamar yadda adadin kuɗin shiga daga samfuran da ake samarwa kowane wata:

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

Wannan ba kuskure ba ne; lokacin neman matsakaicin, aikin haƙiƙa yana raguwa tare da kishiyar alamar.

Mataki na gaba shine hana ma'aikatanmu yin aiki fiye da kima da gabatar da hani kan lokutan aiki:

SciPy, ingantawa tare da yanayi

Me yayi daidai:

SciPy, ingantawa tare da yanayi

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

Ƙuntatawa na yau da kullun shine fitarwar samfur dole ne kawai ya zama tabbatacce:

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

Kuma a ƙarshe, mafi kyawun zato shine cewa saboda ƙarancin farashi da inganci, jerin abokan ciniki masu gamsuwa koyaushe suna layi mana. Za mu iya zaɓar juzu'in samarwa na wata-wata da kanmu, bisa la'akari da warware matsalar ingantawa ta ƙuntata tare da 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]

Bari mu zagaya a hankali zuwa duka lambobi kuma mu lissafta nauyin maharan na wata-wata tare da ingantacciyar rarraba kayayyaki. x = (8, 6, 3) :

  • Yuni: 8 * 10 + 6 * 20 + 3 * 30 = 290 чел * час;
  • tsakiya: 8 * 7 + 6 * 15 + 3 * 20 = 206 чел * час;
  • senor: 8 * 5 + 6 * 10 + 3 * 15 = 145 чел * час.

Kammalawa: domin darektan ya karɓi iyakar abin da ya cancanta, yana da kyau a ƙirƙiri shafukan saukarwa 8, shafuka masu matsakaici 6 da shagunan 3 kowane wata. A wannan yanayin, babban dole ne ya yi noma ba tare da kallon sama daga na'ura ba, nauyin matsakaicin zai zama kusan 2/3, ƙananan ƙananan ƙasa da rabi.

ƙarshe

Labarin ya bayyana mahimman dabarun aiki tare da kunshin scipy.optimize, ana amfani dashi don magance matsalolin rage girman yanayin. Da kaina ina amfani scipy don dalilai na ilimi kawai, shi ya sa misalin da aka bayar yana da irin wannan yanayi na ban dariya.

Ana iya samun yawancin ka'idoji da misalan kama-da-wane, alal misali, a cikin littafin IL Akulich "Mathematical Programming in misalai da matsaloli." Ƙarin aikace-aikacen hardcore scipy.optimize don gina tsarin 3D daga saitin hotuna (labarin kan Habre) za a iya gani a ciki Littafin dafa abinci.

Babban tushen bayanai shine docs.scipy.orgmasu son bayar da gudunmuwar tafsirin wannan da sauran sassan scipy Barka da zuwa GitHub.

Спасибо mephistophees don shiga cikin shirye-shiryen bugawa.

source: www.habr.com

Add a comment