מבני נתונים ואלגוריתמים - מחברת קורס/גרפים/גרפים וייצוגיהם
דף זה עוסק בגרפים וייצוגיהם. גרפים הם מבנים מתמטיים פשוטים, המתארים "נקודות" ו"קווים" המחברים בין הנקודות. בשל פשטותם הרבה, הם יכולים למדל בעיות מעניינות רבות.
כדאי לדעת: בספר הקורס, הפרק "Elementary Graph Algorithms" עוסק בנושאים אלה. |
מהו גרף?
עריכה
הגדרה: גרף הוא זוג של שתי קבוצות: ו- . היא קבוצת הצמתים (vertexes), ו- היא קבוצת קשתות (edges), שכ"א ממנה היא מצומת כלשהו ב- לצומת כלשהו ב- . |
דוגמה: נניח שיש שש ערים: 1–6. קיימים כבישים מ-1 ל-3 ומ-1 ל-4, מ-3 ל-4, מ-4 ל-5, ומ-2 ל-6. התרשים הבא מראה גרף מתאים לכך: בדוגמה זו, , ו . |
שימו לב: אנו נתמקד במקרה שבו , קבוצת הצמתים, היא קבוצת המספרים השלמים , עבור כלשהו. |
ממשק
עריכההנה הממשק של גרף:
# Returns an array of the vertexes of a graph (G).
V(G)
# Returns an array of the edges of a graph (G).
E(G)
# Returns an array of the adjacent vertexes of a vertex (v) in a graph (G).
A(G, v)
דוגמה: נניח ש
|
מימושים
עריכהרשימה מקושרת
עריכה
מימוש C++ |
במימוש זה מחזיקים מערך ראשי Vertexes
של רשימות-מקושרות משניות:
- במערך הראשי
Vertexes
יש איבר לכל צומת (איבר זה הוא כאמור רשימה מקושרת). - כל רשימה מקושרת מחזיקה את הצמתים שיש קשת מצומת המוצא אליהם.
דוגמה: להלן מבנה הנתונים במימוש זה המתאים לגרף שראינו לעיל: |
במימוש זה, כך נממש את שלוש הפעולות שראינו לעיל:
V(G)
- נחזיר את המערך[1, ..., Length(Vertexes)]
. סיבוכיות הפעולה היא .E(G)
- נעבור בלולאה כפולה על כל חוליות הרשימות המקושרות. בלולאה החיצונית נעבור על המערך הראשיVertexes
, ובלולאה הפנימית נעבור על חוליות הרשימה המשנית. סיבוכיות הפעולה היא .A(G, v)
- נמצא את הרשימה המשנית בתוך המערך הראשיVertexes
בזמן , ונעבור על חוליות הרשימה בלולאה. הסיבוכיות היא , כאשר היא קבוצת השכנים של .
שימו לב: אפשר לממש את הפעולהE(G) כך שזמנה יהיה רק . בשיעורי הבית תתבקש לעשות זאת. מכאן ואילך נניח שבמימוש זה, סיבוכיות הפעולה היא .
|
כדאי לדעת: בפועל כדאי להשתמש בייצוג זה עבור גרפים דלילים, כלומר גרפים בהם . |
מטריצה
עריכה
מימוש C++ |
במימוש זה מחזיקים מערך ראשי של מערכים בוליאניים משניים:
- במערך הראשי יש איבר לכל צומת (איבר זה הוא כאמור מערך בוליאני).
- במערך המשני יש איבר בוליאני לכל צומת. איבר זה הוא
True
אמ"ם יש קשת מצומת המוצא לאיבר המתאים.
דוגמה: להלן מבנה הנתונים במימוש זה המתאים לגרף שראינו לעיל: |
במימוש זה, כך נממש את שלוש הפעולות שראינו לעיל:
V(G)
- בדיוק כמימוש רשימה מקושרת, נחזיר את המערך[1, ..., Length(Vertexes)]
. סיבוכיות הפעולה היא .E(G)
- נעבור בלולאה כפולה על כל האיברים הבוליאניים. בלולאה החיצונית נעבור על המערך הראשיVertexs
, ובלולאה הפנימית נעבור על איברי המערך המשני. נחזיר זוגות המתאימים רק לאיברים שערכםTrue
. סיבוכיות הפעולה היא .A(G, v)
- נמצא את המערך המשני בתוך המערך הראשיVertexs
בזמן , ונעבור על איבריו בלולאה. הסיבוכיות היא .
כדאי לדעת: בפועל כדאי להשתמש בייצוג זה עבור גרפים דחוסים, כלומר גרפים בהם . |
תכונות
עריכהלעתים רוצים לייחס תכונות כלשהן לצמתים, לקשתות, או לשניהם. לדוגמה, ייתכן שנרצה לייחס ערך בוליאני לצומת שמשמעו "נבדק". לחלופין, ייתכן שנרצה לייחס מספר כשלהו לקשת שמשמעו אורך הקשת. כדי ליחס תכונות לצמתים, נשתמש במערכים פשוטים. לדוגמה, קטע הקוד הבא מתאר את זאת שצומת 1 נבדק בגרף לעיל, אבל שאר הצמתים לא:
1 n = Length(V(G))
2 Checked = Make-Array(n)
3 Checked[1] = True
4 for i in [2, ..., n]
5 Checked[i] = False
כדי ליחס תכונות לקשתות, נשתמש בטבלאות ערבול. לדוגמה, קטע הקוד הבא מייחס אורכים לקשתות בגרף לעיל:
1 Distances = Make-Hash()
2 Distances[(1, 4)] = 13
3 Distances[(1, 3)] = 100
4 Distances[(2, 6)] = 2.3
5 Distances[(4, 5)] = 2.3
6 Distances[(3, 4)] = 888
שימו לב: בתחום הגרפים, נניח שייחוס תכונה לקשת כלשהי (כמו ב2-6 בדוגמה לעיל) היא בדיוק . |
גרפים מכוונים ולא מכוונים
עריכהבתרשים הראשון בדף זה ראינו גרף מכוון - גרף שבו יש משמעות לצומת המוצא והיעד של כל קשת.
דוגמה: בגרף שראינו אבל . |
לפעמים אין משמעות לכוון הקשתות, ונניח שלקשתות אין כוון.
הגדרה: נגיד שגרף הוא לא מכוון אמ"ם אין משמעות לכוון הקשתות. |
דוגמה: אם צמתי הגרף מתארים ערים, והקשתות מתארות דרכי עפר בין ערים, אז או שיש דרך בין שתי ערים, או שאין (אבל אם יש - היא דו-כוונית). במקרה כזה נוכל להשתמש בגרף לא מכוון כדי לתאר את המצב. |
כיצד נתייחס לגרף לא-מכוון?
- בציור הגרף, לא נטרח לצייר לקשתות חיצים.
- בשני הייצוגים השונים, נניח (כלומר, שהקשת מופיעה פעמיים).
- אם לקשתות יש תכונות, נניח של ול יש אותן תכונות.
דוגמה: נחשוב על גרסה לא-מכוונת של הגרף הראשון שראינו בעמוד זה. נצייר אותו לרוב כבA בתרשים הבא: כשנתרגם את הגרף לאחד משני הייצוגים שראינו, נחשוב עליו בכB שבתרשים, דהיינו, שיש שתי קשתות בין הצמתים המחוברים. |
הפרק הקודם: גרפים |
גרפים וייצוגיהם תרגילים |
הפרק הבא: עצים |