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

خوارزمية بيلمان-فورد

آخر تحديث

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

بعد V - 1 مرة على جميع الحواف، يكون قد تم إيجاد كل أقصر مسار (الذي يمكن أن يحوي V - 1 حافة على الأكثر). هذا يجعلها O(V · E) - أبطأ من Dijkstra، لكنها تتعامل مع الأوزان السالبة ويمكنها اكتشاف دورة ذات وزن سالب (إذا كانت المرة V لا تزال تخفّف حافة، فلا وجود لأقصر مسار).

التعقيد الزمني والمكاني

المقياسالتعقيدملاحظات
الزمنO(V · E)V − 1 مرة على جميع حواف E
المكانO(V)مسافة واحدة لكل عقدة
الأوزان السالبةمدعومةميزتها الأساسية على Dijkstra
الدورات السالبةقابلة للاكتشافمرة V التي تخفّف تشير إلى وجود واحدة

خطوة بخطوة

الخطوةماذا يحدث
1اضبط مسافة المصدر على 0 وكل البقية على ما لا نهاية.
2كرّر الخطوة التالية V − 1 مرة.
3لكل حافة (u → v, w)، تحقّق مما إذا كان dist[u] + w < dist[v].
4إن كان كذلك، خفّفها: اضبط dist[v] = dist[u] + w.
5توقّف مبكرًا إذا لم تُحدث مرة كاملة أي تغيير.

مثال محلول

المصدر S على 4 عقد S, A, B, C مع الحواف S→A (4)، S→B (5)، A→C (3)، B→A (-3)، تُخفَّف بهذا الترتيب. تبدأ المسافات عند S=0 وكل شيء آخر عند :

المرةالمسافات [S, A, B, C]الإجراء
Init[0, ∞, ∞, ∞]مسافة المصدر هي 0، وكل البقية ما لا نهاية.
1[0, 2, 5, 7]تخفّف S→A إلى 4، وS→B إلى 5، وA→C إلى 7، ثم تخفض B→A قيمة A إلى 5 + (-3) = 2.
2[0, 2, 5, 5]تحسّن A→C الآن C إلى 2 + 3 = 5؛ ولا تُخفَّف أي حافة أخرى.
3[0, 2, 5, 5]لا تُخفَّف أي حافة، لذا فالمسافات نهائية: تكلفة A هي 2 عبر S→B→A.

متى تستخدم بيلمان-فورد

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

كود Bellman-Ford Algorithm

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

كود Bellman-Ford Algorithm بلغة Python

Python
1def bellman_ford(vertices, edges, start):2    dist = {v: float("inf") for v in vertices}3    dist[start] = 04    # Relax every edge V-1 times5    for _ in range(len(vertices) - 1):6        for u, v, w in edges:7            if dist[u] + w < dist[v]:8                dist[v] = dist[u] + w9    # One more pass: any improvement means a negative cycle10    for u, v, w in edges:11        if dist[u] + w < dist[v]:12            raise ValueError("Graph contains a negative-weight cycle")13    return dist14
15
16vertices = ["A", "B", "C", "D", "E"]17edges = [18    ("A", "B", 6), ("A", "C", 7), ("B", "D", 5), ("B", "E", -4),19    ("C", "D", -3), ("D", "B", -2), ("E", "D", 7),20]21
22for node, d in bellman_ford(vertices, edges, "A").items():23    print(f"A -> {node}: {d}")
شغّل هذا الكود في ساحة تجربة Python

الأسئلة الشائعة حول بيلمان-فورد

ما هو التعقيد الزمني لبيلمان-فورد؟
تعمل بيلمان-فورد في زمن O(V · E): تقوم بـ V - 1 مرة، وتخفّف كل مرة جميع حواف E. هذا أبطأ من O((V + E) log V) الخاص بـ Dijkstra، وهو ثمن دعم أوزان الحواف السالبة.
متى ينبغي أن أستخدم بيلمان-فورد بدلًا من Dijkstra؟
استخدم بيلمان-فورد عندما يمكن أن يحتوي الرسم البياني على أوزان حواف سالبة، أو عندما تحتاج إلى اكتشاف دورات ذات وزن سالب. Dijkstra أسرع لكنها صحيحة فقط مع الأوزان غير السالبة. من الاستخدامات الواقعية الشائعة اكتشاف المراجحة في صرف العملات، حيث تكون الدورات السالبة مهمة.
كيف تكتشف بيلمان-فورد دورة سالبة؟
بعد V - 1 مرة من التخفيف، تكون جميع أقصر المسارات نهائية إذا لم تكن هناك دورة سالبة. إذا كان بإمكان مرة إضافية أن تخفّف حافة، فهناك دورة ذات وزن سالب يمكن الوصول إليها، وتصبح أقصر المسارات غير معرّفة (يمكنك الدوران إلى ما لا نهاية لخفض التكلفة).
ما الفرق بين بيلمان-فورد وفلويد-وارشال؟
تحسب بيلمان-فورد أقصر المسارات من مصدر واحد في O(V · E)، بينما تحسب فلويد-وارشال أقصر المسارات بين جميع الأزواج في O(V³). على رسم بياني كثيف، يكلّف تشغيل بيلمان-فورد من كل مصدر O(V² · E)، لذا تكون فلويد-وارشال عادةً الخيار الأفضل عندما تحتاج إلى جميع الأزواج. كلتاهما تتعامل مع الحواف السالبة ويمكنهما الإشارة إلى الدورات السالبة.
لماذا تحتاج بيلمان-فورد إلى V - 1 مرة بالضبط؟
أي أقصر مسار في رسم بياني بلا دورات سالبة يستخدم V - 1 حافة على الأكثر، لأن المسار الذي يزور أكثر من V عقدة يجب أن يكرّر واحدة. تضمن كل مرة تخفيف حافة إضافية واحدة على الأقل من كل أقصر مسار بشكل صحيح، لذا تكفي V - 1 مرة لتثبيتها جميعًا. من المفاهيم الخاطئة الشائعة أن زيادة المرات تحسّن النتيجة - وهي لا تفعل ذلك أبدًا ما لم توجد دورة سالبة.
هل يمكن أن تتوقف بيلمان-فورد مبكرًا؟
نعم. إذا لم تخفّف مرة كاملة على جميع الحواف أي شيء، فإن جميع المسافات تكون بالفعل مثلى ويمكنك التوقف قبل بلوغ V - 1 مرة. غالبًا ما يجعلها تحسين الخروج المبكر هذا أسرع بكثير على الرسوم البيانية التي تتقارب بسرعة، رغم أن حد أسوأ الحالات يبقى O(V · E).
Coddy programming languages illustration

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

ابدأ الآن