גרף קשיר

בתורת הגרפים, גרף בלתי מכוון נקרא קשיר אם קיים מסלול בין כל שני צמתים בגרף. גרף מכוון נקרא קשיר היטב (או קשיר חזק) אם קיים בו מסלול מכוון מכל צומת לכל צומת אחר. פורמלית, גרף G = ( V , E ) {\displaystyle G=\left(V,E\right)} ייקרא קשיר אם לכל זוג צמתים v i {\displaystyle v_{i}\,} ו- v j {\displaystyle v_{j}\,} ב- V {\displaystyle V\,} קיימת סדרה של קשתות e 1 , e 2 , … , e k {\displaystyle e_{1},e_{2},\ldots ,e_{k}} ב- E {\displaystyle E\,} כך שאם e ℓ = ( v a ℓ , v b ℓ ) {\displaystyle e_{\ell }=(v_{a_{\ell }},v_{b_{\ell }})} לכל ℓ ∈ N {\displaystyle \ell \in \mathbb {N} } אז: א. a 1 = i {\displaystyle a_{1}\,=i} . דהיינו, המסלול מתחיל בצומת v i {\displaystyle v_{i}\,} . ב. b k = j {\displaystyle b_{k}\,=j} . דהיינו, המסלול מסתיים בצומת v j {\displaystyle v_{j}\,} . ג. לכל ℓ {\displaystyle \ell } מתקיים b ℓ = a ℓ + 1 {\displaystyle b_{\ell }=a_{\ell +1}} . דהיינו, סדרת הקשתות מהווה מסלול בגרף. יש לשים לב כי ההגדרה הנ"ל משתנה קלות כאשר מדובר בגרפים לא מכוונים או בגרפים מכוונים. במקרה הראשון, קשת היא קבוצה בת שני צמתים, ואילו במקרה השני, קשת היא זוג סדור של שני צמתים. במתמטיקה באופן כללי, ובעיקר בטופולוגיה, קשירות של קבוצה מציינת שכל הקבוצה היא "בחתיכה אחת". בתורת הגרפים קשירות מתבטאת בכך שכל צומתי הגרף מחוברים יחד, במובן זה שניתן להגיע מכל צומת לכל צומת אחר. קשירות היא דרישה בסיסית מגרפים, על מנת שיקיימו תכונות נוספות. למשל, כדי שיהיה בגרף מסלול אוילרי, הכרחי שהוא יהיה קשיר (עד כדי צמתים שאינם מחוברים כלל לקשתות). קשירות היא גם דרישה בסיסית מעץ. רכיב קשירות של גרף הוא תת-גרף קשיר מקסימלי, כלומר, קבוצת קודקודים שיש מסלול בין כל שני קודקודים שלה, והכוללת עם כל קודקוד גם את השכנים שלו; יחד עם הקשתות המחברות את הקודקודים האלה. כל גרף מתפרק באופן יחיד לרכיבי קשירות. דרך נוספת להגדיר רכיבי קשירות היא: נתבונן ביחס על הקודקודים בגרף "יש מסלול ביניהם" זהו יחס שקילות (כאשר בין קודקוד לעצמו יש תמיד את המסלול הריק) אז רכיב קשירות הוא מחלקת שקילות. גרף מכוון נקרא קשיר היטב (או קשיר בחוזקה) אם קיים מסלול מכל צומת שבו אל כל צומת אחר. עבור גרף מכוון כללי, ניתן תמיד לפרק את הגרף לרכיבים קשירים היטב - תתי-גרפים מקסימליים של הגרף המקורי (גם: רק"ח - רכיבי קשירות חזקה), שכל אחד מהם הוא גרף קשיר היטב בפני עצמו. פירוק זה מהווה חלוקה של הגרף למחלקות זרות - שני רכיבים שונים לא יכולים להכיל צומת משותף. גרף מכוון חסר מעגלים (גמ"ל - DAG): גרף בו כל צומת (וקשתותיו היוצאות) מהווה רק"ח יחיד, ויש קשת מכוונת בין שני צמתים אם ורק אם יש קשת בין הרכיבים בגרף המקורי. אלגוריתמים רבים בתורת הגרפים מניחים שהגרף עליו הם פועלים קשיר היטב, ועל כן מפעילים אותם על כל רכיב קשיר היטב בנפרד. גרף מכוון בו עבור כל שני קדקודים u , v ∈ V {\displaystyle u,v\in V} קיים מסלול מ- u {\displaystyle u} ל- v {\displaystyle v} או מ- v {\displaystyle v} ל- u {\displaystyle u} נקרא קשיר למחצה. גרף מכוון הנעשה קשיר לאחר הסרת הכיווניות נקרא קשיר חלש. אלגוריתם Kosaraju (אנ') הוא דרך פשוטה יחסית למציאת הרכיבים הקשירים היטב בגרף שזמן ריצתו ליניארי בגודל הגרף. האלגוריתם מתבסס על שימוש כפול באלגוריתם חיפוש לעומק - פעם אחת על הגרף   G {\displaystyle \ G} עצמו, ופעם על הגרף ה"משוחלף"   G T {\displaystyle \ G^{T}} המתקבל מהיפוך כל כיווני הקשתות. תיאור האלגוריתם: ראשית מפעילים את אלגוריתם חיפוש לעומק על   G {\displaystyle \ G} , ועבור כל צומת זוכרים את זמן היציאה ממנו. כעת מחשבים את   G T {\displaystyle \ G^{T}} . הדבר ניתן לביצוע בזמן ליניארי. כעת מפעילים את אלגוריתם חיפוש לעומק שנית, הפעם על   G T {\displaystyle \ G^{T}} . מתחילים את ריצת האלגוריתם מהצומת בעל זמן היציאה הגבוה ביותר מבין אלו שחושבו בשלב 1, וכאשר האלגוריתם מסיים את הסריקה שהחלה מהצומת הזה ועליו לבחור צומת חדש, בוחרים את הצומת בעל זמן היציאה הגבוה ביותר מבין אלו שנשארו, וכן הלאה. תוצאת האלגוריתם שהופעל בשלב 3 היא יער. כל אחד מהעצים שביער הוא אחד מהרכיבים הקשירים היטב שבגרף, וכולם מופיעים בו. מוציאים אותם כפלט, בהתאם למבוקש (תוצאות החיפוש לעומק בלבד אינן מספיקות, שכן הוא בוצע על הגרף המשוחלף). הסיבה לכך שמובטח שהאלגוריתם יעבוד כהלכה היא זו: אם   C 1 , C 2 {\displaystyle \ C_{1},C_{2}} הם שני רכיבים קשירים היטב בגרף כך שיש קשת מ-   C 1 {\displaystyle \ C_{1}} אל   C 2 {\displaystyle \ C_{2}} , אז מובטח כי זמן היציאה שחושב בשלב 1 עבור צומתי   C 1 {\displaystyle \ C_{1}} גדול מזה שחושב עבור צומתי   C 2 {\displaystyle \ C_{2}} (לא קיימת קשת מ-   C 2 {\displaystyle \ C_{2}} אל   C 1 {\displaystyle \ C_{1}} , שכן אז היו שני הרכיבים הללו מתמזגים לרכיב אחד). על כן, בגרף המשוחלף   G T {\displaystyle \ G^{T}} , לא קיימת קשת מ-   C 1 {\displaystyle \ C_{1}} אל   C 2 {\displaystyle \ C_{2}} (כי הקשתות הפכו את כיוונן). מכיוון שאלגוריתם החיפוש לעומק בשלב 3 מתחיל את ריצתו מהרכיב שמכיל את הצומת בעל זמן היציאה הגדול ביותר שהוא נמצא בהכרח ב-   C 1 {\displaystyle \ C_{1}} , ולכן מרכיב זה לא ניתן להגיע לרכיבים אחרים, והאלגוריתם יחשב אותו בלבד. לאחר שהאלגוריתם פעל על רכיב זה צמתיו מסומנים כך שהאלגוריתם לא ייכנס אליהם שוב, ולכן מובטח כי גם המשך פעולת האלגוריתם תחזיר את התוצאה הנכונה. גרף נקרא k-קשיר (בקודקודים) אם הוא נותר קשיר לאחר הסרת פחות מ-k קודקודים, ו-k-קשיר-קשתות אם הוא נותר קשיר לאחר הסרת פחות מ-k-קשתות. גרף "1-קשיר-קשתות" אינו אלא גרף קשיר. משפט מנגר קובע כי גרף הוא k-קשיר אם ורק אם בין כל שני קודקודים בגרף קיימים k מסלולים זרים בקודקודים והוא k-קשיר-קשתות אם ורק אם בין כל שני קודקודים בגרף קיימים k מסלולים זרים בקשתות.