Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

خوارزمية بريم

آخر تحديث

تبني خوارزمية بريم شجرة تمدد دنيا (MST) - أرخص مجموعة من الحواف تربط كل العقد دون حلقات - عبر تنمية شجرة واحدة نحو الخارج انطلاقاً من عقدة بداية. في كل خطوة تنظر إلى كل الحواف العابرة من الشجرة إلى عقدة خارجها وتضيف الأرخص منها. اضغط تشغيل في الأعلى لمشاهدة الشجرة تتوسّع، آخذةً دائماً الحافة ذات أقل وزن التي تصل إلى عقدة جديدة.

لأنها تختار دائماً الحافة العابرة الدنيا، فإن كل إضافة آمنة (مضمون أنها جزء من إحدى شجرات التمدد الدنيا). باستخدام طابور أولوية قائم على كومة ثنائية مفهرس بأرخص حافة إلى كل عقدة خارجية، تعمل بريم في O(E log V). وهي تتناقض مع كروسكال التي تفرز كل الحواف عالمياً بدلاً من تنمية شجرة متصلة واحدة.

تعقيد الزمن والفضاء

التنفيذالتعقيدملاحظات
كومة ثنائيةO(E log V)طابور أولوية للحواف العابرة
مصفوفة التجاورO(V²)أبسط؛ جيدة للرسوم الكثيفة
الفضاءO(V + E)الانتماء للشجرة + طابور الأولوية
الأفضل لـالرسوم الكثيفةتنمو من عقدة بداية واحدة

خطوة بخطوة

الخطوةما الذي يحدث
1ابدأ الشجرة بأي عقدة مفردة.
2انظر إلى كل الحواف العابرة من الشجرة إلى عقدة خارجها.
3اختر الحافة العابرة ذات أصغر وزن.
4أضف تلك الحافة وعقدتها الجديدة إلى الشجرة.
5كرّر حتى تصبح كل العقد داخل الشجرة.

مثال محلول

بناء شجرة التمدد الدنيا لرسم من 4 عقد بالحواف A-B=1 وA-C=3 وB-C=2 وB-D=4 وC-D=5، بدءاً من A:

الخطوةالشجرةالحواف العابرةالحافة المختارة
1{A}A-B=1, A-C=3A-B (الوزن 1)
2{A, B}A-C=3, B-C=2, B-D=4B-C (الوزن 2)
3{A, B, C}B-D=4, C-D=5B-D (الوزن 4)
4{A, B, C, D}لا شيء - كل العقد في الشجرةانتهى: وزن الشجرة الدنيا 1+2+4 = 7

متى تستخدم خوارزمية بريم

استخدمها عندماتجنّبها عندما
تحتاج إلى شجرة تمدد دنيا لرسم متصل غير موجّه وموزون.يكون الرسم موجّهاً أو تحتاج إلى أقصر المسارات - استخدم ديكسترا أو بلمان-فورد بدلاً منها.
يكون الرسم كثيفاً (E قريب من )؛ صيغة المصفوفة O(V²) بسيطة وسريعة.يكون الرسم متناثراً والحواف مفروزة مسبقاً أو يسهل فرزها - كروسكال غالباً أبسط.
تريد أن تنمو الشجرة من منطقة نحو الخارج (مثل التخطيط التدريجي لشبكة).يكون الرسم غير متصل - بريم تغطي مكوّناً واحداً فقط؛ تحتاج إلى غابة تمدد دنيا.
تملك بالفعل بنية تجاور وطابور أولوية متاحين.تحتاج إلى كشف الحلقات عبر مجموعة حواف عالمية - union-find (كروسكال) أنسب لهذا الشكل.

كود Prim's Algorithm

تنفيذ نظيف وقابل للتشغيل لخوارزمية Prim's Algorithm بلغات Python, JavaScript, Java, C++, C. اختر لغة، وانسخ الكود، أو افتحه محمّلًا مسبقًا في ساحة تجربة Coddy.

كود Prim's Algorithm بلغة Python

