שיעור במבני נתונים ויעילות אלגוריתמים מיום ד` (7.1)

Download Report

Transcript שיעור במבני נתונים ויעילות אלגוריתמים מיום ד` (7.1)

‫מכללת אורט כפר‪-‬סבא‬
‫מבני נתונים‬
‫ויעילות אלגוריתמים‬
‫מבוא לתורת הגרפים‬
‫‪07.01.15‬‬
‫אורי וולטמן‬
‫‪[email protected]‬‬
‫חידה לחימום‬
‫‪‬‬
‫אמיר ומיכל משחקים במשחק‪ .‬על לוח המשחק מונחים ‪ 1,000‬מטבעות‬
‫בשורה‪ .‬לכל מטבע בשורה יש ערך שהוא מספר חיובי והשחקנים יודעים‬
‫בתחילת המשחק את ערכיהם של כל המטבעות‪.‬‬
‫‪‬‬
‫המשחק מתנהל בתורות‪ ,‬לסירוגין‪ .‬בכל תור‪ ,‬השחקן שמשחק בוחר מטבע‬
‫מאחד משני קצוות השורה ולוקח אותו לקופה שלו‪ .‬לאחר ‪ 1,000‬תורות‬
‫נגמרים המטבעות בשורה‪ .‬בשלב זה‪ ,‬סופרים את סכום ערכי המטבעות‬
‫שבקופה של כל אחד מהשחקנים‪ .‬השחקן שצבר סכום גדול יותר‪ ,‬מנצח‬
‫במשחק‪ .‬במקרה של שוויון בסכומים‪ ,‬המשחק מוכרז כתיקו‪.‬‬
‫אמיר משחק ראשון‪ .‬הוא ממש לא רוצה להפסיד‪ .‬לא אכפת לו אם המשחק‬
‫יסתיים בתיקו או בניצחון שלו‪ .‬מצאו אסטרטגיה עבור אמיר שתבטיח שהוא‬
‫לא יפסיד במשחק‪.‬‬
‫‪‬‬
‫הגדרות יסודיות‬
‫תורת הגרפים (‪ )Graph Theory‬היא ענף חשוב במתמטיקה‪ ,‬ולו‬
‫יישומים רבים בתחומי מדע שונים‪ .‬גם במדעי המחשב משתמשים‬
‫בגרפים‪ ,‬בתור טיפוס נתונים עליו ניתן להפעיל אלגוריתמים שימושיים‪.‬‬
‫אבל מה זה בעצם 'גרף'?‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫אנחנו נגדיר גרף (‪ )graph‬בתור אוסף של צמתים או קודקודים (באנגלית‬
‫‪ ,vertices‬וביחיד – ‪,)vertex‬‬
‫אשר ביניהם יש קשתות או צלעות (באנגלית ‪.)edges‬‬
‫נסמן את קבוצת הקודקודים באות ‪ ,V‬ואת קבוצת הצלעות באות ‪.E‬‬
‫בדרך‪-‬כלל מכנים גרפים בשמות (כגון ‪ ,)G‬וכותבים זאת כך‪.G = (V,E) :‬‬
‫הנה‪ ,‬למשל‪ ,‬מספר גרפים‪:‬‬
‫דרגה של קודקוד‬
‫זוג קודקודים הנמצאים משני צידיה של קשת נקראים סמוכים (‪ )adjacent‬או‬
‫שכנים‪ .‬נעיין בגרף הבא‪ ,‬אשר קודקודיו מסומנים באותיות‪:‬‬
‫בגרף זה‪ ,‬שכניו של הקודקוד ‪ x‬הם ‪ u‬ו‪ .v-‬השכן‬
‫היחידי של הקודקוד ‪ y‬הוא הקודקוד ‪ .u‬הקודקוד‬
‫‪ w‬הוא קודקוד מבודד‪ ,‬ללא שכנים‪.‬‬
‫לקודקוד ‪ v‬יש קשת היוצאת ממנו ונכנסת אליו‬
‫חזרה‪ .‬קשת כזו מכונה לולאה עצמית‬
‫(‪ ,)self loop‬או בקיצור – לולאה (‪.)loop‬‬
‫הגדרה‪ :‬נגדיר דרגה (‪ )degree‬של קודקוד ‪ v‬בתור מספר הקשתות הנוגעות‬
‫בו‪ ,‬ונסמן זאת )‪.d(v‬‬
‫למשל‪ ,‬עבור הגרף הזה מתקיים‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪d(x) = 2‬‬
‫‪d(u) = 3‬‬
‫‪d(y) = 1‬‬
‫‪d(w) = 0‬‬
‫‪d(v) = 4‬‬
‫‪‬‬
‫‪‬‬
‫ניתן לראות שדרגתו של קודקוד מבודד היא‬
‫אפס (כי אין אף קשת שנוגעת בו)‪.‬‬
‫כמו כן‪ ,‬עבור הקודקוד ‪ ,v‬רואים כי הלולאה‬
‫"תורמת" ‪ 2‬לדרגת הקודקוד (פעם כשהקשת‬
‫יוצאת מהקודקוד‪ ,‬ופעם שהקשת נכנסת)‪.‬‬
‫דרגה של קודקוד‬
‫טענה‪ :‬בכל גרף‪ ,‬סכום דרגות כל הקודקודים שווה לפעמיים מספר‬
‫הקשתות‪:‬‬
‫‪‬‬
‫‪ d ( x)  2 E‬‬
‫‪xV‬‬
‫טענה זו מכונה לעיתים 'משפט לחיצת‬
‫הידיים'‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫נדמיין קבוצת אנשים שחלקם לוחצים ידיים האחד עם השני‪ ,‬ונייצג‬
‫קבוצה זו על‪-‬ידי גרף‪.‬‬
‫כל אדם ייוצג על‪-‬ידי קודקוד‪ ,‬ונמתח קשת בין שני קודקודים אם שני‬
‫האנשים לחצו ידיים‪.‬‬
‫נניח שכל אדם זוכר לכמה אנשים אחרים הוא לחץ ידיים (זוהי דרגת‬
‫הקודקוד)‪.‬‬
‫משמעות המשפט היא שאם נבקש מכל אדם לומר את מספר האנשים‬
‫איתם הוא לחץ ידיים‪ ,‬ונסכם את כל המספרים‪ ,‬נקבל מספר הגדול פי ‪2‬‬
‫ממספר לחיצות הידיים שהתבצעו‪.‬‬
‫דרגה של קודקוד‬
‫טענה‪ :‬בכל גרף‪ ,‬סכום דרגות כל הקודקודים שווה לפעמיים מספר‬
‫הקשתות‪:‬‬
‫‪‬‬
‫‪ d ( x)  2 E‬‬
‫‪xV‬‬
‫‪‬‬
‫האם קיים גרף בעל ‪ 7‬קודקודים‪ ,‬שדרגתו של כל אחד מהם היא ‪?5‬‬
‫‪‬‬
‫האם קיים גרף שסדרת דרגותיו היא‪...‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪.5 ,4 ,3 ,2 ,2 ,1‬‬
‫‪.3 ,2 ,1 ,1 ,1 ,1 ,1 ,0 ,0‬‬
‫‪.5 ,5 ,4 ,4 ,0‬‬
‫‪.5 ,4 ,3 ,3 ,2 ,2‬‬
‫דרגה של קודקוד‬
‫‪‬‬
‫סדרת מספרים שלמים אי‪-‬שליליים עבורה קיים גרף שזוהי סדרת דרגות‬
‫קודקודיו‪ ,‬נקראת סדרה גראפית (‪.)graphic sequence‬‬
‫כפי שראינו‪ ,‬לא כל סדרה היא גראפית‪ ,‬וקיימות סדרות של מספרים‬
‫שאינן מייצגות דרגות קודקודים של גרף‪.‬‬
‫קיימים אלגוריתמים (כגון אלגוריתם ‪ )Havel-Hakimi‬המקבלים סדרה‬
‫גראפית‪ ,‬ובונים ממנה גרף‪.‬‬
‫‪‬‬
‫שאלה‪ :‬הוכיחו כי אם בגרף יש ‪ n‬קודקודים ו‪ n+4 -‬קשתות‪ ,‬וכל הדרגות‬
‫הן לפחות ‪ ,3‬אזי ‪. n < 8‬‬
‫‪‬‬
‫‪‬‬
‫גרף פשוט‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫ישנם גרפים אשר בהם יש יותר מקשת אחת בין שני קודקודים‪ .‬קשתות כאלה‬
‫נקראות קשתות מקבילות או קשתות מרובות (‪ .)multiple edges‬הגרף הבא‬
‫הוא דוגמא לגרף אשר יש בו קשתות מקבילות‪:‬‬
‫גרף שאיננו מכיל קשתות מקבילות וגם לא לולאות‬
‫עצמיות‪ ,‬נקרא גרף פשוט (‪.)simple graph‬‬
‫רוב הגרפים בהם נעסוק יהיו פשוטים‪ .‬כל הגרפים שראינו עד כה‪ ,‬למעט זה‬
‫שקודקודיו סומנו באותיות‪ ,‬היו גרפים פשוטים‪.‬‬
‫לפניכם שלושה גרפים‪ .‬קבעו לגבי כל אחד האם הוא פשוט או לא‪:‬‬
‫גרף מכוון‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫לעיתים‪ ,‬נרצה לתת לקשתות הגרף כיוון (למשל‪ ,‬אם אנחנו משתמשים בגרף‬
‫על מנת לייצג רשת של כבישים‪ ,‬וחלק מהכבישים הם חד‪-‬סיטריים)‪.‬‬
‫לגרף שבו הקשתות הן מכוונות נקרא גרף מכוון (‪ ,directed graph‬או בקיצור‬
‫‪ .)digraph‬גרף שבו הקשתות אינן מכוונות (וכל הגרפים בהם נתקלנו עד כה‬
‫היו כאלו) נקרא גרף לא‪-‬מכוון (‪ .)non-directed graph‬דוגמא לגרף מכוון‪:‬‬
‫אם ניקח גרף מכוון‪ ,‬ונתעלם מהכיוונים על הקשתות‪,‬‬
‫נקבל גרף לא‪-‬מכוון הנקרא גרף התשתית שלו‪.‬‬
‫בגרף מכוון‪ ,‬נגדיר לכל צומת את דרגת הכניסה (‪)in-degree‬‬
‫ודרגת היציאה (‪ )out-degree‬בתור מספר הקשתות‬
‫המכוונות הנכנסות והיוצאות מתוך הצומת‪ ,‬בהתאמה‪.‬‬
‫נסמן ב‪ din(x)-‬את דרגת הכניסה של צומת ‪ ,x‬ואת דרגת היציאה שלו ‪.dout(x) -‬‬
‫ברור שדרגה של כל צומת (בגרף התשתית הלא‪-‬מכוון) שווה לסכום דרגת‬
‫הכניסה ודרגת היציאה‪.din(x) + dout(x) = d(x) :‬‬
‫בגרף מכוון פשוט מותר שיהיו שתי קשתות המחברות בין שני קודקודים‪ ,‬בתנאי‬
‫שכיווניהן הפוכים‪ .‬קשתות כאלה נקראות קשתות אנטי‪-‬מקבילות‪.‬‬
‫נסחו גירסה של משפט לחיצות הידיים עבור גרפים מכוונים‪.‬‬
‫גרף ממושקל‬
‫לעיתים נרצה להצמיד לכל קשת מספר הנקרא המשקל (‪ )weight‬של הקשת‪.‬‬
‫המשקל של קשת יכול לייצג דברים שונים‪ .‬אם‪ ,‬למשל‪ ,‬הגרף מייצג מערכת‬
‫כבישים (כל קודקוד מייצג עיר‪ ,‬וכל קשת מייצגת כביש המחבר שני ערים)‪ ,‬אז‬
‫המשקל של קשת יכול לציין‪ ,‬לדוגמא‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫את המרחק בקילומטרים שבין עיר לעיר‪.‬‬
‫את מהירות הנסיעה המקסימלית בקמ"ש בכביש הזה‪.‬‬
‫את המחיר שצריך לשלם בשקלים עבור הנסיעה בכביש (אם מדובר בכביש אגרה)‪ ,‬וכו'‪.‬‬
‫גרף שבו לכל קשת מוצמד משקל‪ ,‬נקרא גרף ממושקל (‪.)weighted graph‬‬
‫כל הגרפים בהם נתקלנו עד כה היו גרפים לא‪-‬ממושקלים ( ‪un-weighted‬‬
‫‪.)graphs‬‬
‫להלן דוגמא לשני גרפים ממושקלים‪,‬‬
‫האחד מהם מכוון והשני לא‪-‬מכוון‪:‬‬
‫משקל של קשת אינו בהכרח מספר‬
‫טבעי‪ .‬ייתכנו קשתות שמשקליהן הם‬
‫שברים‪ ,‬מס' שליליים‪ ,‬אפס‪ ,‬וכו'‪.‬‬
‫שאלה‬
‫עד כה הכרנו מספר תכונות לגבי גרפים‪ .‬ראינו כי גרף יכול להיות‪...‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫פשוט ‪ /‬לא פשוט‬
‫מכוון ‪ /‬לא מכוון‬
‫ממושקל ‪ /‬לא ממושקל‬
‫שרטטו דוגמא לגרף אחד מכל אחד מהצירופים האפשריים של שלושת‬
‫התכונות (לדוגמא‪ :‬גרף פשוט לא‪-‬מכוון וממושקל‪ ,‬גרף לא‪-‬פשוט לא‪-‬‬
‫מכוון ולא‪-‬ממושקל‪ ,‬וכו')‪.‬‬
‫כמה צירופים כאלו יש?‬
‫שאלה‬
‫משפחה מפורסמת של גרפים נקראת הגרפים השלמים (‪,)complete graphs‬‬
‫והיא מסומנת ‪ .Kn‬הגרף השלם על ‪ n‬קודקודים‪ ,‬עבור ‪ n‬שלם וחיובי (טבעי)‪,‬‬
‫הוא גרף פשוט שבו כל שני קודקודים הם סמוכים‪.‬‬
‫לדוגמא‪ ,‬הגרפים ‪ K2, K3, K4‬יראו כך‪:‬‬
‫‪‬‬
‫‪‬‬
‫שרטטו את ‪ K5‬ואת ‪.K6‬‬
‫איך יראה ‪?K1‬‬
‫ספרו את מספר הקשתות עבור כל אחד מהגרפים ‪ , Ki‬עבור ‪.i = 1..6‬‬
‫האם תוכלו לתת נוסחא כללית עבור מספר הקשתות של הגרף ‪ Kn‬ולהסביר‬
‫מדוע היא נכונה?‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫נסו להוכיח את טענתכם בשתי דרכים‪ :‬ע"י בניית נוסחת נסיגה ופתירתה‪ ,‬וע"י שימוש‬
‫במשפט לחיצת הידיים‪.‬‬
‫מסלולים‬
‫‪‬‬
‫נכנה בשם מסלול (‪ )path‬כל סדרה של קשתות המחברות קודקודים סמוכים‪.‬‬
‫אורך של מסלול פירושו מספר הקשתות שבו‪.‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫מסלול שבו הקודקוד הראשון והאחרון הם אותו הקודקוד‪ ,‬נקרא מעגל (‪.)cycle‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫לדוגמא‪ AEBA :‬הוא מעגל באורך ‪.3‬‬
‫מסלול יקרא פשוט (‪ )simple path‬אם אף קודקוד לא חוזר בו יותר מפעם‬
‫אחת‪ ,‬ומעגל יקרא פשוט (‪ )simple cycle‬אם אף קודקוד‪ ,‬פרט לקודקוד‬
‫הראשון (שהוא גם האחרון)‪ ,‬לא חוזר בו יותר מפעם אחת‪ ,‬ואף קשת לא חוזרת‬
‫יותר מפעם אחת‪.‬‬
‫‪‬‬
‫‪‬‬
‫לדוגמא‪ AEBD :‬הוא מסלול באורך ‪.3‬‬
‫‪ CAB‬מסלול באורך ‪.2‬‬
‫בכל הדוגמאות שראינו לעיל הופיעו מסלולים פשוטים‬
‫ומעגלים פשוטים‪.‬‬
‫המסלול ‪ AEBDBE‬הוא מסלול לא פשוט באורך ‪.5‬‬
‫המעגל ‪ BACAB‬הוא מעגל לא פשוט באורך ‪.4‬‬
‫האם בהגדרה ניתן לוותר על החלק "ואף קשת‪?"...‬‬
‫גרף לא‪-‬מכוון ייקרא קשיר (‪ )connected‬אם מכל קודקוד‬
‫ניתן להגיע לכל קודקוד אחר על‪-‬ידי מסלול‪.‬‬
‫גרף קשיר‬
‫כאמור‪ ,‬גרף לא‪-‬מכוון ייקרא קשיר (‪ )connected‬אם מכל קודקוד ניתן להגיע‬
‫לכל קודקוד אחר על‪-‬ידי מסלול‪.‬‬
‫נביט בגרף הלא‪-‬קשיר הבא‪:‬‬
‫‪‬‬
‫‪‬‬
‫בגרף לא‪-‬מכוון‪ ,‬רכיב קשירות (‪ )connected component‬הוא תת‪-‬גרף קשיר‬
‫של הגרף המקורי הכולל את כל הקודקודים שניתן להגיע אליהם מקודקוד נתון‪.‬‬
‫לדוגמא‪ ,‬בגרף הנתון ישנם שלושה רכיבי קשירות‪:‬‬
‫‪‬‬
‫‪‬‬
‫רכיב קשירות אחד כולל את הקודקודים ‪.1,2,3,4,8‬‬
‫רכיב קשירות אחר כולל את הקודקודים ‪.0,5,6‬‬
‫רכיב קשירות נוסף כולל את הקודקוד ‪.7‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫קודקוד כזה‪ ,‬שדרגתו היא אפס‪ ,‬נקרא קודקוד מבודד (‪ .)isolated vertex‬קודקוד מבודד‬
‫הוא קודקוד הנמצא לבדו ברכיב קשירות‪.‬‬
‫בגרף קשיר יש בדיוק רכיב קשירות אחד‪.‬‬
‫גרף קשיר בחוזקה‬
‫‪‬‬
‫‪‬‬
‫גרף מכוון ייקרא קשיר היטב או קשיר בחוזקה (‪ )strongly connected‬אם‬
‫מכל קודקוד ניתן להגיע לכל קודקוד אחר על‪-‬ידי מסלול מכוון‪.‬‬
‫לדוגמא‪ ,‬הגרף ‪ G1‬הוא קשיר בחוזקה‪ ,‬ואילו הגרף ‪ G2‬אינו קשיר בחוזקה‪:‬‬
‫‪2‬‬
‫‪‬‬
‫‪‬‬
‫‪G‬‬
‫‪1‬‬
‫‪G‬‬
‫בגרף מכוון‪ ,‬רכיב קשירות בחוזקה (‪,)strongly connected component‬‬
‫המכונה בקיצור רק"ח (‪ ,)SCC‬הוא תת‪-‬גרף קשיר‪-‬בחוזקה של הגרף המקורי‬
‫הכולל את כל הקודקודים שניתן להגיע אליהם מקודקוד נתון‪.‬‬
‫בגרף קשיר בחוזקה יש בדיוק רכיב קשירות בחוזקה (רק"ח) אחד‪.‬‬
‫מטריצת סמיכויות‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫אחת הדרכים הנפוצות לייצג גרף בזיכרון המחשב‪ ,‬היא באמצעות מטריצת‬
‫סמיכויות (‪ ,)adjacency matrix‬הנקראת גם מטריצת שכנויות‪.‬‬
‫שיטה זו היא אפקטיבית בעיקר כאשר ידוע מראש המס' המקסימלי של‬
‫קודקודים בגרף‪.‬‬
‫נסמן מס' זה ב‪ ,n-‬ונניח שלכל קודקוד יוצמד מספר בין ‪ 0‬לבין ‪.n-1‬‬
‫כעת‪ ,‬נגדיר מטריצה ריבועית ‪ A‬בגודל ‪.nxn‬‬
‫אם קיימת קשת בין קודקוד ‪ i‬לבין קודקוד ‪ ,j‬אז נציב את הערך ‪( 1‬או את‬
‫הערך הבוליאני ‪ )TRUE‬בתא ]‪ .A[i][j‬אם לא קיימת קשת כזו‪ ,‬אז נציב בתא‬
‫זה את הערך ‪( 0‬או את הערך הבוליאני ‪.)FALSE‬‬
‫לדוגמא‪:‬‬
‫נשים לב שמטריצת הסמיכויות היא‬
‫מטריצה סימטרית‪ .‬מדוע זה כך?‬
‫מטריצת סמיכויות‬
‫כיצד ניתן לחשב‪ ,‬באמצעות מטריצת סמיכויות‪ ,‬את הדרגה (‪ )degree‬של קודקוד?‬
‫‪‬‬
‫‪‬‬
‫באמצעות ספירת מספר ה‪-1-‬ים בשורה המתאימה לו‪ ,‬או בעמודה המתאימה לו‪.‬‬
‫מהי סיבוכיות זמן הריצה של חישוב זה?‬
‫‪‬‬
‫‪‬‬
‫)‪Ө(n‬‬
‫כיצד ניתן לגלות‪ ,‬באמצעות מטריצת סמיכויות‪ ,‬האם יש בגרף לולאה עצמית?‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫נבדוק האם המספר ‪ 1‬מופיע על האלכסון הראשי של המטריצה‪.‬‬
‫שימו לב שבמקרה כזה‪ ,‬כדי לחשב את דרגת הקודקוד יש לספור את האלכסון הראשי פעמיים‪.‬‬
‫כיצד ניתן לזהות‪ ,‬באמצעות מטריצת סמיכויות‪ ,‬קודקוד מבודד?‬
‫‪‬‬
‫‪‬‬
‫בשורה‪/‬בעמודה המתאימה לקודקוד‪ ,‬מופיעים רק אפסים (פרט לאלכסון הראשי)‪.‬‬
‫כיצד תיראה מטריצת הסמיכויות של גרף שלם ‪?Kn‬‬
‫‪‬‬
‫‪‬‬
‫כל הערכים במטריצה יהיו ‪-1‬ים‪ ,‬פרט לאלכסון הראשי שיכיל רק ‪-0‬ים‪.‬‬
‫מה תהיה סיבוכיות זמן הריצה של אלגוריתם‪ ,‬הבודק האם‬
‫הגרף אוילריאני?‬
‫‪‬‬
‫‪‬‬
‫)‪Ө(n2‬‬
‫מטריצת סמיכויות‬
‫ראינו כיצד ניתן לייצג באמצעות מטריצת סמיכויות גרף בלתי מכוון‪ .‬אולם‬
‫האם תעבוד שיטה זו גם עבור גרף מכוון?‬
‫נשים ‪ 1‬בתא ]‪ A[i][j‬אם יש קשת מכוונת היוצאת מ‪ i-‬ונכנסת ל‪.j-‬‬
‫‪‬‬
‫‪‬‬
‫בשיטה זו‪ ,‬מטריצת הסמיכויות לא תהיה בהכרח סימטרית‪ ,‬משום שמקיומה של קשת‬
‫מכוונת מקודקוד ‪ i‬לקודקוד ‪ j‬לא ניתן להסיק שקיימת קשת מכוונת מקודקוד ‪ j‬לקודקוד ‪.i‬‬
‫‪‬‬
‫מה מאפיין גרף מכוון שמטריצת הסמיכויות שלו היא סימטרית?‬
‫‪‬‬
‫‪‬‬
‫בצד כל קשת מכוונת המופיעה בו‪ ,‬מופיעה גם קשת אנטי‪-‬מקבילה‪.‬‬
‫כיצד ניתן לחשב את דרגת היציאה (‪ )out-degree‬של קודקוד?‬
‫‪‬‬
‫‪‬‬
‫לספור את כמות ה‪-1-‬ים בשורה המתאימה לקודקוד‪.‬‬
‫כיצד ניתן לחשב את דרגת הכניסה (‪ )in-degree‬של קודקוד?‬
‫‪‬‬
‫‪‬‬
‫לספור את כמות ה‪-1-‬ים בעמודה המתאימה לקודקוד‪.‬‬
‫מטריצת סמיכויות‬
‫נניח שרוצים לייצג באמצעות מטריצת סמיכויות גרף ממושקל (‪ ,)weighted‬מכוון או‬
‫בלתי מכוון‪.‬‬
‫הנה הצעה‪ :‬אם לא קיימת קשת בין קודקוד ‪ i‬לבין קודקוד ‪ j‬אז נשים ‪ 0‬בתא ]‪ ,A[i][j‬ואם‬
‫קיימת קשת בין שני הקודקודים – אז בתא ]‪ A[i][j‬נאחסן מספר המציין את משקל‬
‫הקשת‪ .‬איזו חולשה יש בפתרון הזה?‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫הפתרון הזה יעבוד‪ ,‬רק בתנאי שאסור שמשקל קשת יהיה שווה לאפס! אם מרשים שמשקל‬
‫של קשת יהיה שווה לאפס‪ ,‬לא נדע להבחין בין מקרה בו בין שני קודקודים לא קיימת קשת‬
‫כלל‪ ,‬לבין מקרה בו קיימת קשת‪ ,‬אולם המשקל שלה הוא אפס‪.‬‬
‫אפשרות אחרת‪ ,‬היא להגדיר מטריצת סמיכויות שכל אחד מהתאים בה מכיל שני‬
‫ערכים‪ :‬דגל בוליאני הקובע האם קיימת קשת או לא‪ ,‬ומספר המציין את משקל הקשת‬
‫(אם קיימת)‪.‬‬
‫לדוגמא‪:‬‬
‫{ ‪struct edge‬‬
‫;‪int exists‬‬
‫‪ */‬שדה שערכו ‪ 1‬אם קיימת קשת‪ ,‬ו‪ 0-‬אם לא *‪/‬‬
‫‪ */‬שדה שערכו משקל הקשת‪ ,‬אם היא קיימת *‪float weight; /‬‬
‫;}‬
‫;]‪struct edge adjacency_matrix[N][N‬‬
‫מטריצת סמיכויות‬
‫‪‬‬
‫לדוגמא‪ ,‬את הגרף המכוון והממושקל הזה‪:‬‬
‫‪‬‬
‫נייצג באמצעות מטריצת הסמיכויות הבאה‪:‬‬
‫מה סיבוכיות זמן הריצה של אלגוריתם‬
‫המוצא את משקל הקשת הקלה ביותר?‬
‫‪‬‬
‫‪‬‬
‫)‪Ө(n2‬‬
‫שיטת ייצוג זו אינה תומכת בגרפים עם‬
‫קשתות מקבילות (יותר מקשת אחת בין שני‬
‫קודקודים)‪ .‬כיצד ניתן לייצג גרף כזה?‬
‫‪‬‬
‫‪‬‬
‫ניתן לשים בכל תא במטריצה מצביע לראש‬
‫רשימה מקושרת של מבנים‪ ,‬כאשר כל‬
‫מבנה מייצג קשת ומכיל שדה ובו משקל‬
‫הקשת‪.‬‬
‫רשימת סמיכויות‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫שיטה נוספת לייצג גרף בזיכרון המחשב‪ ,‬היא באמצעות רשימת סמיכויות‬
‫(‪ ,)adjacency list‬הנקראת גם רשימת שכנויות‪.‬‬
‫הרעיון הוא להגדיר מערך (או רשימה מקושרת) שכל אחד מאיבריו ייצג‬
‫קודקוד אחד‪ ,‬ולכל אחד מאיברים אלה – תוצמד רשימה מקושרת של כל‬
‫הצמתים שהם שכנים של אותו הקודקוד‪.‬‬
‫לדוגמא‪ ,‬הגרף המכוון הזה‪ ,‬ייוצג כך‪:‬‬
‫רשימת סמיכויות‬
‫‪‬‬
‫כיצד ניתן לייצג גרפים ממושקלים בשיטה זו?‬
‫נוסיף לכל חוליה ברשימה המקושרת שדה נוסף‪ ,‬המייצג את משקל הקשת‪.‬‬
‫לדוגמא‪:‬‬
‫‪‬‬
‫אם ידוע שהגרף הוא דליל (‪ ,)sparse‬כלומר – שמספר הקשתות בו קטן‬
‫מאוד ביחס למספר הקשתות האפשריות‪ ,‬באיזה ייצוג עדיף להשתמש‪:‬‬
‫במטריצת סמיכויות או ברשימת סמיכויות?‬
‫האם ניתן לייצג באמצעות רשימת סמיכויות גם גרף בלתי מכוון?‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫תרגיל‬
‫‪‬‬
‫נתון גרף )‪ ,G = (V,E‬שהוא פשוט‪ ,‬בלתי מכוון ובלתי ממושקל‪:‬‬
‫‪‬‬
‫ייצגו את הגרף ‪ G‬באמצעות רשימת סמיכויות‪.‬‬
‫חשבו את סכום האורכים של כל רשימות הסמיכויות‪.‬‬
‫מה הקשר בין התוצאה שקיבלתם לבין מספר הקשתות בגרף?‬
‫‪‬‬
‫‪‬‬
‫תרגיל‬
‫‪‬‬
‫נתון גרף )‪ ,G = (V,E‬שהוא פשוט‪ ,‬מכוון וממושקל‪:‬‬
‫‪‬‬
‫ייצגו את הגרף ‪ G‬באמצעות מטריצת סמיכויות‪.‬‬
‫ייצגו את הגרף ‪ G‬באמצעות רשימת סמיכויות‪.‬‬
‫‪‬‬
‫תרגיל‬
‫נתון גרף מכוון )‪ .G = (V,E‬נגדיר את הגרף המשוחלף )‪ GT = (V,ET‬באופן הבא‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫קבוצת קודקודיו של הגרף המשוחלף היא ‪ ,V‬כלומר – זהה לקבוצת הקודקודים של הגרף‬
‫המקורי‪.‬‬
‫קבוצת קשתותיו של הגרף המשוחלף היא ‪ ,ET‬המוגדרת באופן הבא‪:‬‬
‫כלומר‪ ,‬קשת )‪ (u,v‬שייכת לקבוצת הקשתות ‪ ET‬של הגרף המשוחלף‪ ,‬רק אם הקשת‬
‫)‪ (v,u‬שייכת לקבוצת הקשתות ‪ E‬של הגרף המקורי‪.‬‬
‫למשל‪ ,‬עבור הגרף ‪ G‬הבא‪:‬‬
‫הגרף המשוחלף ‪ GT‬הוא‪:‬‬
‫פתחו אלגוריתם המקבל כקלט את ‪ ,G‬ומחשב את ‪ .GT‬כתבו את האלגוריתם בשתי גירסאות‪:‬‬
‫במקרה שהגרף מיוצג כמטריצת סמיכויות ובמקרה שהגרף מיוצג כרשימת סמיכויות‪.‬‬
‫נתחו את סיבוכיות זמן הריצה של שני האלגוריתמים‪.‬‬