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