אלגוריתם דייקסטרה
יש לערוך ערך זה. הסיבה היא: שיפורי ניסוח, שימוש עקבי ב-Latex, שיפור ביאורים (האם כולם הכרחיים?)..
| ||
יש לערוך ערך זה. הסיבה היא: שיפורי ניסוח, שימוש עקבי ב-Latex, שיפור ביאורים (האם כולם הכרחיים?).. | |
אנימציה להמחשת האלגוריתם. משקלי הקשתות שווים למרחק הגיאומטרי בינהן. | |
מבנה נתונים | תור קדימויות |
---|---|
סיבוכיות זמן | ישנם מספר מימושים, האופטימלי בהם O(|V|log|V|+|E|) |
סיבוכיות מקום | O(|V|) |
ממציא | מספר ממציאים בלתי תלויים, ראה בהמשך הערך |
נקרא על שם | אדסחר דייקסטרה |
הומצא | 1956 |
אלגוריתם דייקסטרה הוא אלגוריתם למציאת המסלול הקל ביותר מקודקוד מקור לקודקוד יעד בגרף ממושקל בעל משקלים חיוביים, או למציאת כל המסלולים הקלים ביותר מקודקוד מקור לשאר הקודקודים (בעיית המסלולים הקלים ממקור יחיד). לעיתים מחליפים את המונח "מסלול קל" ב"מסלול קצר" או "מסלול מינימלי".
המסלול הקל ביותר בין שתי נקודות מוגדר כמסלול שסכום משקלי הקשתות במסלול הוא הנמוך ביותר מבין כל המסלולים האפשריים. האלגוריתם עובד על גרף מכוון או לא מכוון, בעל משקולות אי-שליליות על הקשתות. בגרף המייצג רשת כבישים, המסלול הקל הוא הדרך המהירה ביותר להגיע ממקום למקום.
אילו הגרף היה רשת תעלות זהות וללא הבדלי גובה, ומשקל קשת היה מייצג אורך תעלה, ניתן להמחיש את האלגוריתם כך: יוזרמו מים מהמקור, כך שהמים יתקדמו בקצב אחיד בתעלות. כשמים מגיעים לקודקוד לראשונה, המסלול שהמים עשו מהמקור לקודקוד זה הינו המסלול הקל ביותר אליו.
הגדרות
[עריכת קוד מקור | עריכה]האלגוריתם פועל על גרפים מכוונים או לא מכוונים, בעלי משקלים חיוביים.
האלגוריתם מקבל גרף וקודקוד מקור, ומוצא את המסלולים הקלים ביותר מהמקור לכל קודקוד אחר בגרף. אלטרנטיבית, האלגוריתם יכול לקבל גם קודקוד יעד, ולמצוא את המסלול הקל ביותר מהמקור ליעד.
המסלול הקל ביותר לקודקוד u מוגדר כמסלול מהמקור ל-u, כך שסכום משקלי הקשתות לאורך המסלול הוא מינימלי מבין כל המסלולים. סכום זה נקרא המרחק בין המקור ל-u.
בביטויי סיבוכיות, הביטויים E ו-V מתייחסים לגודל קבוצת הקודקודים והקשתות, ולא לקבוצות עצמן. למשל, O(V+E) הוא כתיב מקוצר של O(|V|+|E|).
האלגוריתם
[עריכת קוד מקור | עריכה]פסאודו קוד
[עריכת קוד מקור | עריכה]DistEst הינו מיפוי מקודקוד להערכת המרחק מהמקור. Prev הוא מיפוי מקודקוד לקודקוד שקודם לו במסלול הקל ביותר שהתגלה עד כה.
הפסודו קוד מוצא את המסלול הקצר ביותר מהמקור לכל קודקוד בגרף. אם המטרה היא למצוא רק את המסלול הקצר ביותר ממקור ליעד מסוים, ניתן לשנות את תנאי העצירה של הלולאה הראשית כך שיעצור לאחר שקודקוד היעד נשלף מ-Q.
function Dijkstra(Graph, Source):
for v in Graph.Vertices:
DistEst[v] = ∞
Prev[v] = NIL
DistEst[Source] = 0
Initialize min priority queue Q, with all graph vertices, keyed by their DistEst[v]
while Q is not empty:
u = Q.ExtractMin()
for v adjacent to u:
if DistEst[v] > DistEst[u] + Weight(u,v):
-- a shorter path to v has been discovered!
DistEst[v] = DistEst[u] + Weight(u,v)
Prev[v] = u
Q.DecreaseKey(v, DistEst[v])
return DistEst, Prev
הסבר ואינטואיציה
[עריכת קוד מקור | עריכה]אלגוריתם דייקסטרה הוא מעין גרסה של חיפוש לרוחב שמתחשב במשקלי הקשתות. במקום לשמור קודקודים לסריקה בתור (כמו בחיפוש לרוחב), דייקסטרה משתמש בתור קדימויות בו העדיפות נקבעת לפי הערכת מרחק מהמקור.
באתחול, כל הערכות המרחק מאותחלות כאינסוף, פרט להערכת המרחק למקור, שהיא 0 (המרחק מקודקוד לעצמו הוא 0).
בכל איטרציה, יישלף הקודקוד שהערכת מרחקו מינימלית. בשלב זה המסלול הקל ביותר לקודקוד שנשלף הוא ידוע (נימוק מובא בהמשך). לאחר מכן, ייבדקו שכניו של הקודקוד שנשלף[א], וייבדק האם ניתן לשפר את הערכת המרחק של השכנים: כלומר, מוסיפים למסלול הקל ביותר לקודקוד שנשלף את הקשת לשכן, ובודקים האם זה מניב מרחק שנמוך יותר מאומדן המרחק הנוכחי. אם כן, הערכת המרחק לשכן תעודכן.
באיטרציה הראשונה יישלף קודקוד המקור (הערכת מרחקו היא מינמלית - 0, ושאר ההערכות הן אינסוף). עבור הקודקודים שהם שכנים של המקור (כלומר יש צומת מהמקור אליהם), תחושב מחדש הערכת המרחק עבורם והעדיפות שלהם תעודכן.
באיטרציה השנייה, יישלף הקודקוד שמחובר למקור בקשת שמשקלה מינמלית (מבין הקשתות שיוצאות מהמקור). נסמן קודוד זה ב-u. המסלול העובר דרך קשת זו הוא המסלול הקל ביותר - כל מסלול אחר בהכרח עובר דרך קשת נוספת, שרק יכולה להכביד את המסלול (זכרו שכל המשקלים חיוביים). בנוסף, עבור כל שכן של הקודקוד, ייבדק האם התגלה מסלול קל יותר לקודקוד השכן (מקור->u->שכן). מצב זה יקרה אם השכן הוא קודקוד חדש שהחיפוש לא נתקל בו ממקודם, או אם החיפוש כן נתקל בו ממקודם אך המסלול שעובר ב-u הוא קל יותר.
וכך הלאה, בכל איטרציה, יישלף הקודקוד שהערכת מרחקו מינמלי, ובשלב זה ההערכה תהיה המסלול הקל ביותר האמיתי. לאחר מכן, יעודכנו הערכות המרחק לקודקודים ששכנים של הקודקוד שנשלף.
מובטח שכשקודקוד נשלף מהתור, האלגוריתם אכן מצא את המסלול הקל ביותר אליו: אילו היה מסלול קל יותר, הקודקוד הלפני אחרון במסלול זה היה בעל הערכת מרחק נמוכה יותר, ולכן היה נשלף מהתור ראשון. בגרף עם משקלים חיוביים, תת-מסלול לא יכול להיות קל יותר מהמסלול כולו (אינטואטיבית, הנסיעה מאילת לתל אביב דרך יטבתה לא יכולה להיות מהירה יותר מהנסיעה מאילת ליטבתה).
בסוף האלגוריתם, כל הקודקודים נשלפו מתור הקדימויות, ולכן המרחק לכולם ידוע.
כדי למצוא את המסלול עצמו ולא רק את המרחק, ניתן לשמור מיפוי מכל קודקוד לקודקוד שקודם לו במסלול הקל ביותר שהתגלה עד כה (המשתנה Prev בפסאודו קוד). כך ניתן לשחזר את המסלול הקל ביותר - מתחילים מקודקוד היעד, בודקים מי קודם לו, וכך הלאה עד שמגיעים למקור.
דוגמת הרצה
[עריכת קוד מקור | עריכה]אינטואיציה
[עריכת קוד מקור | עריכה]דייקסטרה מגלה את המסלול הקל ביותר תחילה מהקודקודים הקרובים ביותר למקור, ולאחר מכן מקודקודים רחוקים יותר ויותר. למשל, בדוגמת ההרצה הנ"ל תחילה מתגלה המסלול מקודקוד שמרחקו מהמקור הוא 7, לאחר מכן 9, וכו'.[3]
בגרף גאומטרי (משקלים=מרחק גאומטרי), בדומה לדוגמת ההרצה שמופיעה בראש הערך, ניתן לדמיין שמשרטטים עיגול מסביב למקור, ומגדילים הדרגתית את רדיוס העיגול. כשקודוקד נכנס לעיגול, דייקסטרה חישב את המסלול הקל ביותר אליו. ניתן להיעזר באנלוגיה הפיזיקלית הבאה: מתחילים להזרים מים לרשת תעלות (נניח שכל התעלות בעלות קיבולת זהה, ואין הבדלי גבהים). המים יבקרו בקודקודים באותו סדר שדייקסטרה מבקר בהם, וימצאו אותם מסלולים קצרים.[4][5] זוהי מעין גרסה "ממושקלת" של חיפוש לרוחב (ראה פירוט בהמשך הערך).
תכונות
[עריכת קוד מקור | עריכה]- האלגוריתם מוצא עץ מסלולים מזעריים (אנ'). זהו תת-גרף שהוא עץ שמושרש בקודקוד המקור, וכל מסלול מהשורש לכל קודקוד אחר הוא מסלול קל ביותר בגרף המקורי. אם הגרף קשיר, זהו עץ פורש.[6]
- סיבוכיות מקום: סיבוכיות המקום היא O(|V|), הנדרשים עבור תור הקדימויות Q והמילון DistEst.[7][8]
- אם אין מסלול מהמקור לקודקוד מסוים v, יתקיים DistEst[v]=inf ו-Prev[v]=nil.
- הערכת המרחק תמיד גדולה או שווה למרחק האמיתי.[9]
חמדנות ותכנון דינמי
[עריכת קוד מקור | עריכה]ראו גם – אלגוריתם חמדן, תכנון דינמי |
מאחר שכל מסלול קל ביותר מכיל תת-מסלולים שגם הם מסלולים קלים, לבעיה יש תת-מבנה מיטבי (Optimal substructure). כלומר, הפתרון יכול להבנות מפתרון בעיות קטנות יותר. בעיות מסוג זה מתאימות לפתרון בעזרת אלגוריתמים חמדניים ותכנון דינמי.[10][11] החמדנות של האלגוריתם באה לידי ביטוי בכך שהאלגוריתם בוחר את הקודקוד שנראה בשלב הנוכחי כקרוב ביותר.[11] ניתן לראות את הגישה החמדנית כפתרון יעיל של בעיית תכנון דינמי.[12]
נכונות
[עריכת קוד מקור | עריכה]נסמן ב-S את קבוצת הקודקודים שנשלפו מתור הקדימויות. נוכיח באינדוקציה על |S|, שלכל קודקוד ב-S, המסלול שהאלגוריתם מצא הוא אכן המסלול הקל ביותר.
נוכיח שלכל קודוקד שנשלף מהתור, המסלול שהאלגוריתם מצא הוא אכן המסלול הקל ביותר (נכון מהאיטרציה בה הוא נשלף מהתור). ההוכחה תבוצע באינדוקציה על מספר הקודקודים שנשלפו מהתור. בסוף ריצת האלגוריתם, כל הקודקודים נשלפו מהתור, ולכן האלגוריתם נכון.[ב]
כמו בפסאודו קוד הנ"ל, נסמן ב-DistEst[v] את הערכת המרחק מ-s ל-v. בנוסף, נסמן ב-TrueDist[v] את המרחק הקל ביותר מ-s ל-v.
בסיס האינדוקציה:
כשטרם נשלפו קודקודים מהתור, הטענה מתקיימת באופן ריק.
כשקודקוד אחד נשלף, אז בהכרח זהו קודקוד המקור s. בגרף בעל משקלים אי-שליליים, המסלול הקל ביותר מ-s לעצמו הוא המסלול שמכיל רק את s.
צעד האינדוקציה:
נניח שנשלפו k קודקודים, כך שלכולם האלגוריתם מצא את המסלול הקל ביותר האמיתי (הנחת האינדוקציה). נסמן ב-v את הקודקוד ה-k+1 שנשלף מהתור, ונוכיח שגם עבורו האלגוריתם מצא את המסלול הקל ביותר האמיתי.
יהי Q מסלול כלשהו מ-s ל-v. נוכיח שמשקלו איננו קטן משל .
נסמן ב-u את הקודקוד שקודם ל-v במסלול הקל ביותר שהאלגוריתם מצא עד כה (Prev[v] בפסאודו קוד הנ"ל). בנוסף נסמן ב-y את הקודקוד הראשון ב-Q שאיננו אחד מ-k הקודקודים הראשונים שנשלפו, וב-x את הקודקוד שלפני y במסלול Q.
בגלל שהקשת uv נשלפה מתור הקדימויות לפני xy, מתקיים (במילים: הערכת המשקלים של המסלול P קטנה או שווה להערכת המשקל של המסלול Q). אחרת x היה נשלף מתור הקדימויות לפני u.
לפי הנחת האינדוקציה והעובדה שהאלגוריתם כבר ביקר ב-u ו-x, ניתן להציב את TrueDist במקום DistEst: . כלומר, אפילו תת-המסלול של Q מ-s ל-y איננו עדיף על . הוספת הקשתות הנוספות במסלול Q רק יכולה להגדיל את המשקל.
ולכן המשקל של המסלול שאלגוריתם דייקסטרה מצא קטן או שווה לכל מסלול אחר מ-s ל-v.[13][14]
קשתות שליליות
[עריכת קוד מקור | עריכה]כאשר בגרף יש משקלים שליליים, לא מובטח שאלגוריתם דייקסטרה יימצא את המסלול הקצר ביותר.[13]
בהוכחת הנכונות הנ"ל, הביטוי איננו נכון, משום שייתכן ש-w(xy) שלילי.[13] במילים אחרות, דייקסטרה מניח שהמסלול הקל ביותר ל-v חייב לעבור בקודקודים שקרובים יותר למקור. אך כאשר יש צלעות שליליות, לא נכון להניח זאת.[15]
כפי שניתן לראות בדוגמה, יכול להיות מסלול בו קשת חיובית כבדה ש"מחביאה" מדייקסטרה שאחריה יש קשתות שליליות, שיכולות לקזז את הקשת הכבדה, ואף להפוך את המסלול לקל ביותר.
סיבוכיות זמן ובחירת מבנה נתונים לתור הקדימויות[ד]
[עריכת קוד מקור | עריכה]
דרוש ידע מוקדם: סיבוכיות זמן, סימון אסימפטוטי |
בביטויי הסיבוכיות בערך זה, V ו-E מתייחסים למספר הקודקודים והקשתות בגרף (בהתאמה), ולא לקבוצת הקודקודים\קשתות עצמה.
סיבוכיות זמן
[עריכת קוד מקור | עריכה]ניתוח מקרה גרוע
[עריכת קוד מקור | עריכה]כל קודקוד מוכנס ומוצא מתור הקדימיות בדיוק פעם אחת. בגרף מכוון, כל קשת תופיעה פעם אחת בלולאת ה-for (שורה 10), ולכן כמות הקריאות ל-DecreaseKey היא לכל היותר . לכן סיבוכיות הזמן במקרה הגרוע היא:[16][17]
נבחן כיצד הסיבוכיות תושפע מבחירת מבנה הנתונים לתור הקדימויות.
הבחירה הנאיבית ביותר הוא רשימה (זהו גם המימוש שהיה ידוע בשנות החמישים, כשאלגוריתם דייקסטרה הומצא[18][19]). עלות EXTRACT_MIN היא , ו-DECREASE_KEY ב- (בהנחה שהקודקודים ממוספרים, או שניתן להגיע אליהם בזמן קבוע באמצעות מצביע). סך הכל זמן הריצה של האלגוריתם הוא .[17] אם הגרף צפוף מאוד (), אז זוהי הסיבוכיות הטובה ביותר האפשרית, משום שאי אפשר להתחמק מלסרוק את כל הקשתות בגרף.[20] אך עבור המקרה הכללי, הומצאו מגוון תורי קדימויות יעילים יותר.[19]
בחירה פופולרית[21] הוא ערימה בינארית, שהוצע על ידי וויליאמס ב-1964.[19] בערימה בינארית האתחול לוקח זמן ליניארי, ופעולות ה-EXTRACT_MIN ו-DECREASE_KEY ניתנות לביצוע בזמן לוגריתמי. לכן הסיבוכיות הכוללת של האלגוריתם היא [ה]. סיבוכיות זו עדיפה על רשימה כל עוד .[17] אופציה נוספת היא ערימה d-ארית, מעין הכללה של ערימה בינארית עם סיבוכיות דומה.[22] על אף שזוהי לא הסיבוכיות מקרה גרוע הטובה ביותר, בפרקטיקה זו בחירה יעילה ופופולרית.[21]
תורי הקדימויות המניבים את הסיבוכיות הטובה ביותר מסתמכים על ההבנחה הבאה: במקרה הגרוע, כמות הקריאות ל-DECRESE_KEY גדולה בסדר גודל מכמות הקריאות ל-EXTRACT_MIN (שכן כמות הקשתות בגרף יכולה להגיע לריבוע כמות הקודקודים). כלומר, יש יתרון לתור קדימויות שמאפשר לבצע את DECREASE_KEY בזמן קבוע, ומשאיר את EXTRACT_MIN בזמן לוגריתמי. בעזרת תור קדימויות כזה, אלגוריתם דייקסטרה רץ בזמן.[17]
ישנן מספר ערימות המתאימות לסיבוכיות זו: ערימת פיבונאצ'י (1984), אך נדרש להשתמש בניתוח לשיעורין;[17][23] Relaxed heap (1988), וריאציה של ערימת פיבונאצ'י שמתאימה לעיבוד מקבילי;[24] תור ברודאל (אנ') (1996), שאיננו משתמש בניתוח לשיעורין, אך הוא מורכב שלא לצורך, ומניח הנחות לא ריאליסטיות;[19][25] וערימת פיבונאצי חזקה (אנ') (2012), שנועדה להיות אלטרנטביה פשוטה יותר לתורי ברודאל, ללא ניתוח לשיעורין או הנחות בעייתיות.[19][26] נחקרו מגוון תורי קדימויות נוספים, שהם מחוץ להיקף הערך.
במודל החישובי הסטנדרטי[ו], לא ניתן לשפר את הסיבוכיות של אלגוריתם דייקסטרה מעבר ל-O(VlogV+E). אחרת, יופר החסם תחתון למיון , שכן דייקסטרה סורק את הקודקודים לפי סדר מרחק עולה.[27][28][ז] לכן דייקסטרה לא נופל מכל אלגוריתם מסלולים קלים אחר שמסתמך על מיון קודקודים.[29]
מבנה נתונים | אתחול | EXTRACT_MIN | DECREASE_KEY | אלגוריתם דייקסטרה | הערות |
---|---|---|---|---|---|
רשימה[17][30] | -[ח] | ||||
ערימה בינארית[17] | [ה] | ||||
ערימת פיבונאצי[17][30], relaxed heap[24] | ניתוח לשיעורין | ||||
ערימת פיבונאצי חזקה (אנ'),[19][30] תור ברודאל (אנ')[31][30] |
ביצועים פרקטיים וניתוח מקרה ממוצע
[עריכת קוד מקור | עריכה]ערימת פיבונאצי (רגילה או חזקה) ותור ברודאל אינם נפוצים בפרקטיקה, משום שהם מורכבים למימוש וברוב המקרים אינם מניבים ביצועים טובים יותר (על אף הסיבוכיות מקרה גרוע הטובה יותר).[16][32] הסיבות לפער בין הביצועים האמפיריים לסיבוכיות מקרה גרוע ביותר נובעת מגורמים קבועים משמעותיים ש"מוחבאים" בסימון האסימפטוטי, ומפער בין המקרה הגרוע ביותר למקרים נפוצים יותר.[16][25][32]
נבחן למשל את תור הקדימויות שנבחר בספריות קוד פופולריות:[ט] ערימה בינארית נבחרה בספריות בשפת פייתון (NetworkX),[33] C#,[34] ראסט,[35] ו-Go[36]; בעוד ש-Boost, ספריית C++ יעילה ופופולרית, משתמשת בערימה d-ארית (d=4).[37][38][י] העדפה זו נתמכת גם על ידי מחקרים אקדמיים שביצעו מבחנים אמפיריים.[22][25][32][39][40]
ניתוח מקרה ממוצע עוזר לתת הסבר תאורטי לפער בין הביצועים בפרקטיקה לסיבוכיות מקרה גרוע. במקרה הגרוע נעשה מספר יוצא דופן של קריאות ל-DECREASE_KEY, ביחס למקרה הממוצע. בממוצע, מספר הקריאות הנוספות ל-DECREASE_KEY (ביחס ל-EXTRACT_MIN) איננו מספיק כדי להצדיק את הגדלת הגורמים הקבועים שנדרשים עבור EXTRACT_MIN (כפי שקורה בערימת פיבונאצ'י).[32][16]
גולדברג (אנ') וטרג'אן (1996) הראו שמספר הקריאות הצפוי ל-DECREASE_KEY חסום על ידי , במודל בו ההנחה היחידה היא שעבור כל קודקוד, משקלי הקשתות מוגרלות באופן בלתי תלוי מאותה התפלגות. זמן הריצה הצפוי של אלגוריתם דייקסטרה עם ערימה בינארית הוא לעומת עם ערימת פיבונאצי. לערימת פיבונאצ'י יש יתרון (אסימפטוטי) רק כאשר, ואפילו אז היחס בין זמני הריצה הוא רק , שבפרקטיקה זניח לעומת הגורמים הקבועים בערימת פיבונאצ'י.[32]
יש וריאציה של אלגוריתם דייקסטרה בעלת זמן ריצה ממוצע ליניארי (כאשר ידוע חסם למשקל המקסימלי, והמשקלים מתפלגים אחיד).[י"א][41][42]
משקלים שלמים
[עריכת קוד מקור | עריכה]אם המשקלים הם מספרים שלמים, יש תורי קדימויות מיוחדים שיכולים לשפר את הסיבוכיות.[י"ב]
תור דלי (אנ') מאפשר לדייקסטרה לרוץ בזמן O(E+V*C), שכן הוא מאפשר לבצע DECREASE_KEY ב-O(1) ו-EXTRACT_MIN ב-.[י"ג] תור דלי מנצל את כך שניתן לחלק את המפתחות בתור הקדימויות בין C+1 דליים (כאשר C הוא המשקל המקסימלי בגרף), שכל אחד מכיל רשימה מקושרת של קודקודים בעלי מפתח זהה. ייתכן שהמפתח המזוהה עם דלי ישתנה, אך תמיד יהיה צורך רק ב-C+1 דליים.[41][43]
המפתחות בתור תמיד יהיו בטווח בין המינימום הנוכחי ל-, או שהמפתח אינסופי (האלגוריתם טרם סרק את הקודקוד). נוכיח טענה זו כשמורת לולאה (אנ'): באתחול טענה זו נכונה באופן טריויאלי. בכל איטרציה, בתחילתה מבוצע EXTRACT_MIN שאיננו מקטין את המינימום, ולכן לא מפר את השמורה; ו-DECREASE_KEY גם איננו מפר את השמורה, שכן המפתח החדש הוא: .[41][43]
תור דלי הוא דוגמה בסיסית לתורי קדימויות מונוטוניים (אנ'), שהם תורי קדימויות המותאמים למקרים בהם ערך המינימום לא קוטן. הנחה זו מתאימה לדייקסטרה, שסורק קודקודים בסדר עולה של מרחקם מהמקור.[41][43]
תור קדימויות מונוטוני נוסף הוא ערימת בסיס (אנ'), שמשפר את תור דלי בכך שדליים מכילים מספר מפתחות, אך דליים של מפתחות שקרובים יותר למינימום יהיו "צרים" יותר (יכילו פחות מפתחות). זמן הריצה של דייקסטרה עם ערימת בסיס הוא , ואם משתמשים בערימת בסיס עם שתי רמות מתקבל זמן ריצה של .[41][43][י"ד]
עבור גרפים מכוונים, סיבוכיות המקרה הגרוע הטובה ביותר הושגה על ידי Thorup (אנ') ב-2004: (O(E+Vloglog(min{V,C}).[44][ט"ו][ט"ז] יש וריאציה של דייקסטרה בעלת זמן ריצה ממוצע ליניארי O(E).[41] עבור גרפים לא מכוונים, ישנה אפילו וריאציה שרצה ב-O(E) במקרה הגרוע.[45]
מבנה נתונים | EXTRACT_MIN | DECREASE_KEY | אלגוריתם דייקסטרה |
---|---|---|---|
תור דלי (שכבה אחת)[43] | O(C) | O(1) | O(E+VC) |
תור דלי (2 שכבות)[43] | O(sqrt(C)) | O(1) | |
תור דלי עם k שכבות[43] | O(k) | ||
ערימת בסיס (שכבה אחת)[43] | O(logC) | O(1) | |
ערימת בסיס (2 שכבות)[43] | O(1) | ||
הערימה של Thorup (2004)[43] | O(1) | O(loglogV) | O(EloglogV) |
יישומים
[עריכת קוד מקור | עריכה]השוואה לאלגוריתמים אחרים
[עריכת קוד מקור | עריכה]דייקסטרה כהכללה של אלגוריתם חיפוש לרוחב עבור גרפים ממושקלים
[עריכת קוד מקור | עריכה]ראו גם – אלגוריתם חיפוש לרוחב |
ניתן לראות את אלגוריתם דייקסטרה כהכללה של אלגוריתם חיפוש לרוחב עבור גרפים ממושקלים.[4][46] בפרט, אלגוריתם דייקסטרה שקול לאלגוריתם חיפוש לרוחב בגרף שבו כל המשקלים שווים ל-1.[46][47]
סיבוכיות אלגוריתם חיפוש לרוחב היא O(V+E),[48] בהשוואה ל-O(VlogV+E) של דייקסטרה. כלומר, בעיית המסלול הקצר ביותר בגרף לא ממושקל הינה קלה יותר מאשר בגרף ממושקל.
אלגוריתם חיפוש לרוחב יכול למצוא מסלול קצר ביותר בגרף ממושקל באופן הבא: ניצור גרף חדש, G', שבו עבור כל קשת e=uv ניצור w(e) קשתות חדשות בעלות משקל=1 המחברות את u ו-v דרך w(e)-1 "קודקודי דמה" חדשים. אך שיטה זו מגדילה משמעותית את גודל הגרף שעליו צריך לבצע חיפוש. ניתן לראות את דייקסטרה כאופטימיזציה של שיטה זו, אשר אינה דורשת הגדלה מלאכותית של הגרף.[46]
גרפים בעלי משקלים שליליים
[עריכת קוד מקור | עריכה]- ערכים מורחבים – אלגוריתם בלמן-פורד, האלגוריתם של ג'ונסון
האלגוריתם הקלאסי לבעיה זו הוא אלגוריתם בלמן-פורד. נהוג ללמוד אלגוריתם זה לצד דייקסטרה בקורסי מבוא לאלגוריתמים רבים. בלמן-פורד דומה במובנים מסוימים לדייקסטרה: גם הוא מיישם את התבנית האלגוריתמית של פורד לאלגוריתמים למציאת המסלול הקצר ביותר (ראה בפרק ההיסטוריה),[18] וגם הוא אלגוריתם חמדן המשתמש בתכנון דינמי.[13]
סיבוכיות הזמן של אלגוריתם בלמן-פורד היא O(VE).[49] זו הייתה הסיבוכיות מקרה גרוע הטובה ביותר שהייתה ידועה עד ל-2023, אז פורסם אלגוריתם אקראי בעל סיבוכיות זמן של Õ(EV^8/9)[י"ז] בסבירות גבוהה.[50] כלומר, בעיית המסלול הקצר ביותר הינה קשה יותר כאשר יש בגרף משקלים שליליים.
האלגוריתם של ג'ונסון מוצא מסלולים קצרים ביותר בין כל זוג קודקודים בגרף, באמצעות שילוב כוחות בין בלמן-פורד ודייקסטרה.
שימוש ביוריסטיקות - A*
[עריכת קוד מקור | עריכה]- ערך מורחב – אלגוריתם חיפוש A*
ניתן לראות את אלגוריתם A* כוראיציה של דייקסטרה שמשתמשת בפונקציית יוריסטיקה כדי למצוא יותר מהר את המסלול הקצר ביותר. באלגוריתם A* נשלף הקודוקד v שממזער את DistEst[v]+h(v), כאשר h היא פונקציית יוריסטיקה האומדת את המרחק מ-v לקודקוד היעד. השוו זאת לדייקסטרה, אשר שולף את הקודקוד שממזער את DistEst[v] בלבד.[51] דייקסטרה שקול ל-A* אם בוחרים את פונקציית היוריסטיקה h(x)=0.
לעומת דייקסטרה, A* נועד למצוא את המסלול הקצר ביותר בין זוג קודקודים ספציפי, בעוד שדייקסטרה מסוגל לפתור גם את בעיית כל המסלולים הקצרים ממקור יחיד.[51]
במקרים רבים היוריסטיקה מאפשרת לאלגוריתם לנצל ידע חיצוני על הקודקודים. למשל, אם הגרף מייצג מיקומים, ניתן להשתמש במרחק האוקלידי בין v ליעד בתור פונקציית היוריסטיקה. כך אלגוריתם החיפוש יודע לוותר מראש על כיווני חיפוש מיותרים, ו"לכוון" ליעד. עם זאת, כדי להבטיח פלט נכון, ישנם הגבלות מסוימות על פונקציית היוריסטיקה (ראה בערך על האלגוריתם), ועבור קלטים מסוימים פונקציית המרחק האוקלידי לא מקיימת תנאים אלו.[51]
מקרים פרטיים
[עריכת קוד מקור | עריכה]עבור גרף לא מכוון, יש אלגוריתם אקראי שרץ ב- בהסתברות גבוהה (אנ') (כלומר, כשהקלט שואף לאינסוף, ההסתברות שואפת ל-1). האלגוריתם הוא וריאציה על אלגוריתם דייקסטרה, שבה רק תת-קבוצה מצומצמת של הקודקודים נמצאת בתור הקדימויות.[52]
בנוסף, ישנם מקרים פרטיים של גרפים מכוונים בהם ניתן למצוא אלגוריתם בעל סיבוכיות עדיפה מדייקסטרה. ישנם גם שיפורים עבור גרפים מישוריים, גרפים חסרי מעגלים, וקלט גאומטרי.[53][54]
המצאת האלגוריתם
[עריכת קוד מקור | עריכה]המחקר המתמטי המודרני על מציאת המסלול הקל ביותר בגרף בעל משקלים חיוביים החל בשנות החמישים של המאה ה-20. ב-1956 חוקר ממכון ראנד פרסם תבנית לאלגוריתמים למציאת המסלול הקל ביותר, שאלגוריתם דייקסטרה מיישם. אלגוריתם דייקסטרה פורסם באופן בלתי תלוי ב-1957 על ידי חוקרים ממכון CASE, ב-1959 בידי אדסחר דייקסטרה (שהגה את האלגוריתם כבר ב-1956) וב-1960 על ידי אנשי חקר ביצועים. בנוסף, בתעשייה נעשה שימוש באלגוריתם זהה או דומה, לפחות בפרויקט אחד.[55]
פורד (1956): תבנית לאלגוריתמים למציאת המסלול הקל ביותר
[עריכת קוד מקור | עריכה]ראו גם – אלגוריתם בלמן-פורד (על שמו של פורד) |
ב-1956 ל"ר פורד ג'וניור (אנ') ממכון ראנד תיאר תבנית לאלגוריתמים למציאת המסלול הקל ביותר. לתבנית זו תואמים אלגוריתם דייקסטרה, כמו גם אלגוריתם בלמן-פורד המסוגל לעבוד עם משקלים שליליים (וקרוי על שם פורד בזכות תבנית זו). אך התבנית הינה כללית, ויכולה להתאים באותה מידה גם לאלגוריתמים בעלי סיבוכיות אקספוננציאלית. התבנית של פורד:
נסמן ב- פונקציה המחזירה את הערכת המרחק מצומת המקור לכל צומת אחרת (בדומה ל-DistEst בפסודו-קוד בתחילת הערך).
אתחול: קבע ו- לכל .
לולאה: באופן איטרטיבי, בחר קשת המקיימת , וקבע .
פורד לא ציין אף כלל לבחירת הקשת . אלגוריתם דייקסטרה בוחר את הקשת שממזערת את .[18][56]
אדסחר דייסקטרה (1956\1959)
[עריכת קוד מקור | עריכה]ראו גם – אדסחר דייקסטרה |
דייסקטרה תכנן את האלגוריתם ב-1956, במטרה להציג את יכולות המחשב ARMAC (הו') בטקס החניכה החגיגי שלו. דייסקטרה רצה לבחור בעיה אלגוריתמית שגם קהל לא מתמטי יוכל להבין. הבעיה שבחר בה הייתה מציאת המסלול הקצר ביותר בין ערים הולנדיות.[י"ח] דייסקטרה מספר שהוא תכנן את האלגוריתם בכ-20 דקות, בזמן הפסקת קפה שלקח כשעשה קניות עם ארוסתו. דייסקטרה האמין שדווקא משום שלא היה יכול להשתמש בעפרון ונייר, הוא אולץ לחשוב על אלגוריתם פשוט ואלגנטי.[57]
דייסקטרה פרסם את האלגוריתם רק כ-3 שנים לאחר המצאתו, ב-1959. תיאור האלגוריתם התפרס על פני עמוד אחד בלבד, מתוך מאמר בן 2.5 עמודים שכלל גם תיאור של אלגוריתם גרפי נוסף.[58] המאמר לא עסק בבחירת מימוש לתור הקדימויות (למעשה דייקסטרא כלל לא השתמש במונח זה),[58] ולכן בטקסטים מודרניים לעיתים מתייחסים לסיבוכיות הזמן של האלגוריתם המקורי כ-.[16][18]
דייסקטרה אמר שב-1956 "אלגוריתם למציאת המסלול הקל ביותר בקושי נחשב למתמטיקה: יש מספר סופי של מסלולים מ-A ל-B וברור שאחד מהם הוא הקצר ביותר, אז על מה כל המהומה?". דייקסטרא החליט לפרסם מאמר על האלגוריתם 3 שנים לאחר המצאתו, כאשר עורך של כתב עת חדש, שעסק גם בנושאים שכיום ייחשבו כחלק ממדעי המחשב,[59] פנה לדייסקטרה ושאל אם יש לו מה לתרום לכתב העת.[57]
בתחילת שנות השישים דייסקטרה נתקל לראשונה בטקסט שקורא לאלגוריתם על שמו, בספר לימוד גרמני.[57]
מאמרים שפורסמו במקביל
[עריכת קוד מקור | עריכה]במקביל לדייקסטרה, חוקרים אחרים פיתחו את האלגוריתם ופרסמו אותו.
ב-1957 התפרסם תיאור של האלגוריתם במאמר של חוקרים ממכון CASE (אנ') באוהיו.[18] התיאור פורסם בדו"ח שנתי של פרויקט מחקר שבוצע עבור ה-Combat Development Department ב-Electronic Proving Ground של צבא ארצות הברית.[18] המאמר לא התבלט בזמן פרסומו,[60] אך בהסתכלות היסטורית הוא זכור כתגלית עצמאית של אלגוריתם דייקסטרה.[18]
ב-1960 Whiting & Hillier פרסמו מאמר נוסף שתיאר את האלגוריתם.[61][62][63] המאמר פורסם בכתב עת העוסק בחקר ביצועים, והמוטיבציה נבעה מבעיות תחבורה ותקשורת.[61]
Dantzig פרסם אלגוריתם דומה ב-1960, אך הוא היה פחות יעיל.[18]
LEO 1 ו-British Railways (1955-1956)
[עריכת קוד מקור | עריכה]LEO 1 היה מחשב בריטי שהחל לפעול ב-1951. המחשב היה שייך לתאגיד המזון J. Lyons and Co., שגם השכיר את שירותי המחשוב לגורמים אחרים. ב-1955 British Railways (אנ') שכרו את שירותי המחשוב לטובת חישוב המרחק בין תחנות הרכבת שלהם. בניסוח גרפי, זוהי הבעיה של מציאת המסלול הקצר ביותר בין כל זוג קודקודים. על הבעיה עבד רוג'ר קולמן, תחת ניהולו של דייוויד קמינר.
כחלק מפתרון הבעיה, פותח אלגוריתם שאפשר להחשיב כגרסה מוקדמת של אלגוריתם דייסקטרה. עם זאת, האלגוריתם של קולמן כלל הרבה התאמות לבעיה הספציפית של British Railways. בנוסף, האלגוריתם מעולם לא פורסם, והידע שלנו עליו מתבסס על ראיונות שחובבי היסטוריית מחשוב ערכו עם קולמן בשנות האלפיים. קולמן לא המשיך לעסוק במדעי המחשב, ועד לאותם ראיונות הוא לא ידע על קיומו של האלגוריתם של דייסקטרה ועל החשיבות ההיסטורית של המצאתו שלו.[64][65]
ראו גם
[עריכת קוד מקור | עריכה]קישורים חיצוניים
[עריכת קוד מקור | עריכה]- אלגוריתם דייקסטרה, באתר MathWorld (באנגלית)
- אלגוריתם דייקסטרה, מחברת קורס מבני נתונים ואלגוריתמים בויקיספר
- מימושים של האלגוריתם בעשרות שפות, באתר Rosetta Code (אנ')
- יישום המאפשר לראות הרצה של האלגוריתם בצורה אינטרקטיבית וויזואלית, באתר אוניברסיטת סן פרנסיסקו
- "גילוי מחדש" של דייקסטרה באמצעות פיתח מונחה-בדיקות, בבלוג של רוברט מרטין (אנ') ("הדוד בוב")
- וידאו
- Dijkstra's algorithm in 3 minutes, סרטון בערוץ "Michael Sambol", באתר יוטיוב (אורך: 2:45)
- האלגוריתם של דייקסטרה, סרטון בערוץ "ד"ר שרי שינולד", באתר יוטיוב (אורך: 9:49)
- How Dijkstra's Algorithm Works, סרטון בערוץ "Spanning Tree", באתר יוטיוב (אורך: 8:31)
- Introduction to Algorithms, Lecture 16: Dijkstra, סרטון בערוץ "MIT", באתר יוטיוב (אורך: 51:25)
ביאורים
[עריכת קוד מקור | עריכה]- ^ בהקשר הנכוחי, בגרף מכוון "שכן" משמעותו שיש קשת שיוצאת מהקודקוד הראשון ונכנסת לקודקוד השכן.
- ^ ההוכחה היא עבור בעיית המסלולים הקלים ממקור יחיד לכל הקודקודים בגרף. ההוכחה דומה עבור הגרסה שבה האלגוריתם מסתיים לאחר שליפת קודקוד יעד מסוים (בעיית המסלול הקל ממקור יחיד ליעד יחיד).
- ^ האיור מספק אינטואיציה, אך ישנם מקרים שבהם הוא איננו מדויק: ייתכן ש-x=u, y=v או שיש חפיפה בין הקודקודים s,u,x. בנוסף ייתכן שבמסלול מ-y ל-v יש קודקודים נוספים מבין הקודקודים שבוקרו.
- ^ רוב הספרות מתמקדת בהרצה של דייקסטרה על גרף מכוון. אם הגרף לא מכוון, ניתן ליצור גרף חדש שבו כל קשת u-v משוכפלת פעמיים, עבור שני הכיוונים (u->v, v->u). זהו הבדל של קבוע בגודל הקלט, ולכן רוב תוצאות הסיבוכיות עבור גרפים מכוונים תקפים גם לגרפים לא מכוונים. אך תוצאות לגבי אופטימליות, ביצועים פרקטיים וזמן ממוצע לא בהכרח מדויקות.
- ^ 1 2 אם הגרף לא קשיר, אז הסיבוכיות היא O((V+E)logV). אם הגרף קשיר (כפי שנהוג להניח בטקסטים רבים), אז E=\Omega(V) ולכן ניתן להתייחס לסיבוכיות כ-O(ElogV).
- ^ ה-Comparison-addition model, שבו מותר לבצע השוואות וסכימות של המשקלים. ראה התייחסות ל-RAM model בתת-הפרק על משקלים שלמים.
- ^ לא ניתן להתחמק מהופעת E בסיבוכיות משום שהאלגוריתם חייב לסרוק את כל הקשתות בגרף (במקרה הגרוע).
- ^ ניתן להניח שבקלט יש רשימת קודקודים.
- ^ ציינתי ספריות רלוונטיות מתוך רשימה של github repository בעלות מעל ל-2,500 כוכבים, ושמתויגות ב-graph-algorithms (ראה רשימה כאן).
- ^ האנומליה היא ספריית הג'אווה JGraphT, שמתממשת ב-Pairing heap (אנ') (ראה קוד מקור). ספריית ג'אווה פופולארית נוספת, AlgoDS, מאפשרת לבחור בין מימוש מבוסס רשימה, ערימה בינארית או ערימת פיבונאצי (ראה קוד מקור).
- ^ אם אין תלות בין המשקלים, זמן הריצה מתקיים בסבירות גבוהה.
- ^ אלא אם מצוין אחרת, האלגוריתמים בפרק זה מניחים מודל חישובי שנקרא מכונת RAM (אנ'). בניסןל ךא פורמלי, במודל זה הקלט "נכנס" במילים בזיכרון RAM (בניגוד למספרים ממשיים, שבהם עסקנו עד כה). בנוסף ניתן לבצע על המשקלים פעולות אריתמטיות ופעולות בסיסיות על סיביות, בדומה למעבד סטנדרטי. ראה למשל כאן.
- ^ מימוש של דייקסטרה באמצעות תור דלי נקרא גם אלגוריתם דייאל (Dial's algorithm), כהוקרה למאמר של רוברט ב. דייאל מ-1969. מבנה הנתונים הוצע באופן בלתי תלוי גם על ידי רוברט ואגנר ב-1976 ויפים דיניץ (אנ') ב-1978.
- ^ ערימות בסיס הוצעו ב-1990 על ידי Ahuja, Mehlhorn, Orlin & Tarjan, על בסיס מחקר של דונלד ג'ונסון מ-1977.
- ^ האלגוריתם מניח שניתן לבצע כפל מספרים בזמן קבוע. אחרת, הסיבוכיות מתדרדת ל-O(E+V(loglogmin{V,C})^(1+epsilon)).
- ^ ישנו גם אלגוריתם בזמן לינארי O(E), אך הוא מניח מודל חישובי ייחודי שלא רלוונטי לאף ארכיטקטורת מחשבים מוכרת. ראה כאן בעמוד 1 ו-כאן.
- ^ משמעות הסימון Õ (אנ') היא O כאשר מתייחסים לגורמים לוגריתמיים כזניחים. כלומר הוא כתיב מקוצר של (קורמן ושות', עמ' 73-74)
- ^ הגרף הכיל 64 קודקודים, שכל אחד מהם מייצג עיר בהולנד.
הערות שוליים
[עריכת קוד מקור | עריכה]- ^ מבוסס על Cormen et al. (2022), עמ' 620. פונקציות העזר שוטחו, השמות עובדו לשמות אינדיקטיביים יותר, והקבוצה S נמחקה משום שלא השפיעה על הפונקציונליות.
- ^ Dijkstra's Shortest Path Algorithm, brilliant.org (באנגלית אמריקאית)
- ^ Mehlhorn & Sanders (2008), עמ' 198
- ^ 1 2 Cormen et al. (2022), עמ' 620
- ^ הרצת האלגוריתם, תוכן מקורס בקמפוס IL, סרטון בערוץ "האוניברסיטה הפתוחה", באתר יוטיוב (אורך: 14:12), 18 אוקטובר 2021
- ^ Cormen et al. (2022), עמ' 608
- ^ Whyt is the space complexity of Dijkstra with heap O(V) instead of (V + E)?, Stack Overflow (באנגלית)
- ^ Dijkstra’s algorithm, TopperWorld (באנגלית)
- ^ Cormen et al. (2022), עמ' 611
- ^ Cormen et al. (2022), עמ' 605-606
- ^ 1 2 Greedy Algorithms, brilliant.org (באנגלית אמריקאית)
- ^ M. Sniedovich, Dijkstra's algorithm revisited: the dynamic programming connexion, Control and cybernetics 35(3), 2006, עמ' 599-620 (באנגלית)
- ^ 1 2 3 4 האוניברסיטה הפתוחה, אלגוריתמים, באתר קמפוס IL, קורס אקדמי אינטרנטי
- ^ 1 2 Jon Kleinberg And Eva Tardos, Chapter 4: Greedy Algorithms, Algorithm Design, Pearson/Addison-Wesley, 2006, ISBN 813170310X, 9788131703106. (באנגלית). ישנה מהדורה מתורגמת: פיתוח אלגוריתמים, בתרגום תמר אלמוג, 2010, הוצאת האוניברסיטה הפתוחה.
- ^ 1 2 Sanjoy Dasgupta, Christos H. Papadimitriou, Umesh Virkumar Vazirani, Algorithms, McGraw-Hill Higher Education, 2006, עמ' 122, ISBN 978-0-07-738849-2. (באנגלית)
- ^ 1 2 3 4 5 Kurt Mehlhorn, Peter Sanders, Chapter 10: Shortest Paths, Algorithms and Data Structures: The Basic Toolbox, Springer Science & Business Media, 2008, עמ' 198-199, ISBN 978-3-540-77977-3. (באנגלית)
- ^ 1 2 3 4 5 6 7 8 Cormen et al. (2022), עמ' 623-624
- ^ 1 2 3 4 5 6 7 8 Alexander Schrijver, On the history of the shortest path problem, Documenta Mathematica Series: Optimization Stories, 2012, עמ' 155-167 doi: 10.4171/DMS/6/19 (באנגלית)
- ^ 1 2 3 4 5 6 Gerth Stølting Brodal, George Lagogiannis, Robert E. Tarjan, Strict fibonacci heaps, Proceedings of the forty-fourth annual ACM symposium on Theory of computing, STOC '12, Association for Computing Machinery, 2012-05-19, עמ' 1177–1184 doi: 10.1145/2213977.2214082. המבוא של מאמר זה מכיל סקירה היסטורית.
- ^ Ravindra K. Ahuja, Thomas L. Magnanti, James B. Orlin, Network flows: theory, algorithms, and applications, USA: Prentice-Hall, Inc., 1993-02, עמ' 122, ISBN 978-0-13-617549-0. (באנגלית)
- ^ 1 2 עבור סימוכין לפופולריות, ראה בתת-פרק על ניתוח אמפירי וניתוח מקרה ממוצע.
- ^ 1 2 Daniel H. Larkin, Siddhartha Sen, Robert E. Tarjan, A Back-to-Basics Empirical Study of Priority Queues, Society for Industrial and Applied Mathematics, 2013-12-18, Proceedings, עמ' 61–72
- ^ M.L. Fredman, R.E. Tarjan, Fibonacci Heaps And Their Uses In Improved Network Optimization Algorithms, 25th Annual Symposium onFoundations of Computer Science, 1984., 1984-10, עמ' 338–346 doi: 10.1109/SFCS.1984.715934
- ^ 1 2 James R. Driscoll, Harold N. Gabow, Ruth Shrairman, Robert E. Tarjan, Relaxed heaps: an alternative to Fibonacci heaps with applications to parallel computation, Commun. ACM 31, 1988-11-01, עמ' 1343–1354 doi: 10.1145/50087.50096
- ^ 1 2 3 Michal Mrena, Peter Sedlacek, Miroslav Kvassay, Practical Applicability of Advanced Implementations of Priority Queues in Finding Shortest Paths, 2019 International Conference on Information and Digital Technologies (IDT), 2019-06, עמ' 335–344 doi: 10.1109/DT.2019.8813457
- ^ Gerth Stølting Brodal, Strict Fibonacci Heaps (עמ' 3), מצגת מסימפוזיון, 22 במאי 2012 (באנגלית)
- ^ Tarajan et al 2024 pg 2
- ^ Ulrich Meyer, Average-case complexity of single-source shortest-paths algorithms: lower and upper bounds, Journal of Algorithms, Twelfth Annual ACM-SIAM Symposium on Discrete Algorithms 48, 2003-08-01, עמ' 91–134 doi: 10.1016/S0196-6774(03)00046-4
- ^ Tarjan et al. 2024
- ^ 1 2 3 4 Michal Mrena, Peter Sedlacek, Miroslav Kvassay, Practical Applicability of Advanced Implementations of Priority Queues in Finding Shortest Paths, IEEE, 2019-06, עמ' 335–344 doi: 10.1109/DT.2019.8813457
- ^ Gerth Stølting Brodal, Worst-case efficient priority queues, Proceedings of the seventh annual ACM-SIAM symposium on Discrete algorithms, SODA '96, Society for Industrial and Applied Mathematics, 1996-01-28, עמ' 52–58 doi: 10.5555/313852.313883
- ^ 1 2 3 4 5 A.V. Goldberg, R.E. Tarjan, Expected performance of Dijkstra's shortest path algorithm, 1996
- ^ NetworkX source code (v3.4.2) - networkx.algorithms.shortest_paths.weighted
- ^ C-Sharp-Algorithms source code - DijkstraShortestPaths.cs, GitHub
- ^ petgraph source code - dijkstra.rs, GitHub
- ^ graph/paths.go, GitHub
- ^ Nimrod Aviram, Y. Shavitt, Optimizing Dijkstra for real-world performance, ArXiv, 2015-05-19
- ^ boost source code (v1.87.0) - dijkstra_shortest_paths.hpp
- ^ Rhyd Lewis, A Comparison of Dijkstra's Algorithm Using Fibonacci Heaps, Binary Heaps, and Self-Balancing Binary Trees, Arxiv, 2023 doi: 10.48550/ARXIV.2303.10034
- ^ Stefan Edelkamp, Amr Elmasry, Jyrki Katajainen, The weak-heap family of priority queues in theory and praxis, Proceedings of the Eighteenth Computing: The Australasian Theory Symposium - Volume 128, CATS '12, Australian Computer Society, Inc., 2012-01-31, עמ' 103–112 doi: 10.5555/2523693.2523707
- ^ 1 2 3 4 5 6 Melhorn & Sanders (2008), Chapter 10.5: Monotone Integer Priority Queues
- ^ Andrew V. Goldberg, A Practical Shortest Path Algorithm with Linear Expected Time, SIAM Journal on Computing 37, 2008-01, עמ' 1637–1655 doi: 10.1137/070698774
- ^ 1 2 3 4 5 6 7 8 9 10 J. Costa, L. Castro, R. de Freitas, Exploring Monotone Priority Queues for Dijkstra Optimization, arXiv, 2024 doi: arXiv:2409.06061
- ^ Mikkel Thorup, Integer priority queues with decrease key in constant time and the single source shortest paths problem, Journal of Computer and System Sciences, Special Issue on STOC 2003 69, 2004-11-01, עמ' 330–353 doi: 10.1016/j.jcss.2004.04.003
- ^ Mikkel Thorup, Undirected single-source shortest paths with positive integer weights in linear time, Journal of the ACM 46, 1999-05, עמ' 362–394 doi: 10.1145/316542.316548
- ^ 1 2 3 Dasgupta et al. (2012), פרק 4.4
- ^ Shaull Almagor, Is Dijkstra's algorithm just BFS with a priority queue?, Computer Science Stack Exchange, 24 Feb. 2013 (באנגלית)
- ^ Cormen et al. (2022), עמ' 558
- ^ Cormen, Leiserson, Rivest & Stein, Chapter 22.1, Introduction to Algorithms, 4th edition, The MIT Press, 2022, ISBN 9780262046305. (באנגלית)
- ^ Jeremy T. Fineman, Single-Source Shortest Paths with Negative Real Weights in Õ(𝑚𝑛8/9) Time, Proceedings of the 56th Annual ACM Symposium on Theory of Computing, STOC 2024, Association for Computing Machinery, 2024-06-11, עמ' 3–14 doi: 10.1145/3618260.3649614
- ^ 1 2 3 Dijkstra's single-source shortest path algorithm, אוניברסיטת קורנל, 2019 (באנגלית)
- ^ Ran Duan, Jiayi Mao, Xinkai Shu, Longhui Yin, A Randomized Algorithm for Single-Source Shortest Path on Undirected Real-Weighted Graphs, 2023 IEEE 64th Annual Symposium on Foundations of Computer Science (FOCS), IEEE, 2023-11-06, עמ' 484–492 doi: 10.1109/focs57990.2023.00035
- ^ Seth Pettie, Vijaya Ramachandran, A Shortest Path Algorithm for Real-Weighted Undirected Graphs, SIAM Journal on Computing 34, 2005-01, עמ' 1431 doi: 10.1137/S0097539702419650
- ^ Ravindra K. Ahuja, Thomas L. Magnanti, James B. Orlin, Network Flows: Theory, Algorithms, and Applications, Prentice Hall, 1993, עמ' 108, ISBN 978-0-13-617549-0. (באנגלית)
- ^ לטענות בפסקה זו יש סימוכין בהמשך הפרק, במקומות המתאימים.
- ^ L.R. Ford, Jr, Network Flow Theory, Paper P-923, The RAND Corporation, 1956.
- ^ 1 2 3 Philip L. Frana, Thomas J. Misa, An interview with Edsger W. Dijkstra, Communications of the ACM 53, 2010-08, עמ' 41–47 doi: 10.1145/1787234.1787249
- ^ 1 2 E. W. Dijkstra, A note on two problems in connexion with graphs, Numerische Mathematik 1, 1959-12-01, עמ' 269–271 doi: 10.1007/BF01386390
- ^ Numerische Mathematik, The European Digital Mathematics Library
- ^ למשל, בגוגל סקולר ישנם 0 ציטוטים של המאמר מלפני שנת 2000.
- ^ 1 2 P. D. Whiting, J. A. Hillier, A Method for Finding the Shortest Route Through a Road Network, OR 11, 1960, עמ' 37–40 doi: 10.2307/3007178
- ^ Paola Festa, Shortest Path Algorithms, Boston, MA: Springer US, 2006, עמ' 185–210, ISBN 978-0-387-30165-5. (באנגלית)
- ^ Stuart E. Dreyfus, An Appraisal of Some Shortest-Path Algorithms, Operations Research 17, 1969-06, עמ' 395–412 doi: 10.1287/opre.17.3.395
- ^ Tim Greening-Jackson, LEO I and the BR job, Self published, 2012 (באנגלית)
- ^ הרצאה של ג'ון גרהאם-קמינגס ב-Strata Conference London 2012, הרצאה בערוץ "O'Reilly", באתר יוטיוב (אורך: 18:24), 2 באוקטובר 2012