12.5 استخدام العَودية لحل المسائل
أهداف التعلم
في نهاية هذا القسم، ينبغي أن تكون قادرًا على:
- استخدام العَودية للبحث بكفاءة في قائمة.
- عرض حل لمشكلة الأبراج الثلاثة.
البحث الثنائي
عادةً ما يتطلب البحث في قائمة مرتبة فحص كل عنصر. إذا لم يُعثر على العنصر المطلوب، فقد يستغرق البحث وقتًا طويلاً.
البحث الثنائي خوارزمية عَودية تُستخدم للبحث بكفاءة في القوائم المرتبة. في كل خطوة عَودية، يُستبعد حوالي نصف العناصر بوصفها غير مطابقة محتملة، لذا يتقدم البحث بشكل أسرع بكثير.
يبدأ البحث الثنائي بفحص العنصر الأوسط في القائمة. إذا عُثر على مفتاح البحث، تُرجع الخوارزمية الموقع المطابق (الحالة الأساسية). وإلا، يتكرر البحث على حوالي نصف القائمة. إذا كان المفتاح أكبر من العنصر الأوسط، فلا بد أن المفتاح في النصف الأيمن، والعكس صحيح. تستمر العملية بفحص العنصر الأوسط للنصف المتبقي من القائمة.
مثال 12.3
البحث الثنائي
""" Binary Search """
def binary_search(search_list, low, high, key):
# التحقق من الحالة الأساسية
if high > low:
mid = (high + low) // 2
# إذا كان العنصر موجودًا في المنتصف
if search_list[mid] == key:
return mid
# الحالة العَودية: تحديد أي مصفوفة فرعية يجب فحصها
# المصفوفة الفرعية اليمنى
elif key > search_list[mid]:
return binary_search(search_list, mid + 1, high, key)
# المصفوفة الفرعية اليسرى
else:
return binary_search(search_list, low, mid - 1, key)
else:
# المفتاح غير موجود (حالة أساسية أخرى)
return "Not found"
# قائمة اختبار
in_list = [1, 3, 13, 16, 19, 22, 27, 32, 48, 66, 78, 99, 111, 122]
# استدعاء دالّة البحث الثنائي
print(binary_search(in_list, 0, len(in_list)-1, 48)) # المفتاح موجود في الفهرس 8
print(binary_search(in_list, 0, len(in_list)-1, 86)) # المفتاح غير موجود
ناتج الشِفرة أعلاه:
8
Not found
مفاهيم تطبيقية
البحث الثنائي
حل مشكلة الأبراج الثلاثة
كما نوقش في قسم سابق، يمكن حل مشكلة الأبراج الثلاثة بالعَودية. يعتمد الحل على استدعاء حل المسألة الأصغر التالية مرتين. وكما هو موضح في مثال الشِفرة أدناه، يمكن للحل العَودي أن يحل المشكلة لأي عدد من الحلقات.
مثال 12.4
حل مشكلة N من الأبراج
حل مشكلة الأبراج الثلاثة بسيط بالعَودية. في الشِفرة أدناه، تُرقَّم الحلقات من الأعلى إلى الأسفل. أصغر حلقة هي 1، والحلقة التالية هي 2، وعند حل المشكلة لثلاث حلقات، تكون الحلقة السفلية هي 3.
""" Solving the towers problem recursively """
def three_towers(N, source_tower, dest_tower, temp_tower):
# الحالة الأساسية: نقل الحلقة السفلية من البرج المصدر إلى البرج الهدف
if N==1:
print("Move ring 1 from tower", source_tower, "to tower", dest_tower)
return # الخروج عند الوصول إلى الحالة الأساسية
# الحالة العَودية
# استدعاء النسخة الأصغر من المشكلة:
# لنقل مكدس N-1 إلى البرج الأوسط
three_towers(N-1, source_tower, temp_tower, dest_tower)
# نقل الحلقة N إلى البرج الهدف
print("Move ring", N, "from tower", source_tower, "to tower", dest_tower)
# استدعاء النسخة الأصغر من المشكلة:
# لنقل مكدس N-1 الآن من البرج الأوسط
# إلى البرج الهدف
three_towers(N-1, temp_tower, dest_tower, source_tower)
# شِفرة اختبار
print("Solution for 3 rings:")
three_towers(3, 't1', 't3', 't2') # t1، t2، t3 هي الأبراج
ناتج الشِفرة أعلاه:
Solution for 3 rings:
Move ring 1 from tower t1 to tower t3
Move ring 2 from tower t1 to tower t2
Move ring 1 from tower t3 to tower t2
Move ring 3 from tower t1 to tower t3
Move ring 1 from tower t2 to tower t1
Move ring 2 from tower t2 to tower t3
Move ring 1 from tower t1 to tower t3
مفاهيم تطبيقية
حل مشكلة الأبراج الثلاثة
جرّب بنفسك
توليفات العملات
اكتب دالّة عَودية باسم print_H_T() تُنتج جميع التوليفات الممكنة للوجه ("H") والذيل ("T") لعدد معين من رميات العملة.
مثال: لثلاث عملات، يجب أن يطبع البرنامج المخرجات الموضحة أدناه.
HHH
HHT
HTH
HTT
THH
THT
TTH
TTT