Depth-First Search DFS (Depth-First Search) DFS חיפוש לרוחב חיפ וש לעומק (DFS) הוא אלג וריתם לסרי קת הגרפים. פועל גם על גרפים מ כוו נים וגם על בלתי מ כוו נים בהינתן גרף,G=(V,E) אלגוריתם DFS מבקר בכל הצמתים וקשתות של G בודק האם G קשיר מחשב רכיבי קשירות של G מחשב "יער פורש" של G 1
.1.2.3 האסטרטגיה לחפש "עמוק יותר" בגרף ככל שהדבר אפשרי נבדקות קשתות של הקדקוד שהוא הקדקוד האחרון שהתגלה עד עכשיו לאחר שנבדקו כל הקשתות היוצאות מ-, החיפוש "נסוג" וממשיך בבדיקת הקשתות היוצאות מקדקוד שממנו התגלה אם נותרו קודקודים שטרם התגלו חוזרים על התהליך סיווג קדקודים DFS - - - קדקוד שטרם התגלה קדקוד שהתגלה אבל לא סיימנו טיפול בו קדקוד שהתגלה וסיימנו טיפול בו בכל קודקוד שומרים חותמות הזמן (timestamps) מועד גילוי של d[] מועד סיום הטיפול ב- f[] הם ערכים שלמים בין 1 ל- 2 V d[], f[] לכל קודקוד d[] < f[] 2
דוגמה u w דוגמה u w 3
דוגמה u w דוגמה u w 4
DFS DFS(G=(V,E)) // π[u] - predecessor of u 1 for each erte u V 2 color[u] WHITE 3 π[u] NULL 4 time 0 5 for each erte u V 6 if color[u] = WHITE 7 DFS-VISIT(u) זמן ריצה E) O(V + DFS-VISIT(u) // white erte u has just been discoered 1 color[u] GRAY 2 time time+1 3 d[u] time 4 for each Adj[u] // eplore edge (u, ) 5 if color[] = WHITE 6 π[] u 7 DFS-VISIT() 8 color[u] BLACK // blacken u; it is finished. 9 f [u] time time+1 תכונות של חיפוש לעומק G π =(V, E π נגדיר ) תת-גרף הקודמים subgraph) (predecessor של G: E π ={ (π[], ) E π[] NULL and V } כאשר DFS מופעל על גרף (E G, =,V) הוא בונה יער עומק forest) (depth-first המורכב מכמה עצי עומק 5
תכונות של חיפוש לעומק (a) מועדי הגילוי והסיום יוצרים ביטוי סוגריים בנוי היטב נסמן גילוי של קדקוד u ע"י u) נסמן סיום טיפול ב- u ע"י (u (b).2.3 תכונות של חיפוש לעומק משפט: בכל חיפוש לעומק של גרף (E G=(V, (מכוון או בלתי מכוון), עבור שני קדקודים u ו- מתקיים בדיוק אחד משלושת התנאים הבאים:.1 הקטעים ] f[u] [ d[u], ו- ] f[] [ d[], זרים לחלוטין ] f[] [ d[u], f[u] ] [ d[], ו- u הוא צאצא של בעץ העומק ] f[u] [ d[], f[] ] [ d[u], ו- הוא צאצא של u בעץ העומק מסקנה: הוא צאצא של u ביער העומק של גרף G אם ורק אם d[u] < d[] < f[] < f[u] 6
משפט המסלול הלבן משפט: הוא צאצא של u ביער העומק של גרף G אם ורק אם בזמן d[u] שבו מגלה החיפוש את u, ניתן להגיע ל- לאורך מסלול המורכב כולו מקדקודים לבנים. סיווג קשתות 1. קשת עץ edge) -(tree קשת השייכת ליער G π.2 קשת אחורה edge) (back מחברת קודקוד לאב קדמון שלו ביער העומק קשת קדימה edge) (forward רק בגרף מכוון. קשת שאינה קשת עץ, מחברת קודקוד לצאצא שלו ביער קשת חוצה edge) (cross רק בגרף מכוון. כל קשת אחרת. - קשת המחברת בין שני עצי עומק שונים או - קשת בין שני קדקודים שונים באותו עץ שאינם ביחס "אב קדמון-צאצא" G π.3 G π.4 7
סיווג קשתות.1.2.3 ניתן לשנות את DFS כך שיסווג כל קשת (,u) במהלך הריצה לפי צבעו של הקדקוד. לבן קשת עץ אפור קשת אחורה שחור אם d[] d[u] < קשת קדימה, אם d[] d[u] > קשת חוצה מיון טופולוגי Sort Topological (DAG) Direct Acclic Graph גרף מכוון חסר מעגלים מיון טופולוגי של DAG הוא סידור ליניארי של קדקודים כך שאם גרף מכיל קשת (,u), אז u מופיע לפני בסידור V U X Z V Y X W U Z W Y 8
מיון טופולוגי ל- DAG שימושים רבים לציון קדימויות בתוך קבוצת המאורעות איך מתלבש פרופסור בומסטד בבוקר: יש ללבוש פריטי לבוש מסוימים לפני האחרים (גרביים לפני נעליים) יש פריטי לבוש אותם אפשר ללבוש בסדר כלשהו (גרביים ומכנסיים) מיון טופולוגי TOPOLOGICAL-SORT(G) 1 call DFS(G) to compute finishing times f [] for each erte 2 as each erte is finished, insert it onto the front of a linked list זמן ריצה E) 3 return the linked list of ertices O(V + 9
מתי גרף הוא DAG משפט: גרף מכוון (E G=(V, אינו מכיל מעגל אם ורק אם DFS אינו מניב קשתות אחורה הוכחה: (=>) נניח (,u) קשת אחורה, אז אב קדמון של u. לכן קיים מסלול מ- ל- u בעץ העומק וקשת (,u) סוגרת מעגל. מתי גרף הוא DAG (<=) נניח G מכיל מעגל c. יהי הקדקוד הראשון המתגלה ב- הקשת הקודמת ב- c. (u,) ויהי c, בזמן d[] קיים מסלול של קדקודים לבנים מ- ל- u => u צאצא של (u,) => קשת אחורה. u 10
מיון טופולוגי - נכונות האלגוריתם משפט: אלגוריתם Topological-Sort(G) יוצר מיון טופולוגי של גרף מכוון חסר מעגלים G. הוכחה: די להראות שעבור כל קשת (,u) ב- DAG מתקיים f[u].f[]< כאשר קשת (,u) נבדקת נתבונן בצבעים של u ו-. - צבע של u אפור - צבע של לא יכול להיות אפור (כי אז (u,) קשת אחורה).f[] < f[u] ואז u צאצא של לבן, אז - f[] < f[u] ו- הסתיים שחור, אז הטיפול ב- - 11