الاستدعاء الذاتي - الذكاء الاصطناعي - ثالث ثانوي
الجزء الأول
1. أساسيات الذكاء الاصطناعي
2. خوارزميات الذكاء الاصطناعي
3. معالجة اللغات الطبيعية
الجزء الثاني
4. التعرف على الصور
5. خوارزميات التحسين واتخاذ القرار
6. الذكاء الاصطناعي والمجتمع
.2 خوارزميات الذكاء الاصطناعي سيتعرف الطالب في هذه الوحدة على بعض الخوارزميات الأساسية المستخدمة في الذكاء الاصطناعي (AI). كما سيتعلم كيف يُنشئ نظام تشخيص طبي بسيط مُستند إلى القواعد بطرائق برمجية متعددة ثم يقارن النتائج. وفي الختام سيتعلّم خوارزميات البحث وطرائق حل ألغاز المتاهة مع أخذ معايير معينة في الاعتبار. أهداف التعلم بنهاية هذه الوحدة سيكون الطالب قادرًا على أن : يُنشئ مقطعا برمجيا تكراريا. > يقارن بين خوارزمية البحث بأولوية الاتساع وخوارزمية البحث بأولوية العمق. > يصف خوارزميات البحث وتطبيقاتها. يُقارن بين خوارزميات البحث. > يصف النظام القائم على القواعد. > يُدرب نماذج الذكاء الاصطناعي حتى تتعلم حل المشكلات المعقدة. يُقيم نتائج المقطع البرمجي وكفاءة البرنامج الذي أنشأه. يُطوّر البرامج المحاكاة حلّ مشكلات الحياة الواقعية. يُقارن بين خوارزميات البحث. Ministry of Education 2024-1446 الأدوات > مفكرة جوبيتر (Jupyter Notebook) 70 70
الدرس الأول الاستدعاء الذاتي رابط الدرس الرقمي www.ien.edu.sa تقسيم المشكلة Dividing the Problem في هذا الدرس، ستتعلّم استخدام الدوال التكرارية لتبسيط البرنامج وزيادة كفاءته. تخيّل أن والداكَ قد أحضرا لك هديّة، وكنت متلهفا لمعرفتها، ولكن عندما فتحت الصندوق، وجدت صندوقًا جديدًا بداخله، وعندما فتحته، وجدت آخر بداخله ، وهكذا حتى عجزت أن تعرف في أي صندوق توجد الهدية. الاستدعاء الذاتي Recursion الاستدعاء الذاتي هو أحد طرائق حل المشكلات في علوم الحاسب، ويتم عن طريق تقسيم المشكلة إلى مجموعة من المشكلات الصغيرة المشابهة للمشكلة الأصلية حتى يُمكنك استخدام الخوارزمية نفسها لحل تلك المشكلات. يُستخدم الاستدعاء الذاتي بواسطة أنظمة التشغيل والتطبيقات الأخرى، كما تدعمه معظم لغات البرمجة. يحدث الاستدعاء الذاتي عندما تتكرر التعليمات نفسها، ولكن مع بيانات مختلفة وأقل تعقيدا. افتح الصندوق هل هناك صندوق بالداخل؟ لا تم وجدت الهدية وانتهى الاستدعاء الذاتي شكل :2.1 مثال على الاستدعاء الذاتي 71 وزارة التعليم Ministry of Education 2024-1446
72 دالة أخرى. لتلق نظرة على مثال لدالة تستدعي تستخدم دالة )len قائمة كمُعامِل مُدخل، لحساب وتحديد عدد العناصر في القائمة. استدعاء الدالة .mySumGrade def mySumGrade (grades List): sumGrade=0 l=len(gradesList) for i in range(1): sumGrade=sumGrade+gradeslist[i] return sumGrade def avgFunc (grades List): s=mySumGrade (grades List) l=len(gradesList) avg=s/l return avg # program section grades=[89,88,98,95] averageGrade=avgFunc(grades) print ("The average grade is: ",averageGrade) The average grade is: 92.5 دالة الاستدعاء التكرارية Recursive Function الدالة نفسَها وهذه الخاصية تُسمى في بعض الحالات تستدعي الاستدعاء التكراري (Recursive Call). يكون بناء الجملة العام لدالة الاستدعاء التكرارية على النحو التالي: # recursive function def recurse Function(): if (condition): # base case statement else: #recursive call recurse Function() # main program # normal function call recurse Function() الاستدعاء التكراري هو عملية استدعاء الدالة لنفسها. خاطئ البرنامج الرئيس recurseFunction() الشرط الأمر شكل :2.2 تمثيل الاستدعاء التكراري وزارة التعليم Ministry of Education 2024-1446
73 تتكون دالة الاستدعاء التكرارية من حالتين الحالة الأساسية Base Case وفي هذه الحالة تتوقف الدالة عن استدعاء نفسها، ويتأكّد الوصول إلى هذه الحالة من خلال الأمر المشروط. بدون الحالة الأساسية، ستتكرر عملية الاستدعاء الذاتي إلى ما لا نهاية. حالة الاستدعاء التكرارية Recursive Case وفي هذه الحالة تستدعي الدالة نفسها عندما لا تُحقق شرط التوقف، وتظل الدالة في حالة الاستدعاء الذاتي حتى تصل إلى الحالة الأساسية. أمثلة شائعة على الاستدعاء الذاتي Recursion Common Examples أحد الأمثلة الأكثر شيوعًا على استخدام الاستدعاء الذاتي هو عملية حساب مضروب رقم معيّن. مضروب الرقم هو الأعداد الطبيعية الأقل من أو تساوي ذلك الرقم . يُعبَّر عن المضروب بالرقم متبوعا بالعلامة "!"، على سبيل المثال، مضروب الرقم 5 هو 5 ويساوي 5*4*3*2*1. ناتج ضرب جميع جدول :21 مضروب الأرقام من 0 إلى 5 ستلاحظ أن عملية حساب المضروب تستند إلى القاعدة أدناه: 0! = 1 0! 1! = 1*1 = 1 1! 2! = 2*1=2 2! 3! = 3*2*1=63! أن 1 * !0 = !1 أو 2 * !1 = !2 الحالة الأساسية. 1 ، if n =0 n! = (n-1)! * n if n>0 أو 3* !2 = !3 4! = 4*3*2*1 = 24 | 4! ء 5!=4!*55!= 5*4*3*2*1 = 120 5! أو 4 * !3 = !4 حالة الاستدعاء التكرارية. وزارة التعليم Ministry of Education 2024-1446 شكل 2.3: قاعدة حساب المضروب لإنشاء برنامج يقوم باحتساب مضروب العدد باستخدام حلقة التكرار for ، اتبع ما يلي: # calculate the factorial of an integer using iteration def factorialLoop(n): result = 1 for i in range(2,n+1): result = result * i return result # main program num = int(input("Type a number: ")) f=factorial Loop(num) print("The factorial of " num, " is:", f) , Type a number: 3 The factorial of 3 is:6
مضروب (3) 3 * 2 مضروب (2) * مضروب (1) 1 * مضروب (0) الآن احسب مضروب العدد باستخدام دالة المضروب. #calculate the factorial of an integer using a # recursive function def factorial(x): if x == 0: • return 1 الحالة الأساسية. else: return (xfactorial(x-1)) • # main program حالة الاستدعاء التكرارية. "I is: ", f) num = int(input("Type a number: ")) f=factorial(num) print("The factorial of ", num, Type a number: 3 1 The factorial of 3 is: 6 3! = 3*2*1= 6 شكل 2.4 شجرة الاستدعاء الذاتي جدول :2.2 مزايا الاستدعاء الذاتي وعيوبه المزايا العيوب • تقلل دوال الاستدعاء التكرارية من عدد التعليمات في . في بعض الأحيان، يَصعُب تتبع منطق دوال الاستدعاء التكرارية المقطع البرمجي. • يمكن تقسيم المهمة إلى مجموعة من المشكلات الفرعية . يتطلب الاستدعاء الذاتي مزيدا من الذاكرة باستخدام الاستدعاء الذاتي. والوقت. • في بعض الأحيان، يسهل استخدام الاستدعاء الذاتي • لا يسهل تحديد الحالات التي يمكن فيها لاستبدال التكرارات المتداخلة. استخدام دوال الاستدعاء التكرارية. الاستدعاء الذاتي والتكرار Recursion and Iteration يُستخدم كل من الاستدعاء الذاتي والتكرار في تنفيذ مجموعة من التعليمات لعدة مرات، والفارق الرئيس بين الاستدعاء الذاتي والتكرار هو طريقة إنهاء الدالة التكرارية دالة الاستدعاء التكرارية تستدعي نفسها وتنهي التنفيذ عندما تصل إلى الحالة الأساسية. أما التكرار فيُنفّذ لبنة المقطع البرمجي باستمرار حتى يتحقق شرط محدد أو ينقضي عدد محدد من التكرارات. الجدول التالي يعرض بعض الاختلافات بين الاستدعاء الذاتي والتكرار. جدول 2.3 التكرار والاستدعاء الذاتي وزارة التعليم Ministry of Education 2024-1446 التكرار التنفيذ. سریع يتطلب حجم ذاكرة أقل. حجم المقطع البرمجي أكبر. ينتهي باستكمال العدد المحدد من التكرارات أو تحقيق شرط مُعيَّن. الاستدعاء الذاتي بطيء التنفيذ مقارنةً بالتكرار. يتطلب حجم ذاكرة أكبر. حجم المقطع البرمجي أصغر. ينتهي بمجرد الوصول إلى الحالة الأساسية 74
متى تستخدم الاستدعاء الذاتي؟ يُعدُّ الاستدعاء الذاتي الطريقة الأكثر ملائمة للتعامل مع المشكلة في العديد من الحالات. يسهل استكشاف بعض هياكل البيانات باستخدام الاستدعاء الذاتي بعض خوارزميات التصنيف Sorting Algorithms) ، تستخدم الاستدعاء الذاتي، مثل: التصنيف السريع . (Quick Sort) ، في المثال التالي ستستخرج أكبر رقم موجود في قائمة مكونة من الأرقام باستخدام دالة الاستدعاء التكرارية. كما يظهر في السطر الأخير من المثال دالة أخرى للتكرار لغرض المقارنة. def findMaxRecursion (A, n): if n==1: m = A[n-1] else: m = max(A[n-1], find Max Recursion (A,n-1)) return m def findMaxIteration (A,n): m = A[0] for i in range(1,n): m = return m # main program myList = max(m,A[i]) [3,73,-5,42] 1 = len(myList) myMaxRecursion = findMaxRecursion (my List,l) print("Max with recursion is: ", myMaxRecursion) myMaxIteration = findMaxIteration (my List, l) print("Max with iteration is: ", myMaxIteration) Max with recursion is: 73 Max with iteration is: 73 تستخرج الدالة ( )max العنصر ذا القيمة الأكبر العنصر ذو القيمة الأكبر في myList). max(A[3], findMaxRecursion (A, 3)) 42 ) < max(A[2], find MaxRecursion(A, 2)) -5 max(A[1], findMaxRecursion(A, 1)) 73 > 3 شكل 2.5 شجرة الاستدعاء الذاتي لدالة استخراج أكبر رقم في قائمة مكونة من الأرقام 75 وزارة التعليم Ministry of Education 2024-1446
وزارة التعليم Ministry of Education 2024-1446 في البرنامج التالي، ستُنشئ دالة استدعاء تكرارية لحساب مضاعف الرقم. ستقوم بإدخال رقمًا ( الأساس) وفهرسًا ( الأُس أو القُوَّة) يقبلهما البرنامج ، ومن ثُمَّ ستستخدم دالة الاستدعاء التكرارية ( )powerFunRecursive التي ستستخدم هذين المدخَلَين لحساب مُضاعَف الرقم. يمكن تحقيق الأمر نفسه باستخدام التكرار والمثال التالي يوضح ذلك: ، def powerFun Recursive (baseNum, expNum): if(expNum==1) : return(baseNum) else: return(baseNum*powerFunRecursive(baseNum, expNum-1 ) ) def powerFunIteration (baseNum, expNum): numPower = 1 for i in range(exp): numPower = numPower*base return numPower # main program base = int(input("Enter number: ")) exp = int(input("Enter exponent: ")) numPowerRecursion powerFunRecursive (base, exp) print( "Recursion: ", base, " raised to ", exp, numPowerIteration = powerFunIteration(base, exp) print( "Iteration: ", base, raised to ", exp, "I = Enter number: 10 Enter exponent: 3 Recursion: 10 raised to 3 = 1000 Iteration: 10 raised to 3 = 1000 "I ', numPowerRecursion) II = ',numPowerIteration) دالة الاستدعاء التكرارية اللانهائية Infinite Recursive Function يجب أن تكون حذرًا للغاية عند تنفيذ الاستدعاء التكراري، كما يجب عليك استخدام طريقة معينة لإيقاف التكرار عند تحقيق شرط مُحدَّد لتجنب حدوث الاستدعاء التكراري اللانهائي، الذي يسبّب توقف النظام عن الاستجابة بسبب كثرة استدعاءات الدالة، مما يؤدي إلى فَيْض الذاكرة Memory Overflow) وإنهاء التطبيق. 76
1 2 3 تمرينات حدد الجملة الصحيحة والجملة الخاطئة فيما يلي: 1. تتكون دالة الاستدعاء التكرارية من حالتين. 2. تستدعي دالة الاستدعاء التكرارية دالة أخرى. 3. دوال الاستدعاء التكرارية أسرع في التنفيذ. 4. استدعاء الدوال يجعل لبنة المقطع البرمجي أصغر حجمًا. 5. كتابة مقطع برمجي مُتكرّر يتطلب استدعاءً ذاتيًّا أقل. ما الاختلافات بين التكرار والاستدعاء الذاتي؟ متى يجب استخدام الاستدعاء الذاتي؟ صحيحة خاطئة 77 وزارة التعليم Ministry of Education 2024-1446
وَضّح مزايا استخدام الاستدعاء الذاتي وعيوبه. اكتب دالة استدعاء تكرارية بلغة البايثون تقوم بحساب الرقم الأكبر بترتيب محدد ( مثلا ثاني أكبر رقم) في قائمة من الأرقام. وزارة التعليم Ministry of Education 2024-1446 اكتب دالة استدعاء تكرارية بلغة البايثون لحساب مجموع كل الأرقام الزوجية في قائمة معينة. 4 5 6 78