SciPy (උච්චාරණය කරන ලද sai pie) යනු C සහ Fortran පුස්තකාල ද ඇතුළත් වන numpy මත පදනම් වූ ගණිත පැකේජයකි. SciPy ඔබගේ අන්තර්ක්රියාකාරී Python සැසිය MATLAB, IDL, Octave, R, හෝ SciLab වැනි සම්පූර්ණ දත්ත විද්යා පරිසරයක් බවට පත් කරයි.
මෙම ලිපියෙන්, අපි ගණිතමය ක්රමලේඛනයේ මූලික ශිල්පීය ක්රම දෙස බලමු - scipy.optimize පැකේජය භාවිතා කරමින් විචල්ය කිහිපයක පරිමාණ ශ්රිතයක් සඳහා කොන්දේසි සහිත ප්රශස්තිකරණ ගැටළු විසඳීම. අසීමිත ප්රශස්තිකරණ ඇල්ගොරිතම දැනටමත් සාකච්ඡා කර ඇත
හැඳින්වීම
scipy.optimize පැකේජයේ කොන්දේසි සහිත සහ අසීමිත ප්රශස්තකරණ ගැටළු විසඳීම සඳහා පොදු අතුරු මුහුණතක් ශ්රිතය මඟින් සපයනු ලැබේ. minimize()
. කෙසේ වෙතත්, සියලු ගැටළු විසඳීම සඳහා විශ්වීය ක්රමයක් නොමැති බව දන්නා අතර, ප්රමාණවත් ක්රමයක් තෝරාගැනීම, සෑම විටම මෙන්, පර්යේෂකයාගේ උරහිස් මත වැටේ.
සුදුසු ප්රශස්තිකරණ ඇල්ගොරිතම ශ්රිත තර්කය භාවිතයෙන් නියම කර ඇත minimize(..., method="")
.
විචල්ය කිහිපයක ශ්රිතයක කොන්දේසි සහිත ප්රශස්තකරණය සඳහා, පහත ක්රම ක්රියාත්මක කිරීම පවතී:
trust-constr
- විශ්වාස කලාපය තුළ දේශීය අවමයක් සොයන්න.විකි ලිපිය ,Habré පිළිබඳ ලිපිය ;SLSQP
- සීමාවන් සහිත අනුක්රමික චතුරස්ර ක්රමලේඛනය, Lagrange පද්ධතිය විසඳීම සඳහා නිව්ටෝනියානු ක්රමය.විකි ලිපිය .TNC
- කප්පාදු කරන ලද නිව්ටන් සීමා සහිත, සීමිත පුනරාවර්තන සංඛ්යාවක්, ස්වාධීන විචල්ය විශාල සංඛ්යාවක් සහිත රේඛීය නොවන ශ්රිත සඳහා හොඳය.විකි ලිපිය .L-BFGS-B
- බ්රොයිඩන්-ෆ්ලෙචර්-ගෝල්ඩ්ෆාර්බ්-ෂානෝ කණ්ඩායමේ ක්රමයක්, හෙසියන් න්යාසයෙන් දෛශික අර්ධ වශයෙන් පැටවීම හේතුවෙන් අඩු මතක පරිභෝජනයක් සමඟ ක්රියාත්මක කරන ලදී.විකි ලිපිය ,Habré පිළිබඳ ලිපිය .COBYLA
— රේඛීය ආසන්න කිරීම මගින් MARE සීමා සහිත ප්රශස්තකරණය, රේඛීය ආසන්නකරණය සමඟ සීමා කරන ලද ප්රශස්තකරණය (ශ්රේණිගත ගණනය කිරීමකින් තොරව).විකි ලිපිය .
තෝරාගත් ක්රමය මත පදනම්ව, ගැටළුව විසඳීම සඳහා කොන්දේසි සහ සීමාවන් වෙනස් ලෙස සකසා ඇත:
- පන්ති වස්තුව
Bounds
ක්රම සඳහා L-BFGS-B, TNC, SLSQP, Trust-constr; - ලැයිස්තුව
(min, max)
එකම ක්රම සඳහා L-BFGS-B, TNC, SLSQP, Trust-constr; - වස්තුවක් හෝ වස්තු ලැයිස්තුවක්
LinearConstraint
,NonlinearConstraint
COBYLA, SLSQP, Trust-constr methods සඳහා; - ශබ්දකෝෂය හෝ ශබ්දකෝෂ ලැයිස්තුව
{'type':str, 'fun':callable, 'jac':callable,opt, 'args':sequence,opt}
COBYLA, SLSQP ක්රම සඳහා.
ලිපි දළ සටහන:
1) වස්තු ලෙස දක්වා ඇති සීමාවන් සහිත විශ්වාස කලාපය තුළ කොන්දේසි සහිත ප්රශස්තකරණ ඇල්ගොරිතමයක් භාවිතා කිරීම සලකා බලන්න Bounds
, LinearConstraint
, NonlinearConstraint
;
2) ශබ්ද කෝෂයක ආකාරයෙන් දක්වා ඇති සීමාවන් සහිත අවම වර්ග ක්රමය (ක්රමය = "SLSQP") භාවිතා කරමින් අනුක්රමික වැඩසටහන්කරණය සලකා බලන්න. {'type', 'fun', 'jac', 'args'}
;
3) වෙබ් චිත්රාගාරයක උදාහරණය භාවිතයෙන් නිෂ්පාදිත නිෂ්පාදන ප්රශස්ත කිරීම පිළිබඳ උදාහරණයක් විශ්ලේෂණය කරන්න.
කොන්දේසි සහිත ප්රශස්තිකරණ ක්රමය="trust-constr"
ක්රමය ක්රියාත්මක කිරීම trust-constr
මත පදනම්ව
සාමාන්ය ස්වරූපයෙන් අවමයක් සොයා ගැනීමේ ගැටලුවේ ගණිතමය සූත්රගත කිරීම:
දැඩි සමානාත්මතා සීමාවන් සඳහා, පහළ සීමාව ඉහළ සීමාවට සමාන වේ .
එක්-මාර්ග සීමාවක් සඳහා, ඉහළ හෝ පහළ සීමාව සකසා ඇත np.inf
අනුරූප ලකුණ සමඟ.
විචල්ය දෙකක දන්නා Rosenbrock ශ්රිතයක අවම අගය සොයා ගැනීම අවශ්ය වේ.
මෙම අවස්ථාවෙහිදී, එහි අර්ථ දැක්වීමේ වසම මත පහත සීමාවන් සකසා ඇත:
අපගේ නඩුවේදී, ලක්ෂ්යයේ අද්විතීය විසඳුමක් තිබේ , ඒ සඳහා වලංගු වන්නේ පළමු සහ හතරවන සීමාවන් පමණි.
අපි පහළ සිට ඉහළට සීමා කිරීම් හරහා ගොස් ඒවා scipy වලින් ලියන්නේ කෙසේදැයි බලමු.
සීමා කිරීම් и එය සීමා වස්තුව භාවිතයෙන් නිර්වචනය කරමු.
from scipy.optimize import Bounds
bounds = Bounds ([0, -0.5], [1.0, 2.0])
සීමා කිරීම් и අපි එය රේඛීය ආකාරයෙන් ලියන්නෙමු:
අපි මෙම සීමාවන් රේඛීය සීමා වස්තුවක් ලෙස අර්ථ දක්වමු:
import numpy as np
from scipy.optimize import LinearConstraint
linear_constraint = LinearConstraint ([[1, 2], [2, 1]], [-np.inf, 1], [1, 1])
අවසාන වශයෙන් අනුකෘති ආකාරයෙන් රේඛීය නොවන සීමාව:
මෙම සීමාව සඳහා අපි Jacobian matrix නිර්වචනය කරමු සහ හිතුවක්කාර දෛශිකයක් සහිත Hessian matrix හි රේඛීය සංයෝජනයකි :
දැන් අපට රේඛීය නොවන සීමාවක් වස්තුවක් ලෙස අර්ථ දැක්විය හැක 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)
ප්රමාණය විශාල නම්, න්යාස විරල ආකාරයෙන් ද දැක්විය හැක:
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)
හෝ වස්තුවක් ලෙස 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)
Hessian matrix ගණනය කිරීමේදී විශාල උත්සාහයක් අවශ්යයි, ඔබට පන්තියක් භාවිතා කළ හැකිය HessianUpdateStrategy
BFGS
и SR1
.
from scipy.optimize import BFGS
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=BFGS())
Hessian ද පරිමිත වෙනස්කම් භාවිතයෙන් ගණනය කළ හැක:
nonlinear_constraint = NonlinearConstraint (cons_f, -np.inf, 1, jac = cons_J, hess = '2-point')
සීමා කිරීම් සඳහා Jacobian matrix ද පරිමිත වෙනස්කම් භාවිතයෙන් ගණනය කළ හැක. කෙසේ වෙතත්, මෙම අවස්ථාවෙහිදී Hessian matrix පරිමිත වෙනස්කම් භාවිතයෙන් ගණනය කළ නොහැක. Hessian යනු ශ්රිතයක් ලෙස හෝ HessianUpdateStrategy පන්තිය භාවිතා කරමින් අර්ථ දැක්විය යුතුය.
nonlinear_constraint = NonlinearConstraint (cons_f, -np.inf, 1, jac = '2-point', hess = BFGS ())
ප්රශස්තිකරණ ගැටලුවට විසඳුම මේ වගේ ය:
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]
අවශ්ය නම්, Hessian ගණනය කිරීමේ කාර්යය 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)
හෝ පරාමිතිය හරහා Hessian සහ අත්තනෝමතික දෛශිකයේ නිෂ්පාදිතය 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)
විකල්පයක් ලෙස, ප්රශස්ත කරන ශ්රිතයේ පළමු සහ දෙවන ව්යුත්පන්නයන් දළ වශයෙන් ගණනය කළ හැක. උදාහරණයක් ලෙස, Hessian ශ්රිතය භාවිතයෙන් ආසන්න කළ හැක SR1
(අර්ධ-නිව්ටෝනියානු ආසන්න වශයෙන්). අනුක්රමණය සීමිත වෙනස්කම් මගින් ආසන්න කළ හැක.
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)
කොන්දේසි සහිත ප්රශස්තකරණ ක්රමය="SLSQP"
SLSQP ක්රමය නිර්මාණය කර ඇත්තේ පෝරමයේ ශ්රිතයක් අවම කිරීමේ ගැටළු විසඳීම සඳහා ය:
කොහෙද? и - සමානාත්මතා හෝ අසමානතා ආකාරයෙන් සීමා කිරීම් විස්තර කරන ප්රකාශන දර්ශක කට්ටල. - ශ්රිතයේ අර්ථ දැක්වීමේ වසම සඳහා පහළ සහ ඉහළ මායිම් කට්ටල.
රේඛීය සහ රේඛීය නොවන සීමාවන් යතුරු සහිත ශබ්දකෝෂ ආකාරයෙන් විස්තර කෙරේ 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])
}
අවම සෙවීම පහත පරිදි සිදු කෙරේ:
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 ]
Optimization උදාහරණය
පස්වන තාක්ෂණික ව්යුහයට සංක්රමණය වීම සම්බන්ධයෙන්, අපට කුඩා නමුත් ස්ථාවර ආදායමක් ගෙන එන වෙබ් චිත්රාගාරයක උදාහරණය භාවිතා කරමින් නිෂ්පාදන ප්රශස්තිකරණය දෙස බලමු. නිෂ්පාදන වර්ග තුනක් නිෂ්පාදනය කරන ගැලී අධ්යක්ෂක ලෙස අප සිතමු:
- x0 - 10 tr සිට ගොඩබෑමේ පිටු විකිණීම.
- x1 - ආයතනික වෙබ් අඩවි, 20 tr සිට.
- x2 - මාර්ගගත වෙළඳසැල්, 30 tr සිට.
අපගේ මිත්රශීලී ක්රියාකාරී කණ්ඩායමට කනිෂ්ඨයන් හතර දෙනෙක්, මධ්යම ක්රීඩකයින් දෙදෙනෙක් සහ එක් ජ්යෙෂ්ඨයෙක් ඇතුළත් වේ. ඔවුන්ගේ මාසික වැඩ කාල අරමුදල:
- ජූනි:
4 * 150 = 600 чел * час
, - මැද:
2 * 150 = 300 чел * час
, - වැඩිහිටි:
150 чел * час
.
ලබා ගත හැකි පළමු කනිෂ්ඨයාට (x0, x1, x2), මැද - (10, 20, 30), ජ්යෙෂ්ඨ - (7, 15, 20) එක් වෙබ් අඩවියක් සංවර්ධනය කිරීම සහ යෙදවීම සඳහා පැය (5, 10, 15) වැය කිරීමට ඉඩ දෙන්න. ) ඔබේ ජීවිතයේ හොඳම කාලය පැය.
ඕනෑම සාමාන්ය අධ්යක්ෂකවරයෙකු මෙන්, අපට අවශ්ය වන්නේ මාසික ලාභය උපරිම කිරීමටයි. සාර්ථකත්වයේ පළමු පියවර වන්නේ වෛෂයික කාර්යය ලිවීමයි value
මසකට නිෂ්පාදනය කරන නිෂ්පාදන වලින් ලැබෙන ආදායම ලෙස:
def value(x):
return - 10*x[0] - 20*x[1] - 30*x[2]
මෙය දෝෂයක් නොවේ; උපරිමය සෙවීමේදී, ප්රතිවිරුද්ධ ලකුණ සමඟ වෛෂයික ශ්රිතය අවම වේ.
මීළඟ පියවර වන්නේ අපගේ සේවකයින් වැඩිපුර වැඩ කිරීම තහනම් කිරීම සහ වැඩ කරන වේලාවන් සඳහා සීමාවන් හඳුන්වා දීමයි:
සමාන වන්නේ කුමක්ද:
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]])
}
විධිමත් සීමාවක් වන්නේ නිෂ්පාදන ප්රතිදානය ධනාත්මක විය යුතු බවයි:
bnds = Bounds ([0, 0, 0], [np.inf, np.inf, np.inf])
අවසාන වශයෙන්, වඩාත්ම රෝස උපකල්පනය නම්, අඩු මිල සහ ඉහළ ගුණාත්මකභාවය නිසා, තෘප්තිමත් පාරිභෝගිකයින්ගේ පෝලිමක් අප වෙනුවෙන් නිරන්තරයෙන් පෙළ ගැසී සිටින බවයි. සීමා සහිත ප්රශස්තිකරණ ගැටළුව විසඳීම මත පදනම්ව අපට මාසික නිෂ්පාදන පරිමාවන් අප විසින්ම තෝරා ගත හැකිය. 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]
අපි සම්පූර්ණ සංඛ්යාවලට ලිහිල්ව වට කර නිෂ්පාදනවල ප්රශස්ත බෙදා හැරීමක් සමඟ ඔරු කරුවන්ගේ මාසික බර ගණනය කරමු x = (8, 6, 3)
:
- ජූනි:
8 * 10 + 6 * 20 + 3 * 30 = 290 чел * час
; - මැද:
8 * 7 + 6 * 15 + 3 * 20 = 206 чел * час
; - වැඩිහිටි:
8 * 5 + 6 * 10 + 3 * 15 = 145 чел * час
.
නිගමනය: අධ්යක්ෂවරයාට ඔහුගේ සුදුසු උපරිමය ලබා ගැනීම සඳහා, මසකට ගොඩබෑමේ පිටු 8 ක්, මධ්යම ප්රමාණයේ අඩවි 6 ක් සහ වෙළඳසැල් 3 ක් නිර්මාණය කිරීම ප්රශස්ත වේ. මෙම අවස්ථාවේ දී, ජ්යෙෂ්ඨ යන්ත්රය සිට ඉහළට නොබලා සීසෑම කළ යුතුය, මැද භාගයේ බර ආසන්න වශයෙන් 2/3 ක් වනු ඇත, කනිෂ්ඨයන් අඩකට වඩා අඩුය.
නිගමනය
පැකේජය සමඟ වැඩ කිරීම සඳහා මූලික තාක්ෂණික ක්රම මෙම ලිපියෙන් දැක්වේ scipy.optimize
, කොන්දේසි සහිත අවම කිරීමේ ගැටළු විසඳීමට භාවිතා කරයි. පුද්ගලිකව මම භාවිතා කරමි scipy
සම්පූර්ණයෙන්ම ශාස්ත්රීය අරමුණු සඳහා, ලබා දී ඇති උදාහරණය එවැනි විකට ස්වභාවයක් ඇත්තේ එබැවිනි.
න්යාය සහ අතථ්ය උදාහරණ රාශියක් සොයාගත හැකිය, නිදසුනක් ලෙස, I.L. Akulich විසින් "උදාහරණ සහ ගැටළු වල ගණිතමය වැඩසටහන්කරණය" පොතේ. වඩාත් දැඩි යෙදුම scipy.optimize
රූප සමූහයකින් ත්රිමාණ ව්යුහයක් ගොඩනැගීමට (
ප්රධාන තොරතුරු මූලාශ්රය වන්නේ scipy
වෙත සාදරයෙන් පිළිගනිමු
ස්තුතියි
මූලාශ්රය: www.habr.com