2047 a האוניברסיטה הפתוחה אלגוריתמים מדריך למידה מדריך למידה לספר מבוא לאלגוריתמים: T.H. Cormen, C.E. Leiserson, R.L. Rivest, Introduction to Algorithms, שתורגם באוניברסיטה הפתוחה בתשנ"ה 995
צוות הקורס כתיבה: ד"ר גיא קורצרס אחראי אקדמי: פרופ' דוד הראל ריכוז הפיתוח וייעוץ: פרופ' יהודית גל-עזר עדכון מהדורה סופית: מיכל ארמוני עריכה: תלמה מוקדי איורים: רחל אהרון-שריקי מק"ט 2047-503 מסת"ב 06-0657-2 הדפסה דיגיטלית ינואר 2003 מהדורה מעודכנת ינואר 2003 תשס"ג 2003. כל הזכויות שמורות לאוניברסיטה הפתוחה. בית ההוצאה לאור של האוניברסיטה הפתוחה, רח' קלאוזנר 6, רמת-אביב, ת"ד 39328, תל-אביב 6392. The Open University of Israel, 6 Klausner St., Ramat- Aviv, P.O.Box 39328, Tel- Aviv, 6392. Printed in Israel. אין לשכפל, להעתיק, לצלם, להקליט, לתרגם, לאחסן במאגר מידע, לשדר או לקלוט בכל דרך או בכל אמצעי אלקטרוני, אופטי, מכני או אחר כל חלק שהוא מהחומר שבספר זה. שימוש מסחרי בחומר הכלול בספר זה אסור בהחלט, אלא ברשות מפורשת ובכתב ממדור זכויות יוצרים של האוניברסיטה הפתוחה. 2
2 23223456789 6 43234567 92589487584735678 5678 2998424682449893678 678 42948743678 678 884248948753678 2678 4886924248948753678 2678 46863678 2 678 44 968494689873678 678 9 4874668489873678 678
4
פתח דבר הקורס "אלגוריתמים" עוסק בניתוח אלגוריתמים ובהוכחת נכונותם, ושם דגש על ניתוח האלגוריתמים מבחינת יעילותם (סיבוכיות). רוב הקורס מוקדש לאלגוריתמים בתורת הגרפים (למשל, מציאת עץ פורש מינימלי) אבל יש בו גם אלגוריתמים אחרים, כמו, למשל, כפל פולינומים מהיר. לימוד הקורס מתבסס על התרגום לעברית של פרקי הספר: Introduction to Algorithms שכתבו C.E. Leiserson,T.H. Cormen ו- Rivest.R.L. מדריך הלמידה מלווה את תהליך הלימוד. הוא מיועד לעזור לך בהבנת חומר הקורס באמצעות הדגשת הנקודות החשובות שהוצגו בספר, הוספת דוגמאות, הצגת היבטים נוספים של הנושאים הנלמדים, ותרגול נוסף. לעתים יש במדריך חלופות חלקיות לחלקים מסוימים מתוך הספר. חלוקת הפרקים במדריך שונה מעט מהחלוקה בספר. בכל פרק במדריך הלמידה מצוין הפרק או הפרקים המתאימים בספר הלימוד שהפרק הזה מתייחס אליהם. שיטת הלימוד המומלצת: יש לעקוב אחר הכתוב במדריך צעד אחר צעד. תחילה יש לקרוא במדריך הלמידה את המבוא לכל פרק, לעבור לספר לקריאת סעיף מסוים או סעיפים מסוימים על פי ההפניות המצויות במדריך הלמידה, ושוב לחזור לקריאת החומר במדריך. כל פרק במדריך מכיל שאלות, והתשובות להן מובאות בסוף הפרק. רצוי לפתור כל שאלה במהלך הלימוד ורק אחר כך להשוות לתשובה המופיעה במדריך הלמידה. אנו מקווים שתיהנה מקריאת הספר ומדריך הלמידה, ומאחלים לך הצלחה בלימוד הקורס. צוות הקורס 5
6
ד( ג( ב( ו( ז( א( ה( פרק א: גרפים וחיפוש לרוחב גרפים קרא ולמד את סעיף 5.4. שאלה נתון הגרף G המובא באיור א.. איור א. ( מהי הדרגה של הקדקוד? ( מיהם השכנים של 2? האם הגרף קשיר? ( סמן בגרף G מסלול פשוט באורך 6. ( האם יש בגרף מסלול פשוט באורך 7? האם יש בגרף קדקוד מבודד? ( ( ( מהו הגרף המושרה על-ידי 7}?{, 2, 4, התשובה בעמוד 20 בגרף בלתי-מכוון הדרגה של קדקוד v V תסומן ב-( degree(v. לעתים נקצר ונכתוב deg(4) = 2 במקום.degree(v) כך לדוגמה, בגרף שבאיור א., מתקיים deg(v) ו- 3 =.deg(5) v ודרגת היציאה של קדקוד d, in בגרף מכוון, דרגת הכניסה של קדקוד v תסומן ב-( v ) d in (a) = 0 כך למשל, בגרף שבאיור א. 2 מתקיים (שכן ל- a לא.d out תסומן ב-( v ) d, in וכן הלאה. (b) =,d out נכנסות קשתות), = 2 (a) 7
איור א. 2 בספר הלימוד יש אבחנה בין המושגים "קדקודים שכנים" ו"קדקודים סמוכים" במקרה של גרף מכוון. על פי ההגדרות בספר הלימוד בגרף מכוון G קדקוד u סמוך לקדקוד v אם קיימת בגרף הקשת.(v,u) u שכן של v ב- G אם קיימת בגרף הקשת.(u,v) או שקיימת בו הקשת (v,u) כאן, במדריך הלמידה לא נבחין בין המושגים סמיכות ושכנות בגרף מכוון. נאמר כי קדקוד u סמוך לקדקוד v, או שכן של קדקוד v אם קיימת בגרף הקשת.(v,u) שאלה 2 (שאלה 5.4- מהספר) המשתתפים במסיבת פקולטה מברכים זה את זה בלחיצת יד, וכל אחד מהפרופסורים זוכר כמה פעמים הוא או היא לחצו ידיים. בסיום המסיבה מסכם ראש המחלקה את מספר הפעמים שכל פרופסור לחץ ידיים. הראה שהתוצאה זוגית באמצעות הוכחת למת לחיצת הידיים lemma) :(handshaking אם (E G =,V) הוא גרף בלתי מכוון, אזי: degree ( v ) = 2 E v V התשובה בעמ' 2 תכונות של גרפים בהינתן קבוצת קדקודים כלשהי } n v},..., v ניתן לבנות ממנה גרפים רבים מאוד ושונים זה מזה על-ידי כך שבוחרים לכל גרף קבוצת קשתות שונה. למרות זאת, כבר ראינו בשאלה 2 שיש תכונות משותפות לכל הגרפים הבלתי-מכוונים. למשל, בכל גרף בלתי-מכוון סכום דרגות הקדקודים הוא 2 E (ולכן, למשל, סכום הדרגות בגרף בלתי-מכוון הוא תמיד מספר זוגי). דוגמה נוספת לטענה שנכונה לכל גרף בלתי-מכוון היא הטענה הבאה: בכל גרף בלתי-מכוון, מספר הקדקודים שדרגתם אי-זוגית הוא זוגי. לדוגמה, בגרף מאיור א., הקדקודים שדרגתם אי זוגית הם 3, 2, ו- 5, ולכן ישנם בגרף ארבעה קדקודים בעלי דרגה אי-זוגית. שאלה 3 הוכח טענה זו (רמז: היעזר בשאלה 2). התשובה בעמ' 23 8
עתה נעבור לדון במשפחה חשובה ומיוחדת של גרפים: משפחת העצים. עצים קרא ולמד את סעיף 5.5 מתחילתו עד סוף תת-סעיף 5.5.. משפט 5.2 מבהיר מעט את הקשר בין הגדלים E ו- V בגרף קשיר בלתי-מכוון. ראשית נעיר שאם גרף בלתי-מכוון (E G =,V) הוא קשיר, אזי קיים תת-גרף ('E T =,V) של G (כלומר, גרף המכיל את כל הקדקודים של G ורק חלק מהקשתות) המהווה עץ. זאת מהנימוק הבא. e ;v k = v 0,C = (v 0, v,..., v k ) נניח כי G מכיל מעגל כאשר נבחר קשת כלשהי על המעגל ונסלק אותה מ- G. ברור כי הגרף המתקבל ({e} G =,V) E \ עדיין קשיר. שאלה 4 הוכח כי הוצאת קשת הנמצאת על מעגל מגרף בלתי מכוון קשיר אינה פוגעת בקשירות הגרף. התשובה בעמ' 24 אם הגרף המתקבל עדיין מכיל מעגל נוסף, שוב נבחר קשת כלשהי על מעגל זה ונסלק גם אותה מהגרף. כך נמשיך, כל עוד הגרף מכיל מעגלים. הואיל ומספר הקשתות בגרף הוא סופי, התהליך חייב להסתיים. בסיום התהליך, קבוצת הקשתות E' שלא סילקנו מן הגרף G יוצרת עץ E'),T = (V, כלומר, גרף E') T = (V, קשיר וחסר מעגלים (מדוע?). נדגים זאת בעזרת הגרף (הקשיר) מאיור א.. נסלק (למשל) מ- G את הקשתות,G כך נבטל את כל המעגלים בגרף, ויתקבל התת-גרף הבא T של 7) (5, ו-( 2.(, המתואר באיור א. 3, המהווה עץ. איור א. 3 9
מאחר ש- T הוא עץ, מתקיים V = 'E (ראה משפט 5.2 סעיף 4). (למשל, בעץ (. E' = 6 = ו- 7 שבאיור א. 3 מתקיים, V = 7 T אם כן, התחלנו מהגרף G שקבוצת הקשתות שלו היא E, וסילקנו חלק מהקשתות. קבוצת הקשתות שלא סילקנו, 'E, היא תת-קבוצה של E, כלומר, 'E. E לכן מתקיים: ובכן, בכל גרף קשיר מתקיים האי-שוויון: (ראה תרגיל 5.4.3) E E' = V E V אך שוויון, V, E = מתקיים רק בעצים, ולכן במובן זה, עץ הוא גרף קשיר V E. > (שים לב כי אי אפשר מינימלי. בכל גרף קשיר אחר מתקיים 4 במשפט,5.2 להסתמך על דיון זה כהוכחה לתרגיל 5.4.3 משום שהוכחת סעיף שעליו הסתמכנו בדיון זה, משתמשת בתרגיל 5.4.3). עתה נמצא חסם עליון על הגודל E של קבוצת הקשתות. נזכיר כי כל קשת ב- E מתאימה לזוג קדקודים מ- V. על כן, מספר הקשתות הכולל ב- E אינו עולה על, V המספר הכולל של זוגות קדקודים ב- V. כידוע, בהינתן קבוצה בגודל מספר הזוגות הוא: () V V V = 2 2 < ( ) V 2 למשל, בהינתן קבוצת הקדקודים d},v = {a, b, c, שעבורה, V = 4 ניתן, למשל, G 2 G ו- לקבל את הגרפים המתוארים באיור א. 4. איור א. 4 0
מספר הקשתות בגרפים אלה אינו עולה על: V V 4 = 3 = 6 2 2 ( ) G 2 הוא הגרף המלא בן 4 קדקודים, והוא מכיל בדיוק 6 קשתות. אם למעשה, הגרף V ( V ) 2 כן, הגרף המלא מכיל קשתות, וכל גרף בלתי-מכוון אחר שאינו מלא, מכיל מספר קטן יותר של קשתות. מ-( ) נובע אפוא כי לכל גרף בלתי-מכוון (ולא רק לגרף קשיר) מתקיים: E = Ο ( V 2 ).Θ( V 2 ל-( Θ( V ) בסיכום, בגרף קשיר, סדר הגודל של E נע בין באופן לא ), נאמר שהגרף "צפוף" V 2 פורמלי, כאשר V 2 E (כלומר, כאשר E קרוב ל- (כלומר מכיל "הרבה" קשתות), ואם "מעט" קשתות)., E V נאמר שהגרף "דליל" (כלומר, מכיל נשים לב, למשל, כי מכך שלכל גרף קשיר מתקיים: נובע כי: (2) V E < V 2 log( V ) log( E ) < 2log( V ) כלומר, (עובדה זו תהיה שימושית בהמשך.) log( E ) = Θ( log V ) לפני שנעבור לדון בייצוג גרפים במחשב, נעיר כי למרות שסעיפים 5.5.2 ו- 5.5.3 כבר נלמדו בקורס "מבני נתונים ומבוא לאלגוריתמים", הכרת החומר המובא בהם חיונית גם בקורס הנוכחי, ולכן, מי שאינו מצוי היטב בחומר זה טוב יעשה אם יחזור ויעיין בסעיפים אלה.
ייצוג גרפים במחשב קרא ולמד את המבוא לחלק VI וכן את פרק 23 מתחילתו עד סוף סעיף 23.. שאלה 5 תאר את שני הייצוגים של הגרף שבאיור א. 5 על-ידי מטריצת סמיכויות ועל-ידי רשימות סמיכות: איור א. 5 התשובה בעמ' 25 שאלה 6 בהינתן ייצוג על-ידי רשימות סמיכות של גרף מכוון, מהו הזמן הדרוש לחישוב דרגת היציאה של כל אחד מהקדקודים? מהו הזמן הדרוש לחישוב דרגות הכניסה? התשובה בעמ' 26 מסלולים קצרים ביותר מעתה ועד תום הפרק השני במדריך נדון בבעיה של מציאת מסלולים קצרים ביותר בגרף נתון, מקדקוד מקור נתון s, לכל שאר הקדקודים. בעיה זו כוללת כמה מקרים, בהתאם למאפייני הגרף: גרף מכוון או בלתי-מכוון. גרף משוקלל (עם משקלות על הקשתות) או לא-משוקלל. במקרה של גרף משוקלל, משקלות חיוביים או שליליים...2.3 בכל אחד מהמקרים נדון במציאת המרחק מקדקוד ספציפי נתון s V לכל שאר קדקודי הגרף. בדרך כלל לא נסתפק במציאת המרחקים מ- s, אלא נרצה גם לשחזר את המסלולים הקצרים ביותר עצמם. 2
מציאת מרחקים בגרפים לא-משוקללים כזכור, בגרף לא משוקלל, המרחק בין זוג קדקודים,u v הוא אורך המסלול הקצר u ביותר (כלומר, המסלול בעל מספר הקשתות המינימלי) המחבר בין ל- v. כך, למשל, בגרף שבאיור א., המרחק בין ל- 6 הוא 3, והמסלול הקצר ביותר הוא 6 5 2. (המרחק הוא 3 למרות שישנם מסלולים ארוכים יותר מ- ל- 6, 4 2 5 6 שאורכו.4 למשל, המסלול זאת משום שהמרחק הוא אורכו של המסלול הקצר ביותר.) כמו כן, ייתכן, כמובן, שיהיה מספר רב של מסלולים קצרים ביותר, שונים, בין אותו זוג קדקודים. חיפוש לרוחב האלגוריתם למציאת המרחק מ- s לשאר הקדקודים בגרף לא-משוקלל נקרא חיפוש לרוחב. (באנגלית נקרא האלגוריתם,BFS ראשי התיבות של (.Breadth First Search זהו האלגוריתם הראשון מבין אלגוריתמי סריקת הגרפים שנלמד בקורס זה. כשמדברים על אלגוריתם סריקה של גרף הכוונה היא לאלגוריתם העובר בצורה שיטתית ומסודרת על הקדקודים והקשתות בגרף (לעתים, אלגוריתם סריקה עובר רק על קבוצה חלקית ממש של הקדקודים והקשתות בגרף ולא על הגרף כולו). הדיון באלגוריתם החיפוש לרוחב ייערך במדריך הלמידה, ואין צורך לקרוא את הפרק המתאים בספר. אלגוריתם זה יכול לרוץ הן על גרפים מכוונים והן על גרפים בלתי מכוונים. תחילה נדון בגרפים מכוונים. לצורך ההסבר של הרעיון העומד בבסיסו של האלגוריתם, נתבונן בגרף שבאיור א. 6 : איור א. 6,s אילו קדקודים בגרף נמצאים במרחק מ- s? ובכן, מדובר כמובן בשכנים של הקדקודים c ו- a (כל שאר הקדקודים מרחקם מ- s הוא 2 לפחות). ואילו קדקודים נמצאים במרחק 2 מ- s? ובכן, באורח בלתי פורמלי, מדובר ב"שכני השכנים" של s, כלומר, בקדקודים השכנים לקדקודים שהם שכנים של s, כלומר, שכנים של a ו- c. 3
כ c.s,c d למשל, הקדקוד הוא שכן של שהוא עצמו שכן של בגרף ישנו מסלול ל- d, באורך 2 מ- s s c d והמרחק בין s ל- d הוא 2. אם כן, הקדקודים במרחק 2 מ- s הם {d,b},,f והם שכני השכנים של s. ואילו הם הקדקודים במרחק 3 מ- s? אלה הם כמובן השכנים של {d,b},,f וכן הלאה. מטרתנו היא אפוא לסרוק את קדקודי הגרף בהדרגה. תחילה אנו סורקים את השכנים של s ומסמנים אותם בתווית, המעידה כי מרחקם מ- s הוא. לאחר מכן אנו סורקים את שכני השכנים של s, ומסמנים אותם בתווית 2, וכן הלאה. אולם ישנה נקודה שבה נדרשת זהירות. למשל, a ו- c הם שכנים של s. אך c הוא גם שכן שני (כלומר, שכן של שכן) של! s זאת משום ש- c הוא שכן של a, שהוא עצמו שכן של s. במהלך הסריקה יש להיזהר ולקבוע את המרחק מ- s ל- - (ולא 2). הנקודה שיש להיזהר בה היא אפוא זו: בעת סריקת הגרף, יש לעדכן בכל שלב רק את המרחק של קדקודים "חדשים", כלומר, כאלה שטרם גילינו, ולא קיבלו עדיין תווית. כך, לאחר שקבענו כי a ו- c נמצאים במרחק מ- s, כשנבוא לסמן את "שכני השכנים", נדאג לקבוע מרחק של 2 רק לקדקודים חדשים, כלומר, לשכנים של a ו- c שעדיין לא סומנו (במקרה זה, d, f ו- b בלבד) ולא לקדקוד c שכבר סומן. את הקדקודים במרחק i מ- s נכנה השכבה ה- i (ביחס ל- s ) בגרף. כך, שכבה 0 בגרף שבאיור א. 6 היא הקדקוד s עצמו, שכבה בגרף מורכבת מהקדקודים a ו- c, ושכבה 3 מורכבת מהקדקוד e. כל הקדקודים שלא ניתן להגיע אליהם מ- s ייקראו שכבת האינסוף. להלן ציור מחדש של הגרף לפי שכבותיו: איור א. 7 4
האלגוריתם נקרא חיפוש לרוחב משום שהוא סורק את קדקודי הגרף שכבה אחר שכבה. האלגוריתם עובר (לרוחב) על השכבה ה- i ומגלה את כל קדקודי השכבה לפני שהוא עובר לגלות את קדקודי השכבה ה- i+. כלומר, כל קדקודי השכבה ה- i נסרקים לפני שנסרק ראשון קדקודי השכבה ה- i+. לצורך הסריקה לפי שכבות,.Q האלגוריתם BFS נעזר בתור במהלך הסריקה נשמרים ב- Q קדקודים שטרם נסרקו. כמו כן, לכל קדקוד u V מתוחזק משתנה d[u] שישמש לסימון u, ובפרט, ב-[ d[u נחשב את המרחק של u מ- s. כל המשתנים d[u] מאותחלים ל-, והמשתנים u של קדקודים שמרחקם מ- s סופי, יעודכנו במהלך האלגוריתם. צומת d[u] שהאלגוריתם כבר סרק מאופיין בכך ש-.d[u] d[s] מאותחל ל- 0 (ואכן המרחק מ- s לעצמו מוגדר כ- 0 ). תיאור האלגוריתם: הקלט לאלגוריתם הוא גרף מכוון (E G(V, חסר משקלות, וקדקוד s V בגרף. BFS(G, s). 2. 3. 4. 5. 6. 7. 8. 9. 0.. for each u V \ {s} do d[u] d[s] 0 ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if d[v] = then d[v] d[u] + ENQUEUE(Q, v) שאלה 7 הרץ את האלגוריתם על הגרף מאיור א. 6. הנח כי הקדקודים מופיעים ברשימות הסמיכות על פי סדר לקסיקוגרפי. התשובה בעמ' 28 אם כן, השימוש בתור הוא שקובע את הסריקה לרוחב, שכבה אחר שכבה. כל קדקודי השכבה ה- i נכנסים לתור לפני כל קדקודי השכבה ה- + i. הואיל ומדובר בתור, כלומר, במבנה נתונים מסוג,FIFO שבו הקדקוד שנכנס ראשון לתור גם יוצא 5
א( ב( א( ב( ב( ראשון, קדקודי השכבה ה- i גם ייסרקו כולם לפני כל קדקודי השכבה ה- + i. באופן דומה, בעת סריקת קדקודי השכבה ה- i, יוכנסו לתור כל קדקודי השכבה ה- + i, ולכן הם ייסרקו כולם לפני כל קדקודי השכבה ה- 2 + i, וכן הלאה. הערות: ( האלגוריתם BFS לא בהכרח מגיע לכל קדקודי הגרף. למעשה, האלגוריתם יגיע (ויסמן) רק את הקדקודים הניתנים להגעה מ- s (כלומר, קיים בגרף מסלול מכוון מ- s אליהם, ומרחקם מ- s אינו אינסופי). כך לדוגמה, בגרף מאיור א. 6, אם נתחיל את הסריקה מ- a, יסומנו כל הקדקודים פרט ל- s, הואיל ואין מסלול מכוון מ- a ל- s. לכן בהרצת האלגוריתם עם a כמקור, d[s] יישאר ולא יעודכן במהלך האלגוריתם (ואכן, כזכור, מאחר שאין אפשרות להגיע מ- a ל- s, המרחק בין a ל- s מוגדר כ- ). באלגוריתם BFS שתיארנו ניתן להשתמש (כמות שהוא) גם לצורך חישוב ( d[u] המרחקים מ- s G בגרף בלתי מכוון. הערכים המתקבלים הם בדיוק מרחקי כל הקדקודים מ- s בגרף הבלתי-מכוון. הנכונות והסיבוכיות של אלגוריתם החיפוש לרוחב ראשית, על i: נוכיח את נכונות האלגוריתם, על ידי הוכחת הטענה הבאה באינדוקציה i כל אברי השכבה ה- i (האיברים במרחק מ- s ) נכנסים לתור, והם נכנסים ( לתור לפני שנכנס לשם ראשון קדקודי השכבות + i, i + 3 i, + 2 וכן הלאה. ( איברי השכבה ה- i אכן מקבלים תווית i באלגוריתם. הוכחה: בסיס האינדוקציה: בשכבה ה- 0 נמצא הקדקוד s לבדו. ואכן בשורות 3 ו- 4, s נכנס ראשון לתור (לפני איברי השכבות 4, 3, 2,, וכן הלאה) ול- s מוענקת התווית 0, כנדרש. שלב האינדוקציה: נניח שטענות (א) ו- ( נכונות עבור כל, j i, j ונראה שהן נכונות גם עבור + i j. = יהי u קדקוד מהשכבה ה- + i. על כן u הוא שכן של איזשהו קדקוד v מהשכבה ה- i. שימו לב כי u הוא אולי גם שכן של קדקודים מהשכבות...,2 + i i.,+ אלא שלפי הנחת האינדוקציה (א), הקדקוד v ייכנס לתור לפני כל הקדקודים מהשכבות...,2 + i i.,+ ברגע ש- v יגיע לראש התור, הקדקוד u יקבל תווית + i, כנדרש. יתר 6
ג( א( ב( ב( על כן, הקדקוד u ייכנס לכן לתור לפני כל קדקוד מהשכבות...,3 + i i. +,2 לפיכך,.i + ( סעיפים ו- (א) תקפים גם עבור הואיל וכך, לפי סעיף (ב) המרחקים מתעדכנים נכונה באלגוריתם,BFS כנדרש. נעבור אפוא לניתוח סיבוכיות האלגוריתם,BFS לפי שורות האלגוריתם. ( באתחול, בשורות ו- 2 של האלגוריתם, עוברים על כל הקדקודים (פרט ל- s ), ולכן מתבצעות ( V ) O פעולות. ( בשורות 4-3 מתבצעות () O פעולות. ( עתה נתבונן בלולאה שבשורה 5. תחילה נעיר כי כל קדקוד בגרף נכנס לתור פעם, u.( אחת לכל היותר (בשורה לפני שמכניסים קדקוד לתור בשורה מעדכנים את המשתנה.d[u] לפיכך, u שוב לא ייכנס ל- Q, שכן לתור נוספים רק קדקודים u שעבורם =,d[u] ואילו לאחר העדכון,.d[u] בשורות ו- 7 מתבצעות אפוא O( V ) פעולות, שכן בשורה מכניסים לתור לכל היותר קדקודים (כלומר, כל הקדקודים פרט ל- s ), ולפיכך, מספר הפעמים V שקדקוד נמחק מהתור בשורה 7 אינו עולה על V (שכן כאשר התור מתרוקן, O( V ) 7 האלגוריתם עוצר). לכן שורות ו- תורמות פעולות. עתה נתבונן בשורות 0-8. בשורה 8 עוברים, עבור u הנוכחי, על כל רשימת הסמיכות של u,.u v ובשורות 9 ו- 0 בודקים אם יש לעדכן את d[v] עבור השכן הנוכחי של לכן, מספר הפעולות המתבצעות בלולאה שבשורות 0-8 עבור u הוא: 3d out (u) = Θ(d out (u)) u, ובודקים אם ביתר פירוט, מגיעים לכל שכן v של =.d[v] אם יש צורך בכך, מעדכנים את.d[v] u נזכור כי כל קדקוד u מוכנס לתור פעם אחת לכל היותר, ולכן גם יגיע לראש u התור פעם אחת לכל היותר. כאמור, מספר הפעולות המתבצעות כאשר נמצא,Θ(d out בראש התור הוא ((u) ולכן ניתן לחסום את המספר הכולל של הפעולות המתבצעות בשורות 0-8 על-ידי:. Θ = u V ( d ( u ) out ) O ( E ) 7
ב( א( אנו כותבים O, שכן הסיכום הוא על כל הקדקודים בגרף. אך ייתכן שיהיו קדקודים אשר כלל לא ייכנסו לתור, ולכן לא יגיעו לראש התור, ואין צורך לכלול בסכום את דרגת היציאה שלהם. לפיכך ה- O מציין חסם מלמעלה, אולי לא הדוק, על זמן הריצה. u w בדרך ניתוח אחרת, קל לראות שבשורות 0-8 עוברים על כל קשת פעם אחת לכל היותר. עוברים על הקשת בדיוק אם וכאשר u מגיע לראש התור, ואז במעבר על שכני מגיעים ל- w u והקשת נסרקת. לכן, מספר הפעולות המתבצעות בשורות 0-8 הוא.O ( E ) בסיכום נקבל כי סיבוכיות האלגוריתם היא ליניארית, ולמעשה היא: O( E + V ) ישנם גרפים שבהם אכן ניתן להגיע מ- s לכל שאר הקדקודים (דוגמה לכך היא הגרף שבאיור א. 6 ). במקרה זה אכן כל הקדקודים יוכנסו לתור, ולכן האלגוריתם יעבור גם על כל הקשתות. אם כן, במקרה זה, האלגוריתם רץ בזמן ( V.Ω( E + לכן סיבוכיות האלגוריתם במקרה הגרוע היא ( V.Θ( E + כמה הערות על המקרה הבלתי-מכוון גם במקרה הבלתי-מכוון הסיבוכיות נותרת.Θ( E + V ) עם זאת, במקרה הבלתי-מכוון עוברים למעשה פעמיים על כל קשת שנסרקת. כל קשת (v e =,u) ( שהאלגוריתם מגיע אליה נסרקת פעמיים, פעם אחת בכיוון u, v כאשר u v כאשר,v u מגיע לראש התור, ופעם שנייה בכיוון מגיע לראש התור. u במילים אחרות, במקרה הבלתי-מכוון, בעת סריקת רשימת הסמיכות של נעבור על v, ולהיפך, בעת סריקת רשימת הסמיכות של v, נעבור על u (דבר שאינו קורה במקרה המכוון). על אף העובדה שכל קשת נסרקת פעמיים, ברור כי סדר הגודל של זמן ריצת האלגוריתם אינו משתנה, משום שההבדל הוא רק בגורם קבוע. BFS במקרה הבלתי-מכוון, האלגוריתם סורק את כל הרכיב הקשיר שאליו ( שייך הקדקוד שממנו מתחילה הסריקה. לדוגמה, נתבונן בגרף הבא: 8
איור א. 8 בביצוע אלגוריתם החיפוש מהקדקוד a, למשל, ייסרקו כל קדקודי הרכיב,(b, c),(c, d),(a, b) (כלומר, הקשתות וכן {d,a},b,c וכל הקשתות ברכיב זה הלאה). האלגוריתם לא יסרוק ולא יגיע כלל לקדקודים הנמצאים ברכיבים הקשירים האחרים. כך, בגרף שבאיור א. 6 לא ייסרקו כלל הקדקודים {g,e}.,f מקרה מיוחד וחשוב הוא המקרה שבו הגרף הוא בלתי-מכוון וקשיר. במקרה זה, האלגוריתם BFS עובר על כל הקדקודים והקשתות בגרף, וסדר הגודל של זמן הריצה שלו הוא ( V,Ω( E + ולכן גם ( V.Θ( E + אך כבר ראינו כי בגרף BFS בלתי-מכוון וקשיר מתקיים Ω( V ) E. = לכן, זמן הריצה של על גרף בלתי-מכוון קשיר הוא.Θ(E) 9
א( ה( ו( ג( ד( ב( תשובות לפרק א תשובה כזכור, דרגתו של קדקוד בגרף בלתי-מכוון שווה למספר הקשתות הקשורות ( לקדקוד. לכן, הדרגה של הקדקוד היא 3. השכנים של הקדקוד 2 הם הקדקודים המחוברים ישירות ל- 2, כלומר, (.{, 4, 5} גרף בלתי-מכוון G הוא קשיר אם עבור כל,u v G קיים מסלול מ- u ל- v. לכן, ( הגרף שבאיור א. הוא קשיר. מבחינה חזותית, גרף קשיר מורכב מ"חלק" אחד בלבד. כך, הגרף שבאיור א. 9 אינו קשיר, כי הוא מורכב משלושה חלקים נפרדים. איור א. 9 מסלול נקרא פשוט אם כל קדקוד במסלול (ולכן, כל קשת בו) מופיע במסלול פעם אחת. בגרף ישנם בדיוק שני מסלולים פשוטים באורך 6: ( איור א. 0 ( לא קיים בגרף מסלול פשוט באורך 7 (כפי שניתן לבדוק ישירות). לא קיים בגרף קדקוד מבודד, הואיל ולקדקוד מבודד דרגה (כלומר, זהו 0 ( קדקוד שלא קשורות אליו קשתות). לעומת זאת, בגרף שבאיור א. 9, ישנו הקדקוד המבודד d. 20
ז( בהינתן גרף (E G, =,V) הגרף המושרה על ידי קבוצה A U מורכב מקדקודי ( A, ומכל הקשתות הפנימיות הקושרות את קדקודי A (כלומר, הקשתות ששני {, 2, 4, 7} קדקודי הקצה שלהן נמצאים ב- A ). הוא: לכן הגרף המושרה על-ידי איור א.,{, 2, 4, 7} לדוגמה, כל הקשתות הקשורות ל- 7 אינן פנימיות לקבוצה ולכן אינן נמצאות בגרף המושרה. תשובה 2 ניתן לתאר את הבעיה בעזרת גרף בלתי-מכוון: לכל פרופסור במסיבה מתאים קדקוד בגרף, ולכל לחיצת ידיים מתאימה קשת בין שני הקדקודים. כלומר, שני קדקודים המתאימים לשני פרופסורים יחוברו על-ידי קשת אם ורק אם הפרופסורים לחצו יד. נתאר זאת בעזרת דוגמה: נניח כי מדובר בחמישה פרופסורים, ונסמן אותם באותיות א, ג, ב, ד ו-ה. נניח לדוגמה כי הפרופסורים שלחצו ידיים הם: א ו-ג, ב ו-ג, ב ו-ד, א ו-ה, ג ו-ה. הגרף המתאים הוא: איור א. 2 (כאשר, כאמור, כל קשת מתאימה לאחת מלחיצות הידיים.) כל אחד מהפרופסורים זוכר כמה ידיים הוא או היא לחצו, ובסוף מסכמים את כל לחיצות הידיים. מה מייצג, במינוח שלנו מתורת הגרפים, מספר הידיים שלחץ כל פרופסור? ובכן, זוהי הדרגה של הקדקוד המתאים בגרף, כלומר, מספר הקשתות 2
ה( 3 הקשורות לקדקוד. כך למשל, פרופסור ג לחץ ידיים, ולכן דרגתו בגרף שבאיור א. 2 היא 3. לכן, המספר הכולל של לחיצות הידיים הוא למעשה סכום דרגות הקדקודים בגרף המתאים: v V deg v. נדון תחילה בסכום ) ( v V deg v ( ) עבור גרף בלתי-מכוון כלשהו. דרגתו של כל קדקוד v בגרף מאופיינת בכך שהיא נקבעת אך ורק על-ידי מספר הקשתות הקשורות ל- v. כל קשת הקשורה ל- v מגדילה ב- את דרגתו של v, ודרגת v גדלה רק עקב קשתות הקשורות אליו. ננסה אפוא להתבונן בסכום הדרגות דרך "המשקפיים" של הקשתות. נתבונן בקשת (ד, ב) בגרף שבאיור א. 2. קשת זו מגדילה ב- את דרגת הקדקוד ב ואת דרגת הקדקוד ד. בסך הכל, הקשת תורמת אפוא 2 לסכום הדרגות. באופן דומה, הקשת (ג, ה) תורמת לדרגת ג ו- לדרגת ה, ולכן מגדילה את סכום הדרגות ב- 2. נוכל אפוא לטעון שכל קשת "אחראית" לתרומה של 2 בדיוק לסכום הדרגות, וכמו כן, רק הקשתות אחראיות על הגדלת דרגות הקדקודים והגדלת הסכום ב- 2. אם כן, הואיל וכל קשת מגדילה את סכום הדרגות ב- 2, נקבל כי סכום הדרגות שווה לפעמיים מספר הקשתות, כלומר: v V = 2 deg ( v) ( E) נבדוק זאת עבור הגרף שבאיור א. 2. מספר הקשתות הוא 5, וסכום הדרגות הוא: deg(v) = (א) deg + (ב) deg + (ג) deg + (ד) deg + deg( Σ = 2 + 2 + 3 + + 2 = 0 ואכן, סכום הדרגות שווה לפעמיים מספר הקשתות. המסקנה היא שבכל גרף לא-מכוון, סכום דרגות הקדקודים הוא מספר זוגי. מאחר שהמספר הכולל של לחיצות הידיים של הפרופסורים שווה לסכום דרגות הקדקודים בגרף הבלתי-מכוון המתאים, נקבל כי הסכום הוא זוגי, כפי שנתבקשנו להראות. הערה: בעבור גרף מכוון (E G(V, ניתן להראות בדרך דומה כי סכום דרגות היציאה של הקדקודים שווה ל- E, כלומר,. u  d ( u ) = E out Œ V 22
הסיבה לכך שבמקרה זה הסכום הוא E (ולא E 2 כמו בגרף הבלתי-מכוון) היא שכל קשת e = u w מעלה ב- את דרגת היציאה של אחד בלבד מבין שני קדקודי הקצה שלה (בדוגמה שלעיל, את דרגת היציאה של u). לכן כל קשת תורמת לסכום דרגות היציאה (ולא 2 כמו בגרף בלתי-מכוון). באופן דומה, לסכום דרגות הכניסה, ולכן מתקיים גם כל קשת תורמת. u din ( u ) = E V תשובה 3 לפי שאלה 2 נקבל כי סכום הדרגות של קדקודי הגרף הוא מספר זוגי. נפריד את סכום הדרגות לשניים: סכום הדרגות הזוגיות וסכום הדרגות האי-זוגיות. נסמן V o את אוסף הקדקודים בגרף שדרגתם זוגית, וב- את אוסף הקדקודים V e ב- שדרגתם אי-זוגית. לדוגמה, בגרף: איור א. 3 V e הקבוצה היא V e = {c, d, e} V o היא: והקבוצה V o = {g, a, b, f} אם כן, מתקיים:  deg( v) =  deg( v) +  deg( v) = 2 E Œ vœv vœv v V e o נתבונן עתה בסכום הדרגות הזוגיות: v  deg( v) Œ V e הואיל ומדובר בסכום של מספרים זוגיים, הסכום גם הוא זוגי. 23
נעביר מאגף לאגף ונקבל: באגף השמאלי קיבלנו 2 המספר v) deg( 2 ( E ) deg( v) = deg( v) v V v V e o מספרים זוגיים: 2 E ו- v) deg(. ולכן v  Œ V e, השווה להפרש בין שני מספרים זוגיים אלה, גם הוא מספר v  Œ V o זוגי. אבל נשים לב כי בסכום V). o אם כן, הגדרת v  deg( v) Œ V o v  deg( v) Œ V o כל אחד מאיברי הסכום הוא אי-זוגי (לפי מייצג סכום של מספרים אי-זוגיים, והוא עצמו זוגי. אך דבר זה ייתכן אם ורק אם מספר האיברים בסכום הוא זוגי. במילים אחרות, אם סכום של קבוצת מספרים אי-זוגיים הוא זוגי, מספר המספרים חייב להיות זוגי (לדוגמה, בגרף שבאיור א. 3 נקבל:  deg( v) = 8 vœv o ואכן ב- V o ארבעה איברים.), V o v  deg( v) Œ V o ברור כי מספר האיברים בסכום הוא בדיוק כלומר, שווה V o הוא.(4 למספר הקדקודים בגרף שדרגתם אי-זוגית (בדוגמה שלעיל, לכן, V o הוא מספר זוגי, כלומר, בכל גרף יש מספר זוגי של קדקודים עבור כל גרף, שדרגתם אי-זוגית. תשובה 4 :C מהמעגל e = (v i, v i+ נסלק קשת ) איור א. 4 ונראה כי בכך לא נפגעה קשירות הגרף. 24
לשם כך עלינו להראות כי לכל זוג קדקודים בגרף,u, w V G עדיין קיים ב- G קשיר, ולכן בגרף G u (e (כלומר, בגרף G ללא הקשת מסלול בין ל- w. נתון כי קיים מסלול P מ- u ל- w : P = u z... r w u ולכן קיים מסלול בין G, אם P אינו מכיל את הקשת e, הרי שהוא מופיע גם בגרף G, וכדי להראות G. אם P מכיל את e, אזי המסלול P אינו מופיע בגרף ל- w בגרף G כי הקשירות לא נפגעה, עלינו להראות שקיים ב- מסלול אחר בין u ל- w. נתאר זאת באיור כך: איור א. 5 v i ל- +i v, החסרה במסלול P, ניתן לבצע באיור אפשר לראות כי במקום הקשת e בין,v i v i ל- מ- v i+ v i ל- מעקף ולהגיע מ- דרך הצד השני של המעגל, כלומר, +i v, ולאחר מכך להמשיך את שארית המסלול i+2 v ו- 2 i v, וכן הלאה, עד i v ל- מ- עד w. לכן, כאשר מסלקים קשת הנמצאת על מעגל, הקשירות אינה נפגעת, שכן כל מסלול שהכיל קשת זו ניתן להמיר במסלול שעוקף את הקשת דרך הצד השני של המעגל, ועובר מהקצה האחד לקצה האחר של הקשת. כלומר, לקשתות (s e =,t) שנמצאות על מעגל יש תחליף בדמות מסלול חלופי המוליך מ- t ל- s. תשובה 5 מטריצת הסמיכויות המתאימה היא: 25
2 3 4 5 6 0 0 0 0 0 0 2 0 0 0 0 0 3 0 0 0 0 4 0 0 0 0 5 0 0 0 0 0 6 0 0 0 0 לדוגמה, בשורה השלישית מופיע בעמודות של הקדקודים הסמוכים ל- 3. הקדקודים הסמוכים ל- 3 הם 2 ו-- 3 עצמו (הואיל ויש לולאה עצמית מ- 3 לעצמו). בייצוג בעזרת רשימות סמיכות, כל קדקוד מצביע על רשימה המורכבת מן הקדקודים הסמוכים לו: איור א. 6 2 כך, הרשימה של 3 כוללת את הקדקודים ו- 3 (סדר הקדקודים בתוך רשימות הסמיכות הוא שרירותי). תשובה 6 תחילה נדון בחישוב דרגות היציאה. יש לעבור על רשימת הסמיכות של כל קדקוד, ולספור כמה שכנים יש לו. הואיל ולכל קדקוד v עוברים פעם אחת בדיוק על רשימת,v שכניו, מספר הפעולות המתאים ל- v פרופורציונלי למספר השכנים של כלומר, Θ(d out (v)) v לדרגת היציאה של v. במילים אחרות, עבור כל קדקוד מתבצעות פעולות. ולכן, הואיל והמעבר על שכני v מתבצע לכל קדקודי הגרף, העבודה הכוללת המושקעת היא: Θ( d ( v) ) = Θ d ( v) out out u V u V 26
= ) ( out, ולכן נקבל כי חישוב הדרגות דורש u V כזכור (ראו שאלה 2), מתקיים d v E זמן של.Θ( E ) (כפי שכבר ראינו, הסבר חלופי לכך הוא שבמעבר על כל רשימת הסמיכות עוברים למעשה פעם אחת על כל קשת (w,u).) עתה נדון בחישוב דרגות הכניסה. נגדיר מערך D, ובמקום ה- i ב- D נחשב את דרגת.v i הכניסה של הקדקוד בניגוד לחישוב דרגות היציאה של הקדקודים, שמתבצע בקלות על-ידי מעבר על רשימות הסמיכות של הקדקודים בזו אחר זו, דרגת הכניסה של כל קדקוד v "מפוזרת" בין רשימות הסמיכות השונות. כך, בגרף הבא: איור א. 7 4 דרגת הכניסה של 2, השווה ל- 3, "מפוזרת" ברשימות הסמיכות של הקדקודים 3, 4 ו- 6 ו- 6. כלומר, אם נעבור על רשימות הסמיכות של הקדקודים 3, נגלה בהדרגה את שלוש הקשתות הנכנסות לקדקוד 2. מסיבה זו לא ניתן לחשב באופן יעיל את דרגות הכניסה של הקדקודים בצורה עוקבת בזה אחר זה. כלומר, אם נרצה לחשב תחילה את דרגת הכניסה של, ניאלץ לעבור על כל רשימות הסמיכות של כל הקדקודים ולבדוק באילו מהן מופיע כאחד השכנים. לאחר מכן, חישוב דרגת הכניסה של 2 יחייב מעבר חוזר על כל רשימות הסמיכות, וכן הלאה, ולכן מדובר בתהליך בזבזני שבו סורקים שוב ושוב אותן רשימות סמיכות. לכן, לא נחשב את דרגות הכניסה של הקדקודים בזה אחר זה, אלא נחשב בו-בזמן את דרגות הכניסה של כל הקדקודים. נדגים זאת בעזרת רשימות הסמיכות שבאיור א. 7. נעבור על רשימות הסמיכות בזו אחר זו. כאשר נפגוש, למשל, את 2 בתחילת רשימת הסמיכות של 3, נוסיף למונה [2]D של 2 במערך D. בהמשך הרשימה נפגוש את 3 עצמו ברשימת הסמיכות של 3 ונוסיף למונה שלו, [3]D. בדומה נעבור על הרשימה של 4, שם נפגוש את ו- 2, ונוסיף למונים שלהם, וכן הלאה. אם כן, בדרך זו, חישוב הדרגות מתבצע במקביל עבור כל הקדקודים. 27
לכן, בעזרת מעבר יחיד של רשימות הסמיכות, ניתן לחשב את כל דרגות הכניסה. לפיכך, הזמן הדרוש לחישוב כל דרגות הכניסה גם הוא,Θ( E ) כמו זמן החישוב של דרגות היציאה. תשובה 7 תחילה מאתחלים את d[u] של כל u s ל-, ואת d[s] ל- 0, ומכניסים את s ל- Q. בשורה 7, s יוצא מ- Q. בשורות -8 מתבצעות הפעולות הבאות: עוברים על שכני,s כלומר, על a ו- c, ומשנים את d[a] ו-[ d[c ל-. ברגע זה מתקיים = 0,d[s] d[a] = ו- = d[c], ועבור שאר הקדקודים, =.d[u] כמו כן, a ו- c נכנסים לתור בזה אחר זה (a נכנס ראשון מכיוון שהוא מופיע לפני c ברשימת הסמיכות של s, שכן ההנחה,7 היא כי הרשימות מסודרות לפי הא"ב האנגלי). עתה, a יוצא מהתור בשורה ובשורות -8 עוברים על שכניו. לכן, מתבצעת הפעולה: d[b] d[a] + = + = 2 כפי שכבר ראינו לעיל, d[c] אינו מתעדכן, הואיל ומעדכנים d[u] של קדקוד חדש בלבד, כלומר, קדקוד u שטרם פגשנו בו במהלך הסריקה, ולכן d[u] עדיין שווה ל- d[d] c ולעומת זאת.d[c] כעת יוצא מהתור, מעדכנים את ו-[ d[f ל- 2,. ומכניסים לתור את d ואחריו את f נתאר בפירוט את ערכי d[u] השונים ואת מצב התור ברגע זה: s a b c d e f g h k d[u] 0 2 2 2 Q = b d f סוף התור ראש התור יש לשים לב כי ברגע זה נסתיימה סריקת שכבה, ומתחילה סריקת שכבה 2. כעת d[u] יוצא מהתור. הואיל ול- b אין שכנים, אין מעדכנים את של אף אחד b מהקדקודים האחרים. כעת יוצא מהתור, d[e] מתעדכן ל- 3, והקדקוד נכנס e d לתור. מצב ה-[ d[u ומצב התור הוא: 28
s a b c d e f g h k d[u] 0 2 2 3 2 Q = f e סוף התור ראש התור,d[a], d[b] מתקיים, f כעת f יוצא מהתור, ולמרות ש- a ו- b שכנים של כלומר, ב-[ d[a ו-[ d[b כבר מוצב ערך סופי, ולכן d[a] נשאר ו-[ d[b נשאר 2 ואינו מתעדכן. כעת e יוצא מהתור, d[g] מתעדכן ל- 4, ב-[ d[k מוצב הערך 4, ו- g ו- k נכנסים לתור. מצב ה-[ d[u והתור Q ברגע זה הוא: s a b c d e f g h k d[u] = 0 2 2 3 2 4 4 Q = g k סוף התור ראש התור כעת מתחילה הסריקה של השכבה הרביעית. עתה g יוצא מהתור, ובסריקת שכניו לא מתבצעים שינויים. עתה מהתור, התור מתרוקן והשגרה נעצרת.,d[h] 5 יוצא מהתור, k ו- h נכנס לתור. לבסוף h יוצא הערה: כאמור, איור א. 7 ממחיש היטב את הדרך שבה האלגוריתם סורק את הגרף. עוברים על קדקודי הגרף שכבה אחר שכבה. הואיל והקדקודים בתוך כל שכבה כבר מופיעים באיור בסדר לקסיקוגרפי (וההנחה היא כי זהו המצב גם ברשימות הסמיכות), המעבר בתוך כל שכבה הוא על כל הקדקודים משמאל לימין בסריקה "לרוחב". 29
30
ל s פרק ב: מסלולים קצרים ביותר בגרף משוקלל נעבור לדון במקרה כללי יותר של גרפים שבהם לקשתות יש משקלות. קרא ולמד את פרק 25 מתחילתו עד סוף התת-סעיף "קשתות בעלות משקלות שליליים". שאלה מצא את כל המסלולים הקצרים ביותר מ- s ל- t בגרף הבא: איור ב. התשובה בעמ' 4 עצי מסלולים קצרים ביותר לעתים קרובות לא די בקביעת המרחק מ- s לשאר הקדקודים בגרף, אלא יש למצוא לכל v s מסלול קצר ביותר מ- s ל- v. לפיכך דרוש כי המידע שמחזיר האלגוריתם יאפשר לנו לשחזר בכל רגע מסלול קצר ביותר מ- s ל- v. אנו מעוניינים אפוא בדרך נוחה לייצוג מסלולים קצרים ביותר. הדרך שנבחר היא לתחזק עבור כל קדקוד v את הקדקוד π(v) הקודם לו על אחד המסלולים הקצרים ביותר מ- s אליו. כלומר, אם המסלול הקצר ביותר שמוצא האלגוריתם מ- -v הוא: s a b... w u v אזי π(v) = u ו- w,π(u) = וכן הלאה. את הערך π(v) של כל v ניתן לתחזק ברשומה המתאימה ל- v. כך, לאחר ריצת האלגוריתם, הערך π(v) יהיה מוגדר לכל v (הניתן 3
מ, ל s ל s ל s ל s להגעה מ- s ), וכך (בדומה למצב ברשימה מקושרת), נוכל ללכת "אחורה" צעד אחר צעד מ- v ל-( π(v ולשחזר מסלול קצר ביותר מ- s ל- v (המסלול ישוחזר "מהסוף,π(u) = ל- w u- להתחלה"). כך, בדוגמה האחרונה נלך מ- v ל- u π(v) = וכן הלאה, עד π(b) = a ו- s π(a) = (הערך של π(s) הוא.(NIL למרות שעשויים להיות מספר רב של מסלולים קצרים ביותר מ- v ל- s, נקפיד כי לכל π(v) = u יוגדר קדקוד קודם v יחיד, המתאים רק לאחד המסלולים הקצרים ביותר. v בפרט, אם נתבונן בכל הקדקודים הניתנים להגעה מ- s ובקבוצת הקשתות π(v) v עבור π(v) כפי שהוגדרו לעיל, נגלה כי התקבל עץ מכוון ששורשו s. כזכור, בעץ מכוון ששורשו s, כל קדקוד v s הוא בעל דרגת כניסה מכוון יש אב יחיד u, (v,u) היא קשת בעץ, : לכל קדקוד v בעץ וזוהי הקשת היחידה בעץ הנכנסת ל- v. כמו כן, יש מסלול מכוון מהשורש s לכל שאר קדקודי העץ (וכן,d in (s) = 0 כלומר, ל- s לא נכנסות קשתות, שכן לשורש אין אב). ואכן, זהו המצב בגרף הקודם שתואר לעיל. לכל קדקוד v ישנו אב יחיד.π(v) בנוסף לכך ניתן להגיע מ- s לכל קדקוד v דרך הקשתות.(π(v), v) יתר על כן, לעץ זה יש תכונה מיוחדת: המסלול (היחיד) מ- s לכל G. בגרף המקורי -v בעץ הוא מסלול קצר ביותר מ- v נמחיש זאת בעזרת הגרף מאיור ב..: איור ב. 2 נניח כי האלגוריתם מגלה את המסלולים הקצרים ביותר הבאים מ- s לשאר הקדקודים: :a- 0 s a מ- :b- 6 s b מ- :c- 6 2 s b c מ- 6 2 s b c t ומ- s ל- t : 32
לפיכך נקבע כי: π(s) = NIL, π(a) = s, π(b) = s, π(c) = b, π(t) = c והעץ המתאים הוא: איור ב. 3 העץ מכיל מסלול יחיד מ- s לכל קדקוד v, s ואורך המסלול הזה שווה למרחק מ- v ל- s ב- G. כך, למשל, המרחק בין s ל- t ב- G הוא,9 וכך גם המרחק בין s ל- t בעץ. כלומר, לכל גרף, האלגוריתם מוצא עץ מכוון,T = (V π, E π ) V π היא קבוצת כאשר.(π(v), v) E π הקדקודים הניתנים להגעה מ- s, ו- היא קבוצת הקשתות בעץ זה המרחקים מ- s לשאר הקדקודים שווים למרחקים מ- s לשאר הקדקודים ב- G. w(e) עם משקולות G = (V, E) בסיכום: עבור כל גרף (שאינו מכיל מעגלים בעלי T = (V π, E π ), s V משקל שלילי הניתנים להגעה מ- s ) וקדקוד תמיד קיים עץ המושרש ב- s, כך שהמרחקים מ- s לשאר הקדקודים ב- T אינם גדולים מהמרחקים ב- G. כלומר, לכל v, s המרחק של v מ- s ב- T שווה למרחק של v מ- s בגרף המקורי G. יתר על כן, האלגוריתמים שלנו ימצאו עץ כזה. קרא ולמד את התת-סעיף "ייצוג מסלולים קצרים ביותר". שאלה 2 (שאלה 25.- מהספר) מצא שני עצי מסלולים קצרים ביותר עבור הגרף מאיור 25.2, המוצגים באיור. השונים מאלה התשובה בעמ' 4 קרא ולמד את המשך פרק 25 עד סוף סעיף 25.. 33
ל s שאלה 3 בצע את השגרה (w RELAX(u,,v עבור הגרף: איור ב. 4 (הערך הרשום בתוך כל קדקוד v הוא הערך d[v] של קדקוד זה.) התשובה בעמ' 4 שאלה 4 יהי הקלה (E G =,V) גרף מכוון ומשוקלל עם מקור s, ונניח כי בוצעה על G סדרת צעדי.(RELAX) הראה כי בכל רגע, לכל v, אם d[v] אינו, אזי d[v] הוא האורך של איזשהו מסלול מ- -v. התשובה בעמ' 42 שאלה 5 הראה כי אם בסדרת צעדי הקלה π(s) מקבל ערך שאיננו,NIL אזי G מכיל מעגל בעל משקל שלילי. התשובה בעמ' 42 האלגוריתם של דייקסטרה נעבור לדון באלגוריתם של דייקסטרה למציאת מסלולים קצרים ביותר מ- s לכל שאר הקדקודים בגרף (E G, =,V) כאשר לכל קשת e E יש משקל w(e) חיובי ממש (כלומר, מתקיים > 0 w(e) לכל.(e E קרא ולמד את סעיף 25.2. האלגוריתם של דייקסטרה מוצא את המרחקים מ- s לכל שאר הקדקודים בגרף מכוון בעל משקלות חיוביים, וזמן הריצה שלו הוא: 34
ב( א( ( ) Θ( E + V log V ) זמן זה מתקבל על-ידי המימוש היעיל ביותר של האלגוריתם, הנעזר בערימות פיבונצ'י. לא נרחיב כאן בפרטי מבנה הנתונים ערימות פיבונצ'י (ראה פרק 2 בספר EXTRACT-MIN הלימוד). נאמר רק כי זהו מבנה נתונים התומך בפעולות (שליפת n קדקוד המינימום) בעלות לשיעורין של Θ(log( n )) עבור קבוצה בת איברים, ובפעולה DECREASE-KEY (הקטנת ערכו של קדקוד בערימה) בעלות לשיעורין של הואיל ובאלגוריתם של דייקסטרה מתבצעות ( V ) O פעולות שליפה.Θ() ו-( E ) O פעולות של הקטנת ערכו של מפתח, מתקבל הזמן הנתון ב-( ), דהיינו,.Θ( E + V log V ) הערות: האלגוריתם של דייקסטרה מתאים (ללא שינויים) גם לריצה על גרפים לא ( מכוונים, וערכי ה-[ d[u המתקבלים הם מרחקי כל הקדקודים בגרף מקדקוד המקור s. אין זה קשה לראות כי במקרה שכל המשקלות שווים, או במקרה דומה, כאשר הגרף חסר משקלות, ריצת האלגוריתם של דייקסטרה זהה לריצת האלגוריתם.BFS (,25.2 שאלה 6 (שאלה 25.2- מהספר) הרץ את האלגוריתם של דייקסטרה על הגרף המכוון שבאיור תחילה עם הקדקוד s כמקור, ולאחר מכן עם הקדקוד y כמקור. על פי דוגמת איור 25.5 בספר, הראה את ערכי d ו- π ואת הקדקודים בקבוצה S אחר כל איטרציה של לולאת ה- while. התשובה בעמ' 43 שאלה 7 (שאלה 25.2-2 מהספר) הבא דוגמה פשוטה לגרף מכוון עם קשתות בעלות משקלות שליליים, שעבורו מפיק האלגוריתם של דייקסטרה תשובות שגויות. מדוע ההוכחה של משפט 25.0 אינה פועלת כאשר מרשים קשתות בעלות משקלות שליליים? התשובה בעמ' 46 35
משקלות שליליים נסיים את הפרק בדיון במקרה הכללי ביותר של בעיית מציאת המרחקים מ- s, והוא המקרה של גרף מכוון שבו משקלות הקשתות עשויים להיות שליליים. הערה: במקרה של משקלות שליליים לא נדון בגרפים לא מכוונים, אלא בגרפים מכוונים בלבד. בגרף בלתי מכוון, המשמעות המידית של כל קשת שלילית היא מעגל בעל משקל שלילי. לדוגמה, נתבונן בגרף: איור ב. 5 בגרף זה ניתן להגיע מ- s ל- b, ואז ללכת הלוך וחזור על הקשת (b,c), וכך להקטין כרצוננו את משקל המסלול מ- s לקדקודים b a, ו- c. לכן, אם ברכיב הקשיר של s ({s, a, b, c} (בדוגמה שלנו, בגרף המושרה על-ידי ישנה קשת בעלת משקל שלילי, המרחק של s מקדקודי הרכיב אינו מוגדר היטב. יתר על כן, אם הרכיב הקשיר של s אינו מכיל קשתות בעלות משקל שלילי, אזי ניתן למצוא את המרחקים לקדקודים ברכיב הקשיר של s בעזרת האלגוריתם של דייקסטרה, ואין צורך באלגוריתם הכללי יותר. כמו כן, המרחקים מ- s לקדקודים שאינם ברכיב הקשיר שלו הם אינסופיים, ללא קשר למשקלות וגם אם קיימים, כמו באיור ב. 5, משקלות שליליים ברכיבים הקשירים האחרים (למשל, המרחק מ- s ל- e אינסופי, שכן אין כלל מסלול מ- s ל- e ). ובסיכום, אין שום טעם לדון במשקלות שליליים במקרה הבלתי מכוון. גם עבור גרפים מכוונים ישנם מקרים שבהם אין משמעות לבעיית חישוב המרחקים, וזאת כאשר הגרף מכיל מעגל בעל משקל שלילי הניתן להגעה מ- s. במקרה זה נוכל להקטין כרצוננו את המרחק מ- s לקדקודי מעגל זה. לדוגמה, נתבונן בגרף: 36
איור ב. 6 בגרף זה, המעגל b c d b הוא בעל משקל שלילי. הואיל וניתן להגיע מ- s ל- b, ניתן להקיף את המעגל מספר פעמים רב כרצוננו, וכך להקטין כרצוננו את המרחק מ- s לקדקודי המעגל. לכן, לצורך הדיון נניח כי הגרף אינו מכיל מעגל בעל משקל שלילי הניתן להגעה מ- s. קרא ולמד את סעיף 25.3. נסביר באופן אינטואיטיבי את הסיבה לכך שאלגוריתם BELLMAN-FORD כהלכה. פועל BELLMAN-FORD כמו האלגוריתם של דייקסטרה, האלגוריתם מבצע סדרה של צעדי הקלה; ביתר דיוק, מתבצעות V איטרציות, שבכל אחת מהן מתבצעת הקלה על כל קשת. (לכן ישנם בדיוק E ( V ) צעדי הקלה.) במהלך האלגוריתם, לכל v s הערך d[v] קט ן בהדרגה, עד השלב הסופי שבו d[v] משתווה v כאשר v) δ(s, הוא המרחק של מ- s. כזכור, עד אותו שלב מתקיים ל-( v,δ(s,.δ(s, v) < d[v]?δ(s, v) ל- d[v] אם כן, באיזה שלב "יגיע" כלומר, אחרי כמה איטרציות של הלולאה שבשורה 2 באלגוריתם BELLMAN-FORD ישתווה הערך d[v] למרחק של v מ- s? ובכן, הדבר תלוי במבנה של המסלולים הקצרים ביותר מ- s ל- v. לדוגמה, נתבונן בגרף: איור ב. 7 37
מ ) ל s.0 s קל לבדוק (ישירות) כי המרחק בין ל- b, למשל, הוא להלן כל המסלולים הקצרים ביותר מ- s ל- b : 8 2 s c b 8 4 2 s c d b 8 3 7 2 s c a d b מסלול א: מסלול ב: מסלול ג: מבין שלושת המסלולים הקצרים ביותר, מסלול א הוא המכיל מספר מינימלי של קשתות. כלומר, מספר הקשתות הקטן ביותר במסלול (המשוקלל) הקצר ביותר מ- s ל- b הוא 2. ניתן לראות אפוא כי מובטח לנו שבגרף זה, לאחר שתי איטרציות באלגוריתם.δ(s, b) = d[b] המשתנה d[b] כבר מעודכן, כלומר, מתקיים,BELLMAN-FORD ובאופן כללי, נסכם את התכונה המאפיינת את אלגוריתם BELLMAN-FORD כך: תכונה : עבור כל,v s נתבונן באוסף המסלולים הקצרים ביותר מ- v ל- s. אם מבין כל המסלולים הקצרים ביותר הללו, נבחר את המסלול P המכיל (גם) מספר מינימלי k d[v],k של קשתות, ואם מספר הקשתות ב- P הוא אזי "יגיע" ל-( v δ(s, אחרי איטרציות לכל היותר של הלולאה שבשורה 5. לדוגמה, באיור ב. 7, המרחק בין s ל- e הוא 2. מבין כל המסלולים הקצרים ביותר מ- 8 2 2 s c b e ולכן d[e] יגיע לערכו הסופי δ(s,e) לאחר 3 איטרציות של הלולאה שבשורה 5. (שים לב כי קיימים גם מסלולים קצרים ביותר מ- s ל- e המכילים מספר רב יותר של 8 4 2 2 קשתות, למשל,.( s c d b e -e, המסלול המכיל (גם) מספר מינימלי של קשתות הוא: -s) על הגרף שבאיור ב. 7. ודא את קיומה של שאלה 8 הרץ את אלגוריתם BELLMAN-FORD תכונה שלעיל עבור כל קדקודי הגרף. התשובה בעמ' 48 38
עתה נוכל להבין מדוע לא דרושות יותר מ- V איטרציות של הלולאה שבשורה 2 באלגוריתם.BELLMAN-FORD בהנחה כי הגרף אינו מכיל מעגלים בעלי משקל שלילי הניתנים להגעה מ- s, תמיד קיים מסלול קצר ביותר מ- s לכל קדקוד v s המכיל לכל היותר V V קשתות. נסביר זאת: אם במסלול מהמקור s לקדקוד v ישנן קשתות או יותר, אזי על המסלול הזה ישנם V + קדקודים או יותר (מדוע?). ולפיכך, הואיל ובגרף ישנם רק V קדקודים ואילו במסלול ישנם V + קדקודים, ישנו לפחות קדקוד אחד המופיע פעמיים על המסלול, כלומר, המסלול מכיל מעגל. נתאר זאת בעזרת איור: איור ב. 8 המסלול עובר מ- s עד x, ואחר כך עובר לאורך מעגל עד שהוא חוזר ל- x, וממשיך משם ל- v. מאחר שמשקל המעגל אינו שלילי (ומאחר שאם משקל המעגל הוא 0 ניתן להסיר אותו) נקבל מסלול טוב לפחות כמו זה שבאיור ב. 8 אם נסיר את המעגל מהמסלול, ויתקבל המסלול החדש:.s x v אם המסלול עדיין מכיל + V קדקודים או יותר, פירוש הדבר שהמסלול עדיין מכיל מעגלים, ונוכל להסיר את כולם באופן דומה בזה אחר זה. לבסוף לא ייוותרו מעגלים על המסלול, והוא יכיל לכל היותר V קדקודים. לפיכך, מספר הקשתות על המסלול (אשר תמיד קטן ב- ממספר הקדקודים) אינו עולה על V. הואיל ומשקל המעגלים שהסרנו הוא חיובי ממש או אפס, קיבלנו מסלול טוב לפחות כמו המסלול (שהכיל מעגלים) שממנו התחלנו. אנו רואים אפוא כי במקרה שאין מעגל בעל משקל שלילי הניתן להגעה מ- s, תמיד ישנו מסלול קצר ביותר מ- s לכל v המכיל לא יותר מ- V קשתות. v מתכונה ומהדיון שלעיל נובע כי המרחק של כל מ- s יעודכן לאחר V איטרציות לכל היותר, שכן ישנו מסלול קצר ביותר מ- s לכל קדקוד אחר המכיל לא יותר מ- V קשתות. יתר על כן, אם מתבצע עדכון של d[v] (כלומר, הקטנת (d[v] עבור קדקוד קצר ביותר מ- s לקדקוד v באיטרציה מספר V, הדבר מעיד כי קיים מסלול v המכיל V קשתות או יותר; מכך נובע בהכרח כי קיים בגרף מעגל בעל משקל שלילי, ויש להחזיר,FALSE כפי שהאלגוריתם אכן עושה. 39
א( א( ב( ג( ב( ג( ב( שאלה 9 u, v V.e E w(e) יהי E) G = (V, גרף מכוון עם משקל לכל קשת לכל נסמן את מספר הקשתות המינימלי שיש במסלול קצר ביותר מ- u ל- v, m = max{num(u, v)} u, v V ב-( v num(u, ונסמן: ( הראה כי V.m אחרי כמה איטרציות של הלולאה שבשורה 2 ניתן לעצור את האלגוריתם? ( (בטא זאת כפונקציה של m.) הצע שינוי פשוט באלגוריתם BELLMAN-FORD לפי התשובה שנתת ב- ), כך שהאלגוריתם יעצור אחרי המספר המינימלי האפשרי של איטרציות. ( התשובה בעמ' 50 סיכום נסכם בטבלה את כל המקרים של בעיית המסלולים הקצרים ביותר מ- s שראינו, ואת האלגוריתם שפותר אותם: משקלות חסר משקלות משקלות חיוביים משקלות חיוביים גרף ושליליים האלגוריתם BFS מכוון אלגוריתם אלגוריתם דייקסטרה בלמן-פורד האלגוריתם BFS בלתי-מכוון אלגוריתם דייקסטרה נסכם גם את סדר הגודל של זמן הריצה, ואת מבנה הנתונים שבו משתמש כל אחד מהאלגוריתמים: האלגוריתם :BFS משתמש בתור ורץ בזמן.Θ( E + V ) ( האלגוריתם של דייקסטרה: משתמש בערימת פיבונצ'י ורץ בזמן (.Θ( E + V log V ) האלגוריתם של בלמן-פורד: משתמש רק ברשימות הסמיכות ורץ בזמן.Θ( E V ) ( 40
תשובות לפרק ב תשובה ניתן לבדוק ישירות כי המרחק בין s ל- t הוא 9. המסלולים הקצרים ביותר הם: 0 - s æææ ffi a æææ ffi t 6 3 s æ æffi b æ æffi t 0-4 3 s æææ ffi a æææ ffi b æ æffi t 6 2 s æ æffi b æ æffi c æ æffi t 0-4 2 s æææ ffi a æææ ffi b æ æffi c æ æffi t תשובה 2 יש למצוא עץ שבו המרחק של כל הקדקודים מ- s שווה למרחקם מ- s דוגמאות נוספות לעצים כאלה מובאות להלן: ב- G. שתי איור ב. 9 תשובה 3 מתבצעת הבדיקה: d[v] > d[u] + w(u, v) כלומר בודקים אם: 8 > 4 + 3 = 7 מאחר שהאי-שוויון מתקיים, מתבצעת הפקודה = 7 v),d[v] d[u] + w(u, ולכן הגרף המתקבל הוא: 4
איור ב. 0 תשובה 4 נראה זאת באינדוקציה על צעדי ההקלה. בהתחלה, לפני ביצוע צעדי ההקלה, מתקיים = d[v] לכל,v s ו- 0 =,d[s] והטענה מתקיימת באופן טריוויאלי. נניח כי הטענה מתקיימת אחרי צעד ההקלה ה- i, ונוכיח כי היא מתקיימת אחרי צעד ההקלה ה- + i. אם d[v] משתנה, מתבצעת הפעולה: d[v] d[u] + w(u, v) (שכן אחרת לא היה מתקיים v),(d[v] > d[u] + w(u, הרי מאחר ש- < d[u] שמהנחת האינדוקציה נובע שקיים מסלול P שאורכו d[u] מ- s ל- u. ולכן המסלול הבא: איור ב. המתקבל כאשר מוסיפים למסלול P את הקשת (v,u), הוא מסלול מ- s ל- v שאורכו: d[u] + w(u, v) = d[v] d[v] d[v] ולכן ישנו מסלול מ- s ל- v שאורכו עבור הערך החדש, כפי שנדרשנו להוכיח. תשובה 5 d[s] בכל פעם ש-( π(s מקבל ערך חדש, קודם לכך עדכון (כלומר הקטנת) (ראה שורות ו- 2 בשגרה.(RELAX מאחר שערכו ההתחלתי של 0, הוא הרי שאם d[s] 42
,NIL מקבל ערך שאינו π(s) נובע מכך ש-[ d[s הופך להיות שלילי במהלך סדרת צעדי ההקלה. נשתמש עתה בשאלה 4. משאלה זו נובע כי ישנו מסלול בעל משקל שלילי מ- s ל- s, שכן ישנו מסלול מ- s ל- s שמשקלו < 0.d[s] אך מסלול מ- s ל- s הוא מעגל, ולכן ישנו ב- G מעגל בעל משקל שלילי, אשר, כמובן, ניתן להגעה מ- s. תשובה 6 הרצת האלגוריתם עם s כמקור: לאחר האתחול, מצב הגרף הוא: איור ב. 2 ותור הקדימויות Q מכיל את כל הקדקודים. לאחר מכן s מוצא מהתור, ומתבצעים צעדי הקלה מ- s לשכניו. הגרף המתקבל הוא: איור ב. 3 כעת הוא בעל הערך המינימלי מבין האיברים בתור. u נמחק מהתור d[u] u ומתבצעים צעדי הקלה מ- u לכל שכניו: 43
איור ב. 4 כעת, x הוא בעל הערך d[x] המינימלי מבין האיברים בתור. לכן x נמחק מהתור, ומתבצעת סדרת צעדי הקלה מ- x לשכניו: איור ב. 5 לאחר מכן v מוצא מהתור, ומתבצעת הקלה מ- v ל- y, שאינה משנה את :d[y] איור ב. 6 ועתה y מוצא מהתור, צעדי ההקלה (מ- y ל- v ומ- y ל- s ) שמתבצעים אינם משפיעים, התור Q מתרוקן, והאלגוריתם עוצר. הקשתות המודגשות מייצגות לכל v את.π(v) כך, למשל,,π(y) = x והקשת y) (x, מודגשת. עתה נתאר את הרצת האלגוריתם עם y כמקור. 44
אתחול: איור ב. 7 לאחר צעדי ההקלה מ- y : איור ב. 8 לאחר צעדי ההקלה מ- s : איור ב. 9 ועתה, צעדי ההקלה מ- u, v ו- x אינם משנים דבר, והאלגוריתם עוצר. 45
תשובה 7 נתבונן בגרף שבאיור ב. 20, ונדגים מה קורה כאשר מריצים עליו את אלגוריתם דייקסטרה. איור ב. 20 לאחר ביצוע צעדי ההקלה מ- s, מתקבל הגרף: איור ב. 2.3 לאחר מכן, v מוצא מתור הקדימויות ומתבצעת הקלה ל- w, ו-[ d[w מקבל את הערך ערכו של d[w] לא ישתנה עוד, שכן ל- w לא נכנסות קשתות אחרות, חוץ מהקשת d[w] הנכנסת מ- v. v ייצא מהתור (ולא ייכנס אליו עוד). אולם אינו מייצג את,2 3 2 s u v w המרחק הנכון מ- s, שכן קיים המסלול שמשקלו וכרגע = 3.d[w] מדוע האלגוריתם אינו פועל כהלכה? הדבר נובע מקיומה של הקשת בעלת המשקל השלילי v),(u, שמשקלה. 2 כאשר האלגוריתם של דייקסטרה מורץ על גרף בעל משקלות חיוביים, מובטח לנו שמהרגע שהערך d[x] של קדקוד x הופך למינימלי ב- Q, בהכרח d[x] "הגיע" ל-( x,δ(s, כלומר, שווה למרחק של s מ- x. כאשר ישנן קשתות בעלות משקל שלילי, תכונה זו אינה מובטחת. למשל, בגרף שבאיור ב. 2, v מוכנס לתור עם.d[v] = 2 לאחר מכן, מעדכנים את d[w] ל- 3, ו- v מוצא מהתור, בהסתמך על כך ש-[ d[v לא יקטן עוד, ולכן v לא יוכל עוד להקטין את ערכו של.d[w] 46
ל s אולם במקרה של משקלות שליליים, ערכו של d[v] לא בהכרח שווה ל-( δ(s,v כאשר (u, v) d[v] נבחר. למעשה, ניתן להקטין את ל- בעזרת הקשת בעלת המשקל v v השלילי 2. על כן, במקרה של משקלות שליליים, אין אפשרות למחוק את מן התור ברגע ש-[ d[v הופך למינימלי ב- Q, והאלגוריתם אינו פועל כהלכה. נעבור על הוכחת משפט 25.0, ונראה היכן ההוכחה נכשלת כאשר הגרף מכיל קשתות בעלות משקל שלילי. נחזור ונביא כאן את איור 25.6 מהספר: איור ב. 22 u הנחנו בשלילה, לצורך קבלת סתירה, שקדקוד עומד להיכנס ל- S, אך.δ(s, u) d[u] כלומר, d[u] עדיין לא "הגיע" למרחק של s מ- u בעת כניסתו של u ל- S. במקרה שכל המשקלות חיוביים, הנחה זו אכן מובילה לסתירה. הדרך לקבלת y,d[u] d[y] הסתירה היא זו: מכך ש- u נבחר, נובע כי כאשר הוא הקדקוד הראשון במסלול הקצר ביותר מ- s ל- u שאינו ב- S. אך מכך ש- y נמצא על המסלול הקצר ביותר מ- -u, ומכך ש-[ d[x,δ(s, (x = קיבלנו כי.d[y] = δ(s,y) עולה על המרחק מ- s ל- u : ומכאן קיבלנו כי: כדי להמשיך את הטיעון, השתמשנו בכך שהמרחק מ- s ל- y אינו δ(s, y) δ(s, u) d[u] d[y] = δ(s, y) δ(s, u) < d[u] ולכן התקבלה סתירה. אך במקרה שישנם משקלות שליליים, לא בהכרח מתקיים: ואי אפשר להמשיך את הטיעון. δ(s, y) δ(s, u) 47
P מ- y ל- u. הואיל וישנן P 2 שהוא המשך המסלול לצורך ההסבר נתבונן במסלול P 2 שלילי, ולכן קשתות בעלות משקל שלילי, בהחלט ייתכן שמשקל מסלול ההמשך (P 2 משקל המסלול מ- s ל- u (השווה למשקל המסלול מ- s ל- y ועוד משקל המסלול קטן ממשקל המסלול מ- s ל- y. לכן, ייתכן כי (y,δ(s, (u < δ(s, ולא ניתן לקבל את הסתירה כנדרש. תשובה 8 מצב הגרף לאחר האתחול: איור ב. 23 עתה מתבצעות V = 5 איטרציות, שבכל אחת מהן מתבצע צעד הקלה על כל קשת. נניח כי בכל איטרציה המעבר על הקשתות מתבצע בסדר לקסיקוגראפי: (a, b), (a, d), (b, a), (b, e), (c, a), (c, b), (c, d), (d, b), (d, e), (s, a), (s, c) לאחר האיטרציה הראשונה, מצב הגרף הוא: איור ב. 24 ולאחר האיטרציה השנייה: 48
ל b איור ב. 25 לדוגמה, בצעד ההקלה מ- c ל- b, d[b] קיבל את הערך 0, שכן,d[c] + w(c,b) = 0,6 + 8 = 4 והדבר מחק את הערך ש- a העניק קודם ל-[ d[b : ערך הגדול מ- 0. לעומת זאת, ל-[ d[e ערך 6 ולא 2, שכן צעד ההקלה מ- b ל- e קדם להקטנת d[b] מ- 4 ל- 0 (בשל הסדר שבו נסרקות הקשתות), ולכן בזמן ההקלה מ- -e, ערכו של d[b] היה.4 באיטרציה השלישית מתעדכן הערך :d[e] איור ב. 26 האיטרציות הרביעית והחמישית אינן משנה ערכי d. בשלב זה האלגוריתם עוצר, שכן כל הערכים נכונים. נוודא את קיומה של תכונה עבור הקדקודים שטרם בדקנו..δ(s, c) = 8 עבור הקדקוד c, כמו כן, המסלול הקצר ביותר בעל מספר הקשתות 8 s המינימלי מ- s ל- c הוא c, המכיל קשת יחידה. ואכן, d[c] מגיע לערכו הנכון (c δ(s, לאחר איטרציה אחת (בדוק!). 49
ב( ג( א( ל s לעומת זאת, המסלול הקצר ביותר בעל מספר הקשתות המינימלי מ- -a הוא: 8 3 s c a ו-[ d[a מגיע ל-( δ(s,a לאחר 2 איטרציות. באופן דומה, המסלול המתאים ל- d הוא: 8 4 s c d ו- d מתעדכן לערכו הנכון לאחר 2 איטרציות. תשובה 9 כאמור לכל num(u, (v,u, v אינו עולה על V, שכן עבור כל זוג ישנו מסלול (,u, v קצר ביותר שאינו מכיל יותר מ- V קשתות. הואיל ולכל,num(u, v) V נובע מכך כי המקסימום מבין המספרים (v num(u, אינו עולה על V. m לכאורה, ניתן לעצור את האלגוריתם לאחר איטרציות, שכן לפי תכונה, (.m לאחר m איטרציות כל ערכי d[v] מעודכנים. למעשה, איננו יודעים מראש את לכן, בכל איטרציה נשמור משתנה change הבודק אם חלו באיטרציה זו עדכונים כלשהם בערכי d. אם לא חלו שינויים, ניתן לעצור את האלגוריתם. לכן, האלגוריתם יעצור לאחר + m איטרציות: יעודכנו כנדרש, ובאיטרציה הנוספת נבחין כי לא חלו שינויים. לאחר m איטרציות כל ערכי d ( האלגוריתם המעודכן הוא (עבור מקור s ואוסף משקלות w): BELLMAN-FORD m (G, w, s) INITIALIZE-SINGLE-SOURCE(G, s) 2 change TRUE 3 while change = TRUE 4 5 6 do change FALSE for each edge (u, v) E do RELAX-m(u, v, w) RELAX-m(u, v, w) if d[v] > d[u] + w(u,v) 2 3 4 then d[v] d[u] + w(u,v) π[v] u change TRUE 50
הערה: במקרה של מעגלים בעלי משקל שלילי, האלגוריתם בגרסתו החדשה יבצע לולאה אינסופית, שכן ערכי d לא יפסיקו להשתנות. ניתן לתקן זאת באופן פשוט על ידי כך שנמנה את האיטרציות (בדומה למצב באלגוריתם BELLMAN-FORD הרגיל), ונעצור את האלגוריתם אם חל עדכון באיטרציה מספר V. 5
52
ג: פרק עצים פורשים מינימליים בעיית העץ הפורש המינימלי את בעיית העץ הפורש המינימלי נדגים בעזרת המקרה הבא: נניח כי יש לבנות אוסף של מסילות ברזל שיקשרו בין ערים שונות ברשת ערים. עוד נניח כי קיים "אילוץ קשירות": דרוש כי לאחר הנחת פסי הרכבת אפשר יהיה לנסוע ברכבת מכל עיר לכל עיר אחרת ברשת. כמו כן, נניח כי השיקול היחיד בבחירת מיקום המסילות הוא כספי: יש להניח את המסילות בעלות כוללת מינימלית, תוך קיום אילוץ הקשירות. הנחה סבירה היא, שלא תמיד אפשר להניח פס רכבת ישיר בין שתי ערים, עקב מכשולים פיסיים או אחרים; ולכן, ישנה קבוצה חלקית של זוגות ערים שניתן לחבר ביניהן באמצעות מסילה. עבור כל זוג ערים v ו- u כאלה, שניתן לחברן במסילה, נתון לנו משקל,w(u, v) > 0 המציין את עלות הנחת מסילת הרכבת מ- u ל- v, בהתחשב במרחק הפיסי בין u ל- v, במכשולים בדרך, וכדומה. נוכל לבנות מודל לבעיה זו על-ידי תכנון גרף משוקלל; לדוגמה, נתבונן בגרף E) G = (V, הבא: איור ג. הקדקודים a, b,..., h מייצגים את הערים השונות. הגרף מכיל קשת בין זוג קדקודים אם ורק אם קיימת אפשרות להניח מסילה בין שתי הערים. המספר הרשום ליד כל קשת מייצג את עלות הנחת המסילה. בדוגמה זו, התת-גרף בעל 53
העלות המינימלית המקיים את אילוץ הקשירות הוא התת-גרף שבאיור ג. 2, המהווה עץ. איור ג. 2 נשים לב כי אילוץ הקשירות נשמר: בעץ תמיד ניתן להגיע מכל קדקוד לכל קדקוד אחר, שכן עץ הוא תת-גרף קשיר. מתברר כי במקרה שבו כל המשקלות חיוביים, הפתרון לשאלת "קשירות בעלות מינימלית" מעין זו הוא תמיד עץ. הבעיה הדנה בבחירת תת-גרף המקשר בין כל הקדקודים, בעלות מינימלית, נקראת בעיית העץ הפורש המינימלי. עץ E') T = (V, המכיל את כל קדקודי הגרף ורק חלק מהקשתות נקרא עץ פורש גרף (שכן הוא "פורש" כביכול את כל קדקודי הגרף). בבעיית העץ הפורש המינימלי נתון,e E לכל קשת w(e) עם משקל > 0 G = (V, E) ואנו דנים במציאת עץ פורש שמשקלו (כלומר, סכום משקלי קשתותיו) מינימלי מבין משקלי כל T = (V, E') העצים הפורשים האחרים. קרא ולמד את פרק 24 מתחילתו ועד סוף סעיף 24. שאלה נתון הגרף: איור ג. 3 54
א( ד( ב( ה( ג( S = {a, b, d, h} נתבונן בקבוצת הקדקודים ובקבוצת הקשתות.A = {(a, b), (d, g), (h, g)} ( מהו החתך שמייצגת הקבוצה S? האם החתך?A מכבד את (S, V \ S) אילו מקשתות A אינן חוצות את?(S, V \ S) ( ( מהן הקשתות הקלות החוצות את?(S, V \ S) ( ( מהו העץ הפורש המינימלי בגרף? התשובה בעמ' 66 שאלה 2 (שאלה 24.- מהספר) תהי (v,u) קשת בעלת משקל מינימלי בגרף G. הראה כי (v,u) שייכת לאיזשהו עץ פורש מינימלי של G. התשובה בעמ' 67 שאלה 3 (שאלה 24.-3 מהספר) הראה כי אם קשת (v,u) מוכלת באיזשהו עץ פורש מינימלי, אזי היא קשת קלה החוצה איזשהו חתך של הגרף. התשובה בעמ' 7 נזכור כי הגענו לבעיה של מציאת עץ פורש בעל משקל מינימלי עקב הרצון למצוא תת-גרף בעל עלות מינימלית המקשר בין קבוצת כל הקדקודים. בשאלה הבאה נדון בכך. שאלה 4 (שאלה 24.-7 מהספר) הראה שאם כל המשקלות של קשתות גרף הם חיוביים, אזי כל תת-קבוצה של קשתות המחברת את כל הקדקודים ואשר משקלה הכולל מינימלי היא בהכרח עץ. מצא דוגמה המראה שמסקנה זו אינה נובעת אם אנו מרשים שחלק מן המשקלות יהיו אי-חיוביים. התשובה בעמ' 73 תחזוקת קבוצות זרות כאמור, האלגוריתמים הבונים עץ פורש מינימלי שומרים בכל רגע נתון אוסף A של קשתות, המוכלות באיזשהו עץ פורש מינימלי. כלומר, בכל רגע, הגרף: 55
G A = (V, A), A E G A הוא עץ. הוא יער (אוסף עצים), וכל רכיב קשיר של בכל רגע במהלך הרצת האלגוריתם קיים עץ פורש מינימלי ('E T, =,V) כך ש-' E A. כלומר, קבוצת הקשתות A שכבר הוספנו לעץ הנבנה מוכלת בקבוצת הקשתות 'E של איזשהו עץ פורש מינימלי. בשלב הבא נוסיף ל- A קשת e בטוחה עבור A, שתקשר שניים מעצי.( G A G A לעץ יחיד (ותפחית ב- את מספר הרכיבים הקשירים ב- נתאר זאת בעזרת האיור הבא: איור ג. 4 e,g A ב- באיור זה, המשולשים מייצגים את העצים (הרכיבים הקשירים) והקשת מייצגת קשת בטוחה עבור A. הקשת נקראת בטוחה, משום שגם אם נוסיף את e.a {e} ל- A, עדיין קיים עץ פורש מינימלי המכיל את עם זאת, ייתכן שאין זה אותו עץ קודם ('E T =,V) שהכיל רק את A. אך בהכרח קיים איזשהו עץ פורש, אולי אחר, המכיל את {e} A. e T 5,T 4 לאחר הוספת e, העצים והקשת הופכים לעץ יחיד. נשים לב כי אסור T i להוסיף ל- A קשתות שהן קשתות פנימיות באחד העצים (כלומר, קשת ששני.(T ב- קדקודיה נמצאים, למשל, אם נוסיף ל- A קשת פנימית של אחד העצים, ייווצר מעגל (מדוע?), ולכן קשת e כזאת בוודאי אינה בטוחה עבור A. אנו זקוקים אפוא לדרך יעילה שבאמצעותה נוכל "לזכור" מהם הקדקודים בכל רכיב קשיר ברגע נתון, וכן לדרך שתאפשר לנו לאחד לקבוצה אחת את הקדקודים של שני עצים נפרדים, כך שיתקבל רכיב קשיר גדול יותר (כמו במקרה של.(T 4 T 5 {e} כדי לנהל בצורה יעילה אלגוריתמים מסוג זה, אנו זקוקים למבנה 56