מבני נתונים ואלגוריתמים - מחברת קורס/גרפים/אלגוריתם Floyd-Warshall
מתוך ויקיספר, אוסף ספרי הלימוד והמדריכים החופשי.
דף זה הוא השלישי מבין שלושה דפים העוסקים באלגוריתמים למציאת המסלול הזול ביותר בגרף מכוון בין כל שני צמתים.
|
כדאי לדעת: כל האלגוריתמים (שאותם נלמד) למציאת מסלולים זולים לכלל הזוגות מתבססים על אותו הרעיון.
|
|
מימוש C++ |
[עריכה] הרעיון הכללי
באלגוריתם "הכפלת מטריצות" מצאנו אפיון רקורסיבי למסלול הזול ביותר כפונקציה של ארכו. כאן, לעומת זאת, נמצא אפיון רקורסיבי למסלולים הזולים ביותר כפונקציה של צמתי הביניים שלהם.
|
הגדרה: נניח מסלול
נאמר שהקבוצה |
|
שימו לב: להלן נקודה שמבלבלת חלק מהסטודנטים מדי שנה. אנו עוסקים בגרפים בהם הצמתים הם מספרים שלמים. לכן, כל אחד מ |
|
דוגמה: להלן הגרף המקורי לבעיה: (נזכר שהגרף ה"מוסף" נוצר על ידי הוספת קשתות במחירים 0 ואינסוף.)
|
|
הגדרה: נגדיר כ |
|
שימו לב: גם באלגוריתם "הכפלת מטריצות" הגדרנו |
|
דוגמה: בגרף שראינו, שני מסלולים (מתוך מספר מסלולים) מ
קל לראות, לכן: |
לפי הגדרה זו, קל מאד לאפיין את המסלולים הזולים ביותר בגרף. המשפט הבא מראה זאת.
|
משפט: נקבע את |
כל שנותר כדי לפתור את הבעיה, הוא להבחין שאפשר לחשב את המסלולים הזולים (עפ"י צמתי-הביניים בהם הם משתמשים) בצורה רקורסיבית. המשפט הבא מראה זאת.
|
משפט:
|
הוכחה: נזכר ש
משמעו המסלול הזול ביותר מ
ל
שכל אחד מצמתי הביניים שלו לקוח מהקבוצה 
אם
, אז
אינו כולל צמתי ביניים. מדובר לכן במחיר הזול ביותר הישיר מ
ל
.
אם
, אז יש שתי אפשרויות:
אינו מופיע בקבוצת צמתי הביניים (כלומר, המסלול הזול ביותר אינו עובר דרך
).
מופיע בקבוצת צמתי הביניים (כלומר, המסלול הזול ביותר אכן עובר דרך
).
במקרה הראשון, היות שלא משתמשים ב
, אז מדובר במסלול הזול ביותר מ
ל
שכל אחד מצמתי הביניים שלו לקוח מהקבוצה
, כלומר התשובה היא פשוט
.
במקרה השני, היות שמשתמשים ב
, המסלול מתחלק לשני חלקים:
- מ
ל
. בחלק זה אפשר להניח ש
אינו צומת ביניים (מדוע?). בקטע זה, לכן, התשובה היא פשוט
. - מ
ל
. גם בחלק זה אפשר להניח ש
אינו צומת ביניים (מדוע?). גם בקטע זה, לכן, התשובה היא פשוט
.
[עריכה] פסוודו-קוד
להלן הפסוודו-קוד לאלגוריתם:
Floyd-Warshall(G, Edge-Costs, m) 1 if m == 0 2 return Edge-Costs 3 D' = Floyd-Warshall(G, Edge-Costs, m - 1) 4 n = Length( V(G) ) 5 D = Make-Matrix(n, n) 6 for u in V(G) 7 for v in V(G) 8 D[u][v] = D'[u][v] 9 if D[u][v] > D'[u][m] + D'[m][v] 10 D[u][v] = D'[u][m] + D'[m][v] 11 return D
ולהלן דוגמה לשימוש בו:
1 n = Length( V(G) ) 2 D = Floyd-Warshall(G, Edge-Costs, n) # Prints 2. 3 Print( D[1][2] ) # Prints ∞. 4 Print( D[2][1] )
[עריכה] ניתוח סיבוכיות
ראשית, קל לראות כי 6-10 הן
, והן למעשה קובעות את זמן הריצה של קריאה יחידה של הפונקציה. נגדיר כ
את מספר צמתי הגרף, וכ
את זמן הריצה של Floyd-Warshall(G, Edge-Costs, m). אז
, ולכן
.
| הפרק הקודם: אלגוריתם "הכפלת מטריצות" |
אלגוריתם Floyd-Warshall | הפרק הבא: זרימה - הגדרות |
מ
היא קבוצת צמתי הביניים של המסלול
הוא פשוט מספר שלם מהקבוצה
.
, קבוצת צמתי הביניים היא
.
, קבוצת צמתי הביניים היא
.
, קבוצת צמתי הביניים היא
(הקבוצה הריקה).
, קבוצת צמתי הביניים היא
.
. במילים אחרות, 
שייך ל
.
ל
:
, ושאינו עובר דרך אף צומת ביניים.
שעלותו
.

.
, אם
.