Python
1import heapq2
3
4def prim(graph, start):5    visited = {start}6    heap = [(w, start, v) for v, w in graph[start]]7    heapq.heapify(heap)8    mst, total = [], 09    while heap and len(visited) < len(graph):10        w, u, v = heapq.heappop(heap)11        if v in visited:12            continue13        visited.add(v)14        mst.append((u, v, w))15        total += w16        # Offer the new node's edges to the frontier17        for neighbor, weight in graph[v]:18            if neighbor not in visited:19                heapq.heappush(heap, (weight, v, neighbor))20    return mst, total21
22
23graph = {24    "A": [("B", 4), ("C", 1)],25    "B": [("A", 4), ("C", 3), ("D", 2)],26    "C": [("A", 1), ("B", 3), ("D", 5)],27    "D": [("B", 2), ("C", 5), ("E", 7)],28    "E": [("D", 7)],29}30
31mst, total = prim(graph, "A")32for u, v, w in mst:33    print(f"{u} - {v} (weight {w})")34print("Total MST weight:", total)
شغّل هذا الكود في ساحة تجربة Python

الأسئلة الشائعة عن خوارزمية بريم

ما هو التعقيد الزمني لخوارزمية بريم؟
باستخدام طابور أولوية قائم على كومة ثنائية، تعمل بريم في O(E log V). أما النسخة الأبسط بمصفوفة التجاور التي تمسح الحافة العابرة الدنيا في كل خطوة فهي O(V²)، وقد تكون أسرع على الرسوم الكثيفة. وكلتاهما تستخدمان فضاء O(V + E).
ما الفرق بين خوارزمية بريم وكروسكال؟
كلتاهما تجدان شجرة تمدد دنيا بأسلوب جشِع. تنمّي بريم شجرة متصلة واحدة من عقدة بداية، مضيفةً مراراً أرخص حافة تغادر الشجرة (باستخدام طابور أولوية). أما كروسكال فتنظر في كل الحواف مرتبةً حسب الوزن وتضيف الأرخص التي لا تكوّن حلقة (باستخدام union-find). تُفضَّل بريم غالباً على الرسوم الكثيفة، وكروسكال على المتناثرة.
هل تجد خوارزمية بريم دائماً الشجرة الدنيا المثلى؟
نعم. في كل خطوة تكون أرخص حافة تعبر الشجرة الحالية آمنة للإضافة - فهي تنتمي إلى إحدى شجرات التمدد الدنيا (خاصية القطع). وإضافة الحواف الآمنة مراراً تنتج شجرة تمدد دنيا حقيقية، شرط أن يكون الرسم متصلاً.
متى ينبغي أن أستخدم خوارزمية بريم بدلاً من كروسكال؟
الجأ إلى بريم عندما يكون الرسم كثيفاً، لأن صيغتها المصفوفية O(V²) تتجنّب فرز كل الحواف E وتنمّي شجرة واحدة من عقدة بداية. أما كروسكال فتتألق على الرسوم المتناثرة حيث يكون فرز قائمة الحواف رخيصاً ويبقي union-find فحوص الحلقات سريعة. كلتاهما تنتجان شجرة دنيا صحيحة، فالاختيار يعتمد أساساً على كثافة الحواف وعلى بنى البيانات المتوفرة لديك بالفعل.
هل تؤثر عقدة البداية على الشجرة الدنيا الناتجة؟
لا - الوزن الإجمالي للشجرة الدنيا واحد بغض النظر عن العقدة التي تبدأ منها، لأن وزن شجرة التمدد الدنيا لرسم متصل فريد. لا تختلف الحواف المحددة إلا عندما تتشارك عدة حواف الوزن نفسه وتوجد شجرات دنيا متعددة. وإلا فإن بريم تصل إلى الشجرة نفسها تماماً بغض النظر عن عقدة البداية.
هل تستطيع خوارزمية بريم التعامل مع الرسوم غير المتصلة؟
ليس مباشرة. تنمّي بريم شجرة واحدة، لذا تغطي فقط المكوّن المتصل الذي يحوي عقدة البداية وتترك الباقي دون مساس. ولتغطية كل مكوّن ستشغّل بريم مراراً من عقدة غير مزارة، منتجاً غابة تمدد دنيا بدلاً من شجرة واحدة.
Coddy programming languages illustration

أتقن الخوارزميات مع Coddy

ابدأ الآن