SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy (تلفظ سائی پائی) ایک نمپی پر مبنی ریاضی کا پیکیج ہے جس میں C اور Fortran لائبریریاں بھی شامل ہیں۔ SciPy آپ کے انٹرایکٹو Python سیشن کو MATLAB، IDL، Octave، R، یا SciLab جیسے مکمل ڈیٹا سائنس ماحول میں بدل دیتا ہے۔

اس مضمون میں، ہم ریاضیاتی پروگرامنگ کی بنیادی تکنیکوں کو دیکھیں گے - scipy.optimize پیکیج کا استعمال کرتے ہوئے متعدد متغیرات کے اسکیلر فنکشن کے لیے مشروط اصلاح کے مسائل کو حل کرنا۔ غیر محدود اصلاحی الگورتھم پر پہلے ہی بحث ہو چکی ہے۔ آخری آرٹیکل. ہیلپ() کمانڈ، Shift+Tab یا in کا ​​استعمال کرتے ہوئے مزید تفصیلی اور تازہ ترین مدد ہمیشہ ہی سکیپی فنکشنز پر حاصل کی جا سکتی ہے۔ سرکاری دستاویزات.

تعارف

scipy.optimize پیکیج میں مشروط اور غیر محدود اصلاح کے مسائل کو حل کرنے کے لیے ایک مشترکہ انٹرفیس فنکشن کے ذریعے فراہم کیا گیا ہے۔ minimize(). تاہم، یہ معلوم ہے کہ تمام مسائل کو حل کرنے کے لئے کوئی عالمگیر طریقہ نہیں ہے، لہذا ایک مناسب طریقہ کا انتخاب، ہمیشہ کی طرح، محقق کے کندھوں پر آتا ہے.
مناسب اصلاحی الگورتھم فنکشن آرگومنٹ کا استعمال کرتے ہوئے بیان کیا گیا ہے۔ minimize(..., method="").
متعدد متغیرات کے فنکشن کی مشروط اصلاح کے لیے، درج ذیل طریقوں کے نفاذ دستیاب ہیں:

  • trust-constr - اعتماد والے علاقے میں مقامی کم از کم تلاش کریں۔ ویکی مضمون, Habré پر مضمون;
  • SLSQP - رکاوٹوں کے ساتھ ترتیب وار چوکور پروگرامنگ، لگرینج سسٹم کو حل کرنے کے لیے نیوٹنین طریقہ۔ ویکی مضمون.
  • TNC - کٹا ہوا نیوٹن محدود، محدود تعداد میں تکرار، بڑی تعداد میں آزاد متغیر کے ساتھ نان لائنر فنکشنز کے لیے اچھا ہے۔ ویکی مضمون.
  • L-BFGS-B — Broyden–Fletcher–Goldfarb–Shanno ٹیم کا ایک طریقہ، جسے Hessian میٹرکس سے ویکٹرز کی جزوی لوڈنگ کی وجہ سے میموری کی کم استعمال کے ساتھ لاگو کیا گیا۔ ویکی مضمون, Habré پر مضمون.
  • COBYLA - لکیری قریب کے ذریعہ MARE محدود اصلاح، لکیری قریب کے ساتھ محدود اصلاح (بغیر میلان حساب کے)۔ ویکی مضمون.

