שיעור במבני נתונים ויעילות אלגוריתמים מיום ד

‫חידה לחימום‬
‫באדמות חולדה‪-‬ל‪‬ד יש‪‬ה רשת ע‪‬פה של מחילות של חולדות‪ .‬המחילות ב‪‬ויות‬
‫מבורות המחוברים בי‪‬יהם על‪-‬ידי קטעי‪-‬מחילה‪ .‬בין כל ש‪‬י בורות יש‪‬ו לכל‬
‫היותר קטע‪-‬מחילה ישיר אחד‪ .‬תו‪‬ה מפה של רשת קטעי‪-‬מחילה‪ ,‬ובה לא‪-‬מעט‬
‫מעגלים‪ .‬א‪‬ו אומרים שיש מעגל כאשר קיימים ש‪‬י בורות המחוברים בי‪‬יהם‬
‫בש‪‬י מסלולים )רצפים( זרים של קטעי‪-‬מחילה‪.‬‬
‫הוחלט להצר את ת‪‬ועת החולדות ברשת‪ ,‬על‪-‬ידי סתימת קטעי‪-‬מחילה‪.‬‬
‫המטרה היא לסתום מספר מי‪‬ימאלי של קטעי‪-‬מחילה אשר ייצור מצב‬
‫שברשת לא יהיו מעגלים‪.‬‬
‫עליכם לכתוב תכ‪‬ית שהקלט שלה הוא מפת קטעי‪-‬המחילה )והבורות שהם‬
‫מחברים(‪ ,‬והפלט שלה הוא המספר המי‪‬ימאלי של קטעי‪-‬מחילה שיש לסתום‬
‫כדי ליצור מצב שבו אין אף מעגל ברשת‪.‬‬
‫ה‪‬תון הראשון בקלט הוא מספר הבורות ברשת )‪ ,(5 < N < 50‬אשר ממוספרים‬
‫מ‪ 1-‬עד ‪ .N‬אחרי ה‪‬תון הראשון ‪‬תו‪‬ה רשימה של קטעי‪-‬מחילה‪ ,‬אשר כל אחד‬
‫מהם מתואר על‪-‬ידי זוג הבורות אותו הוא מחבר‪ .‬הרשימה מסתיימת בזוג‬
‫)‪ .(0,0‬כל בור מופיע ברשימה לפחות פעמיים‪ .‬ייתכ‪‬ו בורות אשר אין בי‪‬יהם‬
‫מסלול של קטעי‪-‬מחילה‪.‬‬
‫לדוגמא‪ ,‬עבור הקלט הבא‪:‬‬
‫‪7122334411356675700‬‬
‫הפלט יהיה ‪.3‬‬
‫‪1‬‬
‫מב‪‬י ‪‬תו‪‬ים ויעילות אלגוריתמים‬
‫)‪(11.2.2015‬‬
‫‪ .1‬מציאת רכיבים קשירים היטב )‪(Strongly Connected Components‬‬
‫אחד היישומים של האלגוריתם לחיפוש לעומק הוא פירוק של גרף מכוון לרכיביו הקשירים היטב‪ .‬כזכור‪ ,‬עבור‬
‫גרף מכוון )‪ ,G = (V,E‬רכיב קשיר היטב )ה‪‬קרא גם רכיב קשיר בחוזקה – רק"ח; ובא‪‬גלית ‪‬קרא – ‪SCC‬‬
‫‪ (Strongly Connected Component‬זו קבוצת קודקודים ‪ U  V‬מקסימלית )גדולה ככל האפשר( כך שעבור‬
‫כל זוג קודקודים ‪ u‬ו‪ v-‬ב‪ ,U-‬קיים מסלול מכוון מ‪ u-‬ל‪ v-‬וגם מסלול מכוון מ‪ v-‬ל‪ .u-‬כלומר‪ ,‬הקודקודים ‪ u‬ו‪v-‬‬
‫‪‬ית‪‬ים להגעה הדדית‪.‬‬
‫אם ‪‬ריץ את ‪ DFS‬על גרף מכוון‪ ,‬אז ברור שש‪‬י קודקודים ששייכים לאותו רק"ח )‪ (SCC‬מצאים על אותו עץ‬
‫עומק‪ .‬מאידך‪ ,‬ייתכ‪‬ו קודקודים השייכים לאותו עץ עומק‪ ,‬אולם אמורים להשתייך לרק"חים שו‪‬ים‪ .‬לדוגמא‪:‬‬
‫באיור ה‪"‬ל ‪‬יתן לראות את מועדי הגילוי והסיום של קודקודים בגרף מכוון‪ ,‬לאחר הרצת ‪ .DFS‬הקשתות‬
‫המודגשות הן קשתות עץ )האלגוריתם ב‪‬ה ש‪‬י עצי עומק(‪ ,‬והאזורים המוצללים הם הרק"חים )יש ארבעה(‪.‬‬
‫לכן‪ ,‬הרצה אחת של ‪ DFS‬אי‪‬ה מספיקה‪ .‬איך ‪‬קבל‪ ,‬אם כך‪ ,‬את הרק"חים?‬
‫‪‬ב‪‬ה גרף הדומה ל‪ ,G-‬פרט לכך שכיוו‪‬י הקשתות המכוו‪‬ות הם הפוכים‪ .‬גרף כזה יסומן ‪ GT‬ויקרא הגרף‬
‫המשוחלף )‪ (transposed graph‬של ‪ .G‬קבוצת הקודקודים שלו זהה לזו של ‪) G‬כלומר‪ ,‬זו הקבוצה ‪ ,(V‬ואילו‬
‫קבוצת הקשתות שלו‪ ,‬שתסומן ‪ ,ET‬מכילה קשת )‪ (u,v‬אם ורק אם הקשת ההפוכה )‪ (v,u‬מצאת ב‪) E-‬בקבוצת‬
‫הקשתות של ‪ .(G‬פורמלית‪ ,‬רשום זאת כך‪ , GT = (V, ET) :‬כאשר }‪. E T  {(u, v) | (v, u)  E‬‬
‫לגרף הזה קוראים גרף משוחלף‪ ,‬משום ש‪‬יתן לקבל אותו על‪-‬ידי ביצוע פעולת שיחלוף )‪ (transpose‬על מטריצת‬
‫הסמיכויות )השכ‪‬ויות( המייצגת את הגרף‪.‬‬
‫כעת‪ ,‬ריץ את האלגוריתם ‪ DFS‬על הגרף המשוחלף ‪ ,GT‬כאשר בכל פעם שא‪‬ח‪‬ו צריכים לבחור בין כמה‬
‫קודקודים לב‪‬ים )למשל‪ :‬בלולאה בשורות ‪ 5-7‬ב‪ DFS-‬או הלולאה בשורות ‪ 4-7‬ב‪ ,(DFS-VISIT-‬במקום לבחור‬
‫שרירותית‪ ,‬בחר את הקודקוד הלבן שמועד הסיום שלו )‪ ,(finished‬ש‪‬קבע על‪-‬ידי הרצת ‪ DFS‬על הגרף ‪ ,G‬הוא‬
‫הגבוה ביותר‪.‬‬
‫עצי העומק המתקבלים כתוצאה מריצה זו של האלגוריתם‪ ,‬מתאימים לרכיבי הקשירות בחוזקה של ‪.G‬‬
‫‪2‬‬
‫אם ‪‬תון ל‪‬ו גרף מכוון )‪ ,G = (V,E‬אז לאחר שא‪‬ו יודעים מיהם הרק"חים שלו‪ ,‬יתן לב‪‬ות את גרף הרכיבים‬
‫)‪ (components graph‬של ‪ .G‬גרף זה יסומן )‪ , GSCC = (VSCC, ESCC‬כאשר ‪ VSCC‬מכילה קודקוד אחד עבור כל‬
‫רכיב קשיר היטב ב‪ ,G-‬ו‪ ESCC-‬מכילה את הקשת )‪ (u,v‬אם מקודקוד ברכיב הקשיר היטב של ‪ G‬המתאים ל‪u-‬‬
‫קיימת קשת מכוו‪‬ת לקודקוד ברכיב הקשיר היטב של ‪ .v‬לדוגמא‪:‬‬
‫שאלה‬
‫בהי‪‬תן גרף מכוון )‪ ,G = (V,E‬מהי סיבוכיות זמן הריצה של ב‪‬יית גרף הרכיבים שלו )‪? GSCC = (VSCC, ESCC‬‬
‫שאלה‬
‫הוכיחו כי גרף רכיבים ‪ GSCC‬הוא תמיד גרף מכוון ללא מעגלים )בראשי תיבות‪ :‬גמ"ל‪ .‬בא‪‬גלית מקובלות ראשי‬
‫התיבות‪.(DAG – Directed Acyclic Graph :‬‬
‫‪3‬‬
‫‪ .2‬פתרון משוואות ‪‬סיגה לי‪‬אריות אי‪-‬הומוג‪‬יות‬
‫למד‪‬ו לפתור משוואת ‪‬סיגה לי‪‬ארית הומוג‪‬ית‪:‬‬
‫) ‪f (n)  c1  f (n  1)  c 2  f (n  2)  c3  f (n  3)  ...  c k  f (n  k‬‬
‫ש‪‬ראית גם כך‪:‬‬
‫‪f (n)  c1  f (n  1)  c 2  f (n  2)  c3  f (n  3)  ...  c k  f (n  k )  0‬‬
‫כעת‪ ,‬רצה ללמוד לפתור גם משוואות מהצורה הבאה‪:‬‬
‫)‪f (n)  c1  f (n  1)  c 2  f (n  2)  c3  f (n  3)  ...  c k  f (n  k )  g (n‬‬
‫כאשר ‪ . g(n) ≠ 0‬משוואה כזו ‪‬קרא משוואת ‪‬סיגה לי‪‬ארית אי‪-‬הומוג‪‬ית‪.‬‬
‫יש מספר דרכים לפתור משוואות ‪‬סיגה כאלו‪ .‬הדרך הראשו‪‬ה היא פשוטה‪ ,‬אך אי‪‬ה מתאימה לשימוש עבור כל‬
‫משוואות ה‪‬סיגה‪ .‬בשיטה זו רושמים את ‪‬וסחת ה‪‬סיגה עבור ‪ ,n‬ואז את ‪‬וסחת ה‪‬סיגה עבור ‪ .n-1‬מחסרים בין‬
‫שתי המשוואות‪ ,‬ומבצעים פעולות אלגבריות כדי לקבל משוואת ‪‬סיגה לי‪‬ארית הומוג‪‬ית‪ ,‬שאותה א‪‬ח‪‬ו כבר‬
‫יודעים איך לפתור‪ .‬שיטת פתרון זו מכו‪‬ה לעיתים 'שיטת ההפרשים'‪.‬‬
‫שאלה‬
‫פתרו את ‪‬וסחת ה‪‬סיגה ‪ , T(n) = 2T(n-1) + 1‬עם ת‪‬אי ההתחלה ‪. T(1) = 1 , T(2) = 3‬‬
‫תשובה‬
‫‪‬עביר אגפים‪:‬‬
‫‪T(n) – 2T(n-1) = 1‬‬
‫‪‬ציב ‪:n-1‬‬
‫‪T(n-1)-2T(n-2) = 1‬‬
‫‪‬חסר מהמשוואה הראשו‪‬ה את המשוואה הש‪‬ייה‪ ,‬ו‪‬קבל‪:‬‬
‫‪T(n) – 3T(n-1) + 2T(n-2) = 0‬‬
‫קיבל‪‬ו משוואת ‪‬סיגה לי‪‬ארית הומוג‪‬ית! ‪‬פתור אותה בשיטה המוכרת‪:‬‬
‫‪‬ציב ‪  i‬במקום ) ‪ , T (i‬ו‪‬קבל‪.  n  3 n 1  2 n  2  0 :‬‬
‫‪‬צמצם ב‪ ,  n  2 -‬ו‪‬קבל את המשוואה האופיי‪‬ית‪.  2  3  2  0 :‬‬
‫‪‬פרק לגורמים‪ , (  1)(  2)  0 :‬כלומר – הפתרו‪‬ות הם‪  1  1 :‬ו‪.  1  2 -‬‬
‫לכן‪ ,‬צורת הפתרון היא‪. T (n)  A1  1n  A2  2 n :‬‬
‫כדי לחשב את ערכם של הקבועים ‪ A1 , A2‬שתמש בת‪‬אי ההתחלה‪.‬‬
‫‪‬ציב ‪ n = 1‬ו‪‬קבל‪ , 1  A1  2 A2 :‬ציב ‪ n = 2‬ו‪‬קבל‪3  A1  4 A2 :‬‬
‫קיבל‪‬ו מערכת של שתי משוואות בש‪‬י ‪‬עלמים‪ ,‬שפתרו‪‬ה‪. A1  1, A2  1 :‬‬
‫לכן‪ ,‬הביטוי המפורש המתאר את ‪‬וסחת ה‪‬סיגה הוא‪T (n)  (1)  1n  1  2 n :‬‬
‫כלומר‪ , T (n)  2 n  1 :‬כפי שרצי‪‬ו להראות‪.‬‬
‫שאלה‬
‫את סעיף ד' של שאלה ‪ 3‬בבחי‪‬ה החיצו‪‬ית מש‪‬ת תשס"ב )‪ (2002‬פתר‪‬ו בעבר בעזרת שיטת האיטרציה‪ .‬פתרו‬
‫אותו כעת באמצעות השיטה לפתרון ‪‬וסחאות ‪‬סיגה לי‪‬אריות אי‪-‬הומוג‪‬יות‪.‬‬
‫‪4‬‬