الفصل الرابع
Recurrences
مقدمة
أخدنا
في الفصل التاني طريقتين(Approaches)
لتصميم(Designing)
الalgorithms
أول
طريقة كانت الincremental
وشفنا
مثال عليها الinsertion
sort والطريقة
التانية كانت divide-and-conquer
وشفنا
مثال عليها الmerge
sort , وعرفنا
ايه هو الrecursion
اللي
مبني عليه طريقة الdivide-and-conquer
وقلنا
انه ببساطة الfunction
او
الalgorithms
بتنادي(call)
نفسها
علشان كدة مسمينه recursion(العودية)
يعني
بيرجع ينادي نفسه ,
في
الفصل التالت شفنا بعض الnotations
لوصف
الrunning
time لأي
algorithm
وهي
الasymptotic
notations زي
الΘ
والO
والΩ
والo
والω.
في
الفصل الرابع هنبدأ ناخد طرق لحساب
الrunning
time لalgorithms
شغالة
بالrecursion.
أولا
يعني إيه عنوان الفصل؟ يعني ايه recurrence?
كلمة
recurrence
معناها
بالعربي مبيوفيش معناها بالانجليزي ,
يعني
ايه؟ يعني هي مصطلح كامل مفيش كلمة واحدة
في اللغة العربية بنفس معناها ,
علشان
كدة أنا مش مترجم إسم الفصل على عكس الفصول
اللي عدت ,
المهم
يعني إيه recurrence?
ببساطة
recurrence
يعني
معادلة بتوصف function
بناءا
على قيمة الfunction
مع
input أقل
, إيه
الكلام ده؟ يعني بتوصف recursive
function أو
دالة بتادي نفسها لإن طبيعي الدالة بتنادي
نفسها مع input
أقل
علشان توصل لمرة وتنادي نفسها مع الbase
case(ال
base case
دي
بتكون input
الtime
بتاعه
معروف زي T(1)
= Θ(1) يعني
لما يكون الدخل بواحد algorithm
بيخلص
في constant
time) اللي
هي غالبا 1
واللي
عندنا ليها قيمة ثابتة ,
وبالتالي
الfunction
تنتهي
وإلا هتفضل تنادي نفسها طول العمر ,
نشوف
مثال علشان الأمور توضح ,
أخدنا
الmerge
sort algorithm وعرفنا
انه بيقسم(divide)
الدخل
نصين وينادي نفسه مع النص الأول وينادي
نفسه مع النص التاني وبعدين يجمع(combine
or merge) , وعرفنا
ان الmerge
او
الcombine
بيتم
في Θ(n)
والdivide
بياخد
Θ(1)
يعني
لو جمعتهم الاتنين بياخدو Θ(n)
, لو
حبينا نمثل الrunning
time للmerge
sort هنمثله
إزاي؟
T(n)
= 2T(n/2) + Θ(n)
الΘ(n)
عارفينها
بتاع الmerge او ال combine
وال2T(n/2)
ده
الوقت اللي بياخده علشان ينفذ الalgorithm
على
النص الأول والنص التاني منفصلين ,
وده
مثال لدالة بتوضح الrunning
time(function) بناءا
على قيمة الfunction
دي
على input
أقل
, يعني
ده مثال لrecurrence
, بيتهيقلي
كدة فهمنا يعني إيه recurrence
, دورنا
بقى في الفصل ده نحل الrecurrence
اللي
بالشكل ده ونجيبله قيمة واحدة زي O(n2)
كمثال.
الأمثلة
اللي هنحلها هتكون بالشكل ده
T(n)
= aT(n/b) + f(n)
a
>= 1 , b > 1
نوضح
المعادلة ,
أول
حاجة a
و
b عبارة
عن constants
, بس
لكل واحد شرط ,
a لازم
يكون أكبر من أو يساوي الواحد ,
ﻷنه
لو بصفر يبقى الterm
بتاعها
اللي هو T(n/b)
بصفر
وبالتالي الfunction
أصلا
مش بتنادي نفسها ويكون ده مش recurrence
أصلا
علشان نحله ,
أما
لو بسالب فكدة الدالة أصلا asymptotically
negative يعني
بتدي قيم سالبة لما الدخل يزيد وبكدة
منقدرش نوصفها بالasymptotic
notation لأن
من شروط الasymptotic
notation إن
الدالة تكون asymptotically
positive يعني
بتدي قيم موجبة لما الدخل يزيد ,
أما
الb
فلازم
يكون أكبر من الواحد ومينفعش يساويه حتى
لإنه لو ساواه ده معناه إن الدالة تنتادي
نفسها مع نفس الدخل ومش هتوصل للbase
case وبالتالي
مش هتبطل تنادي نفسها ,
بمناسبة
الbase
case لو
هو مش موضحها فبديهي ان الbase
case هي
T(1) =
Θ(1) وبتشتغل
على كدة ,
أما
f(n) فهي
دالة عادية زي n
او
n2
+ 3 أة
Θ(lgn)
كأمثلة.
عندنا
3 طرق
مختلفة لحل الrecurrences
وهما
الsubstitution
method
والrecursion-tree
method والmaster
method , وهنحاول
بإذن الله نوضحهم مع تجنب الmaths
على
قد منقدر.
1)
The substitution method
أول
طريقة لحل الrecurrences
معانا
هي الsubstitution
method وكلمة
method
يعني
طريقة وكلمة substitution
يعني
التعويض يعني طريقة التعويض ,
وهنعرف
ليه اتسمت الإسم ده ,
مبدأيا
الطريقة عبارة عن خطوتين أول خطوة انك
تخمن(guess)
الحل
أو بمعنى أدق شكل الحل ,
والخطوة
التانية انك تشوف التخمين ده صح ولا لأ
وتحسب الثوابت وتكون الحل النهائي بعد
ما كان معاك شكل الحل بس ,
يعني
كمثال احنا عارفين ان الrunning
time للmerge
sort بيتحسب
من الrecurrence
T(n)
= 2T(n/2) + Θ(n)
وعارفين
كمان الحل النهائي ليه وهو O(nlgn)
لو
إحنا عايزين نحل recurrence
شبهه
زي ده
T(n)
= 2T(n/2 + 10) + Θ(n)
الفرق
الوحيد في الثابت 10
اللي
احنا متوقعين انه ميأثرش كتير ﻷن عند
زيادة الدخل لأعداد كبيرة هيكون الفرق
بين n/2
و
n/2 + 10
مش
significant(واضح)
وبالتالي
احنا بنتوقع ان حل الrecurrence
ده
هو هو حل الmerge
sort اللي
هو O(nlgn)
ولكن
مش متأكدين ,
دي
كانت خطوة الguessing(التخمين)
, الخطوة
التانية بقى ان احنا نتأكد(نثبت)
إن
الحل اللي إحنا خمناه صح,
والخطوة
التانية دي بننفذها بحاجة في الرياضة
اسمها mathematical
induction فمش
هتقدر تفهم الطريقة دي 100%
غير
لما تكون فاهم الmathematical
induction , ولكن
إحنا في الشرح بنتجنب الmaths
على
قد منقدر لتسهيل المحتوى ,
ويكفينا
إننا نفهم إزاي نستخدم الطريقة ,
واللي
حابب يفهم أكتر يرجع للفصل الخامس من كتاب
الDiscrete
mathematics and its applications باسم
Induction
and Recursion.
نفهم
إزاي نستخدم الطريقة ,
أولا
من إسمها substitution
يعني
تعويض أكيد هنعوض بحاجة مكان حاجة ,
هنعوض
عن الrecursive
call term اللي
هو T(n/2)
مثلا
في معادلة ال merge
sort بإيه
بقى؟ ده بيعتمد على شكل الحل اللي انت
خمنته ,
لو
خمنت ان الحل مثلا O(n2)
فانت
عارف ان لو فيه دالة معينة k(n)
= O(n2)
فده
معناه ان k(n)
دي
asymptotically
smaller(أصغر)
من
الدالة n2
وبالتالي
ممكن تعوض عن الدالة k(n)
<= cn2
بحيث
إن الc
ده
positive
constant , الكلام
ده فاهمينه من الفصل التالت ,
وبالتالي
بتعوض عن الrecursive
call term ب
cn2
وتقلب
اشارة التساوي لأصغر من أو يساوي(علشان
انت استخدمت Big
O) وبعدبن
هيكون الtarget(الهدف)
بتاعك
انك تثبت بعد متعوض ان الـ
T(n)
<= cn2
وبالتالي
تكون T(n)
= O(n2)
وهو
الفرض اللي انت فرضته.
ناخد
مثال ونمشي معاه علشان نحاول نفهم ,
عندنا
الrecurrence
ده
T(n)
= 2T(n/2) + n
فرضا
ان انا شفت recurrence
شبهه
قبل كدة وحليته وبخمن ان الحل هيكون T(n)
= O(nlgn) دي
أول خطوة وهي الguessing
, نحاول
بقى نثبته ,
بما
اني خمنت ان الحل هيكون O(nlgn)
فانا
هعوض عن الrecursive
call term ب
cnlgn
ونحاول
نثبت ان
T(n)
<= cnlgn
الحل
:
1
T(n) = 2T(n/2) + n
2
substitute T(n/2) = c(n/2)lg(n/2)
3
T(n) <= 2c(n/2)lg(n/2) + n
4
T(n) <= cnlg(n/2) + n
5
T(n) <= cnlgn - cnlg2 + n
6
T(n) <= cnlgn - cn + n
7
T(n) <= cnlgn - n(c-1)
8
thus T(n) <= cnlgn
9
for c >= 1
وبكدة
اثبتنا الحل اللي احنا خمناه ,
في
خطوتين كدة فيهم قانونين رياضة نعرفهم
علشان يكون الاثبات مفهوم
في
السطر 5
من
الاثبات اللي حصل ان احنا عوضنا بالعلاقة
دي
cnlg(n/2)
= cnlgn - cnlg2
وده
قانون من قوانين اللوغاريتمات وهو
log(a/b)
= log(a) - log(b)
في
السطر 6
عوضنا
بالعلاقة دي
lg2
= log2(2)
= 1
في
السطر 8
استنتجنا
ان T(n)
<= cnlgn من
T(n) <=
cnlgn - n(c-1) وده
لان طبيعي ان لو x
<= y - z و
z >= 0
فاكيد
x <= y
واحنا
عارفين ان n
عدد
موجب و c
احنا
حددناه انه c
>= 1
في
ملحوظة مهمة ان لم تيجي تثبت لازم تثبت
الhypothesis(الفرضية)بالظبط
يعني انت خمنت ان الحل O(n)
لازم
تثبت ان T(n)
<= cn لو
اثبت ان T(n)
<= cn + 1 فده
غلط مع ان ال1
غير
مؤثر تماما ولكن ده شرط ال mathematical
induction.
من
الملحوظ جدا لأي حد إن الطريقة دي فيها
مشكلة ,
وهي
إن مش كل recurrence
تعرف
تخمن شكل الحل له ,
علشان
كدة الطريقة دي غالبا بتستخدم مع الطريقة
اللي هنشرحها بعدها وهي الrecursion-tree
method , بنستخدم
الrecursion-tree
method في
عملية التخمين ولكن هنا هيكون تخمين مبني
على أساس وهنكون واثقين فيه بنسبة 80%
وبعد
كدة نثبته باستخدام الsubstitution
method.
2)
The recursion-tree method
الrecursion-tree
method زي
ماقلنا ممكن تستخدم في خطوة الguessing
في
طريقة الsubstitution
, وكمان
ممكن تستخدم لوحدها من غير ما تحتاج تثبت
الناتج باستخدام الsubstitution
method , بس
ده لو اتطبقت rigorously(بشكل
دقيق جدا)
. احنا
عارفين يعني ايه recursion
وكلمة
tree يعني
شجرة ودي data
structure مشهورة
وبتستخدم كتير جدا ,
وبيكون
شكلها شبه كدة.
في
الطريقة دي بنرسم tree
مكونة
من nodes(أماكن
التخزين في الtree
data structure) كل
node
بتمثل
الcost
بتاع
call
أثناء
تنفيذ الalgorithm
, بعد
كدة بنجمع الcosts
كلها
يطلعلنا الحل ,
بنجمع
الcosts
من
خلال اننا نجمع الcost
لكل
level(مستوى
في الtree)
وبعدين
نجمع الcosts
بتاع
الlevels
. ناخد
مثال علشان نفهم ,
,والمثال
بتاعنا هيكون الmerge
sort اللي
الrecurrence
بتاعه
بالشكل ده
T(n)
= 2T(n) + Θ(n)
الbase
case بتاعه
طبعا هو T(1)
= Θ(1) , ونقدر
نعوض عن Θ(n)
= cn وبالتالي
يكون شكل الrecurrence
كدة
T(n)
= 2T(n) + cn
حيث
ان ال c
>= 1
طبعا
احنا عارفين ان في كل node
الcost
بتاعها
cn اللي
هو الcost
بتاع
الdivide
والmerge
وتنادي
على نفس الalgorithm
مرتين
مع دخل نص الدخل الحالي ,
وبالتالي
هتكون الrecursion-tree
بالشكل
ده(d).
في
شكل (a)
الcost
بتاع
الalgorithm
اللي
هو T(n)
, بعدين
في شكل (B)
الcost
بتاع
أول node
اللي
بتمثل level
1 هو
cn
وبتنادي
على الalgorithm
مع
نص الدخل مرتين بcost
يساوي
T(n/2)
لكل
نص , في
شكل (c)
نفس
الموضوع الcost
بتاع
T(n/2) هو
cn/2 وكل
واحدة تقسم الدخل وتنادي على الalgorithm
, لغاية
منوصل لدخل يساوي 1
اللي
هو ال base
case اللي
احنا عارفين قيمته T(1)
= Θ(1) أو
ممكن نعبر عنه بالconstant
c , ازاي
نجمع الcosts؟
لو جمعنا cost
كل
level
هتلاقيها
cn , وده
ممكن تحسبه بايدك لكل level
, الا
ال level
الاخير
, لان
احنا مش عارفين عدد الnodes
في
الlevel
ده
, ولكن
سهل نحسبها ,
احنا
في ال level
الاول
عدد الnodes
بيساوي
1
والlevel
التاني
يساوي 2
والlevel
التالت
يساوي 4
, لو
عبرنا عن الindex
بتاع
كل level
بi
نقدر
نحسب عدد nodes
كل
level من
خلال i2
وده
لان كل node
بنفرع
منها 2
nodes ولكن
لو كنا مثلا بنفرع من كل node
عدد
4 nodes
كان
عدد الnodes
لكل
level
هيتكون
بيساوي i4
, اوك
يعني عدد الnodes
لكل
level في
الproblem
اللي
احنا شغالين عليها بيساوي i2
حيث
ان i
الindex
بتاع
الlevel
, ازاي
بقى نعرف الindex
بتاع
اخر level
او
السؤال بشكل تاني امتى الproblem
بيوصل
الدخل بتاعها ل1؟
علشان تقدر تحسب الindex
بتاع
اخر level
محتاج
تجيب علاقة تربط بين الindex
بتاع
الlevel
وحجم
الproblem
في
الlevel
ده(الدخل
يعني)
وبعدين
تساوي العلاقة دي ب 1(1
دي
هي حجم الproblem
اللي
انت عايز تحسب الindex
يتاع
الlevel
عندها)
وتجيب
قيمة الi
يبقى
هو ده الindex
بتاع
اخر level
, نجيبهاالعلاقة
دي ازاي؟ بسيطة انت عندك حجم الproblem
في
الlevel
الاول
n وفي
الlevel
التاني
n/2 وفي
الlevel
التالت
n/4 واضح
ان العلاقة اللي احنا محتاجينها هي n/2i
نساويها
ب 1
ونجيب
قيمة الi
يطلع
الi
بيساوي
lgn وهو
ده الindex
بتاع
اخر level
وعلشان
اول index
بيساوي
صفر فكدة عدد الlevels
عندنا
بيساوي lgn
+ 1 , نحسب
بقى عدد الnodes
في
اخر level
هيطلع
(lgn)2
= (i2)
وده
بيساوي nlg2(لان
في قاعدة في اللوغاريتمات alogb(c)
= clogb(a)
وده
بيساوي n(لان
lg2 = 1)
, وعلشان
كل node
في
اخر level
(ال
base
case) الcost
بتاعها
بيساوي c
وعدد
يبقى الcost
بتاع
اخر level
برده
بيساوي cn
, اذا
الlevels
كلها
الcost
بتاعها
موحد وهو cn
, فعلشان
نخسب الcost
بتاع
الlevels
كلها
نضرب عدد الlevels
في
الcost
بتاع
الlevel
الواحد
, فيطلع
معانا الcost
الكلي
(lgn + 1)
* cn = cnlgn + cn وبالتالي
الناتج النهائي
T(n)
= O(nlgn)
تقدر
بعد كدة تتأكد من الحل ده باستخدام
الsubstitution
method.
3)
The master method
الmaster
method هي
آخر طريقة معانا لحل الrecurrences
, وهي
فالواقع أفضلهم وأسهلهم ,
من
اسمها master
يعني
سيد
يعني هي سيدة الطرق كلها ,
الطريقة
مش محتاجة أي maths
في
تطبيقها ,
ودي
أفضل حاجة ,
هي
عبارة عن 3
cases(حالات)
بتعرفهم
وتطبقهم ,
بتشوف
الproblem
بتاعتك
ينطبق عليها اي case
منهم
وبعد كدة الحل بيكون جاهز.
الmaster
method مبنية
على نطرية بنفس الاسم master
theorem , النظرية
بتقول إيه بقى؟ بتقول ان لو عندك recurrence
بالشكل
ده
T(n)
= aT(n/b) + f(n)
واحنا
عرفنا في مقدمة الفصل الform(الشكل)
ده
وقلنا شروط الa
والb
والf(n)
, انجز
بقى النظرية بتقول إيه؟ بتقول انك هتقارن
الf(n)
بالدالة
دي nlogb(a)
وبناءا
عليه هيبقى معانا 3
cases:
1)
لو
ال f(n)
<= nlogb(a)
واصغر
من معناها حاجتين اول حاجة ان ال f(n)
تكون
asymptotically
smaller يعني
ال nlogb(a)
تعتبر
upper
bound لل
f(n)
وتاني
حاجة ان ال f(n)
تكون
polynomially
smaller يعني
يكون أعلى أس فيها أقل من أعلى أس للدالة
nlogb(a)
والشرطين
دول بيتعبر عنهم بالشكل ده
f(n)
= O( nlogb(a)
- ε) , ε > 0
طبعا
ال big
O خاص
بالشرط الأول اللي هو asymptotically
smaller وال
ε خاص
بالشرط التاني اللي هو polynomially
smaller.
الحل
في الحالة دي بيكون
T(n)
= Θ(nlogb(a))
2)
لو
f(n) = Θ(
nlogb(a)
وده
معناه ان ال f(n)
في
نفس range
الدالة
nlogb(a)
يعني
الدالة nlogb(a)
تكون
tight
bound للدالة
f(n) وده
بيتعبر عنه بالشكل ده
f(n)
= Θ(nlogb(a))
الحل
في الحالة دي بيكون
T(n)
= Θ( nlogb(a)
* lgn)
3)
الحالة
دي عكس الأولى f(n)
>= nlogb(a)
يعني
ال f(n)
تكون
asymptotically
larger وكمان
polynomially
larger وده
بيتعبر عنه بالشكل ده
f(n)
= Ω( nlogb(a)
+ ε) , ε > 0
بس
الحالة دي فيها شرط زيادة غريب شوية اسمه
ال regularity
condition(شرط
الانتظام)
وبيقول
af(n/b)
<= cf(n) for c < 1 والنظرية
ليها إثبات رياضي طويل مش هنخوض فيه طبعا
الحل
في الحالة دي بيكون
T(n)
= Θ(f(n)
ناخد
3 أمثلة
علشان الأمور توضح :
1)
T(n) = 4T(n/2) + n
a
= 4 , b = 2 , f(n) = n
logb(a)
= log2(4)
= 2
nlogb(a)
= n2
دي
الحالة الأولى إن
f(n)
= Θ( nlogb(a)
- ε)
حيث
ان ε =
1
وبالتالي
هيكون الحل
T(n)
= Θ(n2)
2)
T(n) = 4T(n/2) + n2
ودي
الحالة التانية إن
f(n)
= Θ( nlogb(a))
وبالتالي
هيكون الحل
T(n)
= Θ(n2 lgn )
3)
T(n) = 4T(n/2) + n3
ودي
الحالة التالتة إن
f(n)
= Ω(nlogb(a)
+ ε)
حيث
ان ε =
1
وشرط
الregularity
متحقق
af(n/b)
<= cf(n)
af(n/b)
= 4(n3/8)
= 0.5n3
= cf(n)
بحيث
إن ال c
= 0.5
وبالتالي
هيكون الحل
T(n)
= Θ(n3)
في
حالات لايمكن تطبيق الmaster
methos زي
الاتي
1)
الدالة
f(n)
بتكون
asymptotically
smaller بس
مش polynomially
smaller
2)
الدالة
f(n)
بتكون
asymptotically
larger بس
مش polynomiallylarger
3)
ال
regularity
condition في
case 3 مش
متحقق
Uenmen0foe-be Jason Gonnie https://marketplace.visualstudio.com/items?itemName=3quaeloca-chi.Descargar-Labyronia-RPG-2-gratuita-2021
ردحذفpidislinkbe
VcephunPsubs_i Brandon Padilla https://colab.research.google.com/drive/14EUYiLmWnTs2XiNTykpEDqyMbOnqh0m5
ردحذفlink
download
download
klosunavhal
romagscon_se Been Lefevre Firefox browser
ردحذفCorel VideoStudio Pro
Click here
wadocuhab
scelicdestze Jamie Smith Click
ردحذفhotlisere