אלגוריתם פלויד-וורשאל

מתוך המכלול, האנציקלופדיה היהודית
קפיצה לניווט קפיצה לחיפוש

אלגוריתם פלויד-וורשאל הוא אלגוריתם במדעי המחשב המשמש למציאת המסלולים הקצרים ביותר בין כל שני זוגות צמתים, בגרף ממושקל ומכוון. האלגוריתם מבוסס על פרדיגמת התכנון הדינמי. האלגוריתם פועל גם על גרפים שמכילים קשתות עם משקלים שליליים, בניגוד לאלגוריתם דייקסטרה, אבל לא על גרפים עם מעגל שלילי. סיבוכיות זמן הריצה של האלגוריתם היא .

האלגוריתם פורסם על ידי רוברט פלויד בשנת 1962 בגרסתו המוכרת לנו כיום, אך גרסאות דומות של האלגוריתם פורסמו ב-1959 על ידי ברנארד רוי, ועל ידי סטיבן וורשאל ב-1962 במטרה לחשב את הסגור הטרנזיטיבי של קבוצת קודקודים בגרף[1].

תיאור האלגוריתם

האלגוריתם מתבסס על האבחנה הבאה: אם ממספרים את קבוצת הצמתים של הגרף כך שהיא מסומנת ומסמנים בתור את משקל המסלול הקצר ביותר מהצומת אל הצומת שעובר בצומתי ביניים השייכים אך ורק לקבוצה , אז מתקיים: .

כלומר, תמיד מתקיים אחד משניים: אם המסלול הקצר ביותר מ- אל שעובר בצמתים שמספרם לכל היותר לא עובר בצומת שמספרו , ברור כי . לעומת זאת, אם המסלול הקצר כן עובר בצומת שמספרו ברור שהוא עובר בו רק פעם אחת (כי אין מעגלים שליליים בגרף, ולכן אם חוזרים לאותו צומת פעמיים מאריכים את המסלול שלא לצורך והוא לא יהיה מינימלי) ואז אפשר לפרק את המסלול לשני מסלולים: אחד שהולך מ- אל , ושני שהולך מ- אל . שני המסלולים הללו לא עוברים בצמתי ביניים שמספרם גדול מ-, ולכן סכום משקלם נתון על ידי . לכן כל מה שנותר הוא לבדוק איזו משתי השיטות עדיפה לכל צומת.

כעת, פעולת האלגוריתם היא זו: הוא מבצע איטרציות, כאשר באיטרציה ה- הוא מחשב את לכל זוג צמתים ושומר את המידע בטבלה. חישוב מתבצע בזמן בהינתן המידע מהאיטרציה הקודמת, ולכן כל איטרציה של האלגוריתם מתבצעת בזמן (מספרם של זוגות הצמתים האפשריים). לכן זמן הריצה הכולל של האלגוריתם יהיה .

המחשת האלגוריתם

  1. עבור מ-1 עד בצע:
2.1. עבור מ-1 עד בצע:
2.1.1. עבור מ-1 עד בצע:
2.1.1.1.

בסוף, היא מטריצת אורך המסלולים הקצרים ביותר שעוברים דרך הצמתים .

פסאודו קוד:

 let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity)
 for each edge (u,v)
    dist[u][v] ← w(u,v)  // the weight of the edge (u,v)
 for each vertex v
    dist[v][v] ← 0
 for k from 1 to |V|
    for i from 1 to |V|
       for j from 1 to |V|
          if dist[i][j] > dist[i][k] + dist[k][j] 
             dist[i][j] ← dist[i][k] + dist[k][j]
         end if
        end-for
    end-for
end-for

מעניין לציין שגם בהרצה בסדר "הלא נכון" האלגוריתם עובד כשורה לאחר מספר חזרות, כלומר אם נחליף את השורות:

 for k from 1 to |V|
    for i from 1 to |V|
       for j from 1 to |V|
          ...
        end-for
    end-for
end-for

באחת משתי האפשרויות:

 for _ from 1 to 3
    for i from 1 to |V|
       for j from 1 to |V|
          for k from 1 to |V|
             ...
          end-for
        end-for
    end-for
end-for
 for _ from 1 to 2
    for i from 1 to |V|
       for k from 1 to |V|
          for j from 1 to |V|
             ...
          end-for
        end-for
    end-for
end-for

האלגוריתם ירוץ כשורה

טיפול במעגלים שליליים

מעגל שלילי הוא מעגל שסכום קשתותיו קטן מאפס. בין שני קודקודים שמשתתפים במעגל שלילי לא קיים מסלול קצר ביותר, כי בכל מעבר על המעגל נקבל מסלול שמשקלו קטן יותר, וניתן להמשיך כך עד אין-קץ. על כן, במקרה של מעגל שלילי האלגוריתם לא יפיק פלט משמעותי. עם זאת, במידה וקיים מעגל שלילי, ניתן להיעזר באלגוריתם על מנת לגלות זאת:

  • בתחילה, המרחק בין כל קודקוד לעצמו הוא 0.
  • מסלול יכול לשפר, אם ורק אם סכום קשתותיו שלילי, ז"א מדובר במעגל שלילי.
  • על כן, אם קיים קודקוד שמרחקו מעצמו שלילי, משמעות הדבר שקיים לפחות מעגל שלילי אחד בגרף.

מכאן, באמצעות התבוננות במטריצת המסלולים הקצרים ביותר שהפיק האלגוריתם, ניתן להסיק שקיים מעגל שלילי, אם באחד מהתאים על האלכסון הראשי קיים מרחק קטן מאפס.

ראו גם

קישורים חיצוניים

הערות שוליים

  1. ^ Weisstein, Eric. "Floyd-Warshall Algorithm". Wolfram MathWorld. נבדק ב-13 בנובמבר 2009. {{cite web}}: (עזרה)
Logo hamichlol 3.png
הערך באדיבות ויקיפדיה העברית, קרדיט,
רשימת התורמים
רישיון cc-by-sa 3.0