לדלג לתוכן

מבני נתונים ואלגוריתמים - מחברת קורס/גרפים/אלגוריתם "הכפלת מטריצות"

מתוך ויקיספר, אוסף הספרים והמדריכים החופשי


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


כדאי לדעת:

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


הרעיון הכללי

[עריכה]

שימו לב:

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

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


הגדרה:

נגדיר כ את מחיר המסלול הזול ביותר מ ל שארכו בדיוק .

מעניין לראות שבגרף ה"מוסף", אפשר להרחיב את משמעות ההגדרה. המשפט הבא מפרט זאת.



משפט:

בגרף ה"מוסף", שווה בדיוק למחיר המסלול הזול ביותר מ ל שארכו לכל היותר .


לפני שנוכיח את המשפט, להלן דוגמה.



דוגמה:

להלן הגרף המקורי לבעיה:

בעיית המסלולים הזוגים לכלל הזוגות.
בעיית המסלולים הזוגים לכלל הזוגות.

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

  • בגרף המקורי:
    • המסלול הזול ביותר מ ל הוא , ועלותו 2.
    • אין מסלול מ ל באורך 4.
  • בגרף ה"מוסף":
    • המסלול הזול ביותר מ ל גם הוא , ועלותו 2.
    • המסלול הזול ביותר (אך לא היחידי) מ ל באורך 4 הוא , ועלותו 2.


כעת נוכיח את המשפט.


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

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



משפט:

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


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



משפט:

לכל ,‏ הוא:

  1. Edge-Costs[u][v], אם .
  2. Edge-Costs[w][v], אם .


הוכחה: אם , אז מחיר המסלול הזול ביותר מ ל הוא בדיוק מחיר הקשת מ ל (נזכר שבגרף ה"מוסף" בהכרח יש קשת כזו).

אם , אז המסלול הזול ביותר בהכרח מתחלק לשני חלקים:

  1. חלק ראשון, מ ועד כלשהו, באורך .
  2. חלק שני, מ ל, באורך 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