منتخب کردہ طریقہ پر منحصر ہے، مسئلہ کو حل کرنے کے لئے شرائط اور پابندیاں مختلف طریقے سے مقرر کی جاتی ہیں:

  • کلاس آبجیکٹ Bounds طریقوں کے لیے L-BFGS-B, TNC, SLSQP, trust-constr;
  • فہرست (min, max) انہی طریقوں کے لیے L-BFGS-B, TNC, SLSQP, trust-constr;
  • ایک شے یا اشیاء کی فہرست LinearConstraint, NonlinearConstraint COBYLA، SLSQP، اعتماد سازی کے طریقوں کے لیے؛
  • لغت یا لغات کی فہرست {'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 کی بنیاد پر EQSQP مساوات کی شکل میں رکاوٹوں کے ساتھ مسائل کے لیے سفر عدم مساوات کی شکل میں رکاوٹوں کے ساتھ مسائل کے لیے۔ دونوں طریقے الگورتھم کے ذریعے اعتماد کے علاقے میں مقامی کم از کم تلاش کرنے کے لیے لاگو کیے جاتے ہیں اور بڑے پیمانے پر مسائل کے لیے موزوں ہیں۔

عام شکل میں کم از کم تلاش کرنے کے مسئلے کی ریاضیاتی تشکیل:

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

سخت مساوات کی رکاوٹوں کے لیے، نچلی حد اوپری باؤنڈ کے برابر مقرر کی گئی ہے۔ SciPy، حالات کے ساتھ اصلاح.
ایک طرفہ رکاوٹ کے لیے، اوپری یا نچلی حد مقرر کی گئی ہے۔ np.inf متعلقہ نشان کے ساتھ۔
دو متغیرات کے کم از کم معروف روزن بروک فنکشن کو تلاش کرنا ضروری ہے:

SciPy، حالات کے ساتھ اصلاح

اس صورت میں، اس کی تعریف کے ڈومین پر درج ذیل پابندیاں مقرر کی گئی ہیں:

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

ہمارے معاملے میں، نقطہ پر ایک منفرد حل ہے SciPy، حالات کے ساتھ اصلاحجس کے لیے صرف پہلی اور چوتھی پابندیاں درست ہیں۔
آئیے نیچے سے اوپر تک پابندیوں سے گزرتے ہیں اور دیکھتے ہیں کہ ہم انہیں کیسے لکھ سکتے ہیں۔
پابندیاں SciPy، حالات کے ساتھ اصلاح и SciPy، حالات کے ساتھ اصلاح آئیے باؤنڈ آبجیکٹ کا استعمال کرتے ہوئے اس کی وضاحت کرتے ہیں۔

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

پابندیاں SciPy، حالات کے ساتھ اصلاح и SciPy، حالات کے ساتھ اصلاح آئیے اسے لکیری شکل میں لکھتے ہیں:

SciPy، حالات کے ساتھ اصلاح

آئیے ان رکاوٹوں کو ایک LinearConstraint آبجیکٹ کے طور پر بیان کریں:

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

اور آخر کار میٹرکس کی شکل میں نان لائنر رکاوٹ:

SciPy، حالات کے ساتھ اصلاح

ہم اس رکاوٹ کے لیے جیکوبیئن میٹرکس کی وضاحت کرتے ہیں اور ایک صوابدیدی ویکٹر کے ساتھ ہیسیئن میٹرکس کا ایک لکیری مجموعہ SciPy، حالات کے ساتھ اصلاح:

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

اب ہم ایک شے کے طور پر ایک nonlinear constraint کی وضاحت کر سکتے ہیں۔ 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 میٹرکس کا حساب لگاتے وقت SciPy، حالات کے ساتھ اصلاح بہت محنت کی ضرورت ہے، آپ کلاس استعمال کر سکتے ہیں۔ HessianUpdateStrategy. مندرجہ ذیل حکمت عملی دستیاب ہیں: BFGS и SR1.

from scipy.optimize import BFGS

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

ہیسین کو محدود فرق کا استعمال کرتے ہوئے بھی شمار کیا جا سکتا ہے:

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

محدود فرقوں کا استعمال کرتے ہوئے رکاوٹوں کے لیے Jacobian میٹرکس کا حساب بھی لگایا جا سکتا ہے۔ تاہم، اس معاملے میں ہیسیئن میٹرکس کو محدود فرق کا استعمال کرتے ہوئے شمار نہیں کیا جا سکتا۔ 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]

اگر ضروری ہو تو، ہیسین کا حساب لگانے کے فنکشن کو 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 طریقہ فارم میں کسی فنکشن کو کم سے کم کرنے کے مسائل کو حل کرنے کے لیے ڈیزائن کیا گیا ہے:

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

SciPy، حالات کے ساتھ اصلاح

Где SciPy، حالات کے ساتھ اصلاح и SciPy، حالات کے ساتھ اصلاح - مساوات یا عدم مساوات کی شکل میں پابندیوں کو بیان کرنے والے اظہار کے اشاریہ جات کے سیٹ۔ SciPy، حالات کے ساتھ اصلاح - فنکشن کی تعریف کے ڈومین کے لیے نچلے اور اوپری حدود کے سیٹ۔

لکیری اور غیر خطی رکاوٹوں کو کلیدوں کے ساتھ لغات کی شکل میں بیان کیا گیا ہے۔ 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 ]

اصلاح کی مثال

پانچویں تکنیکی ڈھانچے میں منتقلی کے سلسلے میں، آئیے ویب اسٹوڈیو کی مثال کا استعمال کرتے ہوئے پروڈکشن آپٹیمائزیشن پر نظر ڈالتے ہیں، جس سے ہمیں ایک چھوٹی لیکن مستحکم آمدنی ہوتی ہے۔ آئیے اپنے آپ کو ایک گیلی کے ڈائریکٹر کے طور پر تصور کریں جو تین قسم کی مصنوعات تیار کرتی ہے:

  • 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]

یہ کوئی غلطی نہیں ہے؛ زیادہ سے زیادہ تلاش کرتے وقت، معروضی فنکشن کو مخالف نشان کے ساتھ کم کیا جاتا ہے۔

اگلا مرحلہ یہ ہے کہ ہمارے ملازمین کو زیادہ کام کرنے سے روکا جائے اور کام کے اوقات پر پابندیاں متعارف کرائی جائیں:

SciPy، حالات کے ساتھ اصلاح

مساوی کیا ہے:

SciPy، حالات کے ساتھ اصلاح

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 تصاویر کے سیٹ سے 3D ڈھانچہ بنانا (Habré پر مضمون) میں دیکھا جا سکتا ہے۔ مسالہ دار باورچی کتاب.

معلومات کا بنیادی ذریعہ ہے۔ docs.scipy.orgجو لوگ اس اور دیگر حصوں کے ترجمے میں تعاون کرنا چاہتے ہیں۔ scipy میں خوش آمدید GitHub کے.

شکریہ mephistophees اشاعت کی تیاری میں شرکت کے لیے۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں