מבני נתונים ואלגוריתמים - מחברת קורס/גרפים/אלגוריתם Dijkstra/תרגילים/מסלולים זולים עם קשת יחידה שלילית/תשובה

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

שימו לב:

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

נניח שזהו הגרף המקורי:

הבעיה המקורית.
הבעיה המקורית.

נבנה גרף חדש כך.

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

שכפול הצמתים.
שכפול הצמתים.

כעת נוסיף גם קשתות:

  1. במקום כל קשת בגרף המקורי, למעט הקשת השלילית, נמתח קשת מהצומת המתאים ל ב לצומת המתאים ל ב.
  2. במקום כל קשת בגרף המקורי, למעט הקשת השלילית, נמתח קשת מהצומת המתאים ל ב לצומת המתאים ל ב.
  3. במקום הקשת השלילית (בגרף המקורי), נמתח קשת מהצומת המתאים ל ב לצומת המתאים ל ב במחיר 0. התרשים הבא מראה זאת.
הוספת הקשתות.
הוספת הקשתות.

נניח שלקשת השלילית היה מחיר . בנוסף נמתח עוד שני סוגי קשתות:

  1. לכל צומת ב, נמתח קשת במחיר בין ב לבין ‏ ב.
  2. לכל צומת ב, נמתח קשת במחיר 0 בין ב לבין ‏ ב.(לא נצייר קשתות אלו מטעמי נוחות.)

נשים לב שאם כל הגרפים הנ"ל מיוצגים ברשימת שכנויות, אז סיבוכיות הבניה היא .

המשפט הבא מסביר את חשיבות הגרף החדש.



משפט:

מחיר המסלול הזול ביותר מ ל בגרף המקורי, קטן בדיוק ב ממחיר המסלול הזול ביותר מ ל ב בגרף החדש.



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

כעת כל הקשתות אינן שליליות, ומותר להריץ את Dijkstra.

קל לראות שהסיבוכיות הכוללת היא זו של Dijkstra.