dfs

65
לעומק סריקהKleinberg/Tardos- ב3 פרקCormen et al- ב23.3-5 פרקפריקים- אי רכיבים היטב קשירים רכיבים טופולוגי מיון1

Upload: eitan-bendersky

Post on 02-Apr-2015

137 views

Category:

Documents


8 download

TRANSCRIPT

Page 1: DFS

סריקה לעומק

Kleinberg/Tardos-פרק 3 בCormen et al-פרק 23.3-5 ב

רכיבים אי-פריקיםרכיבים קשירים היטב

מיון טופולוגי

1

Page 2: DFS

קשירות

נעיין שוב בבעיית הקשירות:?t-ל s-האם יש מסלול מst

2

Page 3: DFS

קשירות

נעיין שוב בבעיית הקשירות:?t-ל s-האם יש מסלול מ

s t

st

2

Page 4: DFS

כשלון הגישה החמדנית

s t

3

Page 5: DFS

כשלון הגישה החמדנית

s t

3

Page 6: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 7: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 8: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 9: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 10: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 11: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 12: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 13: DFS

תיקון

s t

כשנתקעים במבוי סתום, נבטל את הצעד האחרון שנכשל, וננסה כיוון התקדמות אחר.

4

Page 14: DFS

connectivity(G,s,t) for each x ∈ V do pre[x]←∞, post[x]←∞, from[x]←nil pre_c ← 0, post_c ← 0 DFS(G,s) return pre[t] < ∞

DFS(G,x) pre[x] ← pre_c++ for each y ∈ Adj[x] do if pre[y] = ∞ then from[y] ← x DFS(G,y) end if end for post[x] ← post_c++end DFS

(DFS) סריקה לעומק

בצעד הזה נאמר שהקשת (x,y) נסרקה

x בצעד הזה מגלים את

x-בצעד הזה חוזרים מ

pre[x] :סדר הגילויpost[x] :סדר החזרה

5

Page 15: DFS

סיבוכיות

O(|V|) :אתחול .x לכל היותר פעם אחת לכל DFS(G,x) מבצעים

.x על DFS(G,x)-נחייב את הקריאה ללמעט הקריאות הרקורסיביות, DFS(G,x) עולה

סה”כ:

O(|V|)

O(|V|) + ∑x∈V {O(1) + O(|Adj[x]|)} = O(|V|+|E|)

O(1)+O(|Adj[x]|)

6

Page 16: DFS

סיווג הקשתות

הקשתות הנסרקות נחלקות לארבעה סוגים. קשת שנסרקה (x,y) היא:

.(y כלומר, סריקתה גילתה את) from[y] = x קשת עץ, אםקשת קדימה, אם איננה קשת עץ, אבל y נתגלה בין גילוי x לחזרה

.x-מ.y-לחזרה מ y נתגלה בין גילוי x קשת אחורה, אםקשת הצידה, אם האפשרויות האחרות לא נתקיימו.

,s הגרף הנפרש על ידי קשתות העץ הוא עץ מכוון ששורשו.s-והוא פורש את כל הצמתים הנגישים מ

TDFS

7

Page 17: DFS

הדגמה

0, 9

5, 08, 6

2, 3

6, 77, 4

1, 8

9, 5

4, 13, 2

12 3

5

4

67

8

9

10 11

12

13

זוגות המספרים על הצמתים:סדר הגילוי וסדר החזרה.

המספרים על הקשתות:סדר הסריקה.

קשתות עץקשתות קדימהקשתות אחורהקשתות הצידה

8

Page 18: DFS

הערות

אפשר להריץ את האלגוריתם על גרף לא מכוון.

.x-ל y-ומ y-ל x-תיסרק בשני כיוונים: מ {x,y} כל קשת •• רק הסריקה הראשונה יכולה לגלות צומת חדש.

1. הוכיחו כי בסריקה לעומק של גרף לא מכוון אין קשתות הצידה. (הערה: בגרף לא מכוון אין הבדל בין קשתות קדימה

וקשתות אחורה - שכנעו את עצמכם שכל הקשתות הללו נסרקות לראשונה בכיוון אחורה.)

2. הוכיחו כי ב-G יש מעגל פשוט המכיל את s אםם בכל הרצת .s-מקבלים לפחות קשת אחת אחורה שנכנסת ל s-מ DFS

9

Page 19: DFS

רכיבים אי פריקים

G הקלט: גרף לא מכוון

הפלט: חלוקה של G לרכיבים אי פריקים.

הקלט

הפלט

.G=(V,E) הגדרה: נתון גרף לא מכוון x = y אםם x ∼ y שמקיים ,E יהי ∼ יחס שקילות על

.y-ו x או שיש מעגל פשוט שמכיל אתתתי הגרף הנפרשים על ידי מחלקות השקילות של ∼

.G נקראים הרכיבים האי-פריקים של

שימו לב: הרכיבים האי-פריקים זרים בקשתות, אבל לא בהכרח זרים בצמתים.

הגדרה

10

Page 20: DFS

תכונות

יהי G גרף. נסמן ב-bc(G) את הגרף שצמתיו הרכיבים האי-פריקים של G וצמתי ההפרדה של G וקשתותיו

מחברות בין כל הזוגות של רכיב אי-פריק וצומת הפרדה שמוכל בו. אזי bc(G) הוא עץ.

הגדרה: צומת x ∈ V נקרא צומת הפרדה אםםהסרתו מגדילה את מספר הרכיבים הקשירים שלהגרף. קשת e ∈ E נקראת גשר אםם הסרתה

מגדילה את מספר הרכיבים הקשירים של הגרף.

גשר ≡ רכיב אי-פריק עם קשת אחת.צומת הפרדה ≡ חיתוך בין שני רכיבים אי-פריקים לא

זרים.

צומת הפרדההגדרה

גשר

bc(G)

11

Page 21: DFS

צומת הפרדההדגמה

גשר

12

Page 22: DFS

צומת הפרדההדגמה

גשר

12

Page 23: DFS

צומת הפרדההדגמה

גשר

12

Page 24: DFS

הדגמה

13

Page 25: DFS

זיהוי צמתי הפרדה

נריץ סריקה לעומק של גרף קשיר G החל מצומת s כלשהו. נתבונן בעץ המכוון .

משפט:השורש s הוא צומת הפרדה אםם יש לו לפחות שני ילדים.

כל צומת אחר x הוא צומת הפרדה אםם יש לו ילד y כך שבתת-העץ המושרש ב-y אין אף צומת שממנו קשת אחורה לאב-קדמון

.x של

TDFS

משפט

14

Page 26: DFS

הוכחה

אם ל-s ילד יחיד x, אזי הסרת s מותירה את תת-העץ המושרש s-אינו צומת הפרדה. אם ל s לכן ,G זהו תת-גרף קשיר של .x-ב

לפחות שני ילדים x ו-y, אזי הסרת s מותירה לפחות שני תתי-עצים המושרשים ב-x וב-y. נניח שיש קשת בין צומת u בתת-עץ

אחד לצומת v בתת-העץ האחר. בה”כ u נתגלה לפני ,v-חייבים להגיע ל u-אזי בסריקה מ .(pre[u] < pre[v] ,כלומר) v

ולכן v באותו תת-העץ כמו u, וזו סתירה להנחת קיום הקשת. כלומר, תתי-העצים הללו הם רכיבים קשירים נבדלים, ולכן s צומת

הפרדה.

15

Page 27: DFS

הוכחה (המשך)

יהי x צומת שאיננו s. אם יש ל-x ילד y שבתת-העץ המושרש בו x אזי הסרת ,x אין אף צומת עם קשת אחורה לאב קדמון של

מנתקת את תת-העץ המושרש ב-y משאר הגרף: על פי הנתון אין אף קשת מתת-העץ לצומת במסלול מ-s ל-x. בדומה לטיעון

הקודם, גם אין קשת מתת-העץ המושרש ב-y לאיזשהו תת-עץ x ולכן ,s ,שאר הגרף“ כולל לפחות צומת אחד” .y שאינו מכיל את

צומת הפרדה.

אחרת, גם אחרי הסרת x כל תת-עץ שמושרש בילד של x נותר ברכיב הקשיר של s. בוודאי כל הצמתים שאינם בתת-העץ

המושרש ב-x נותרים ברכיב הקשיר של s. לכן מספר הרכיבים הקשירים לא עולה, ולכן x איננו צומת הפרדה.

16

Page 28: DFS

הדגמה

s

12

3 4

5

6

7

8

10

9

11

12

17

Page 29: DFS

הדגמה

s

12

3 4

5

6

7

8

10

9

11

121

17

Page 30: DFS

הדגמה

s

12

3 4

5

6

7

8

10

9

11

121

5

6

17

Page 31: DFS

הדגמה

s

12

3 4

5

6

7

8

10

9

11

121

5

6

17

Page 32: DFS

הדגמה

s

12

3 4

5

6

7

8

10

9

11

121

17

Page 33: DFS

הדגמה

s

12

3 4

5

6

7

8

10

9

11

121

7

8

10

9

11

12

17

Page 34: DFS

הדגמה

s

12

3 4

5

6

7

8

10

9

11

1211

17

Page 35: DFS

מציאת צמתי הפרדה

נחשב לכל צומת x ערך low[x], שהוא המינימום של pre[z] על כל z שניתן להגיע אליו מתת-העץ המושרש ב-x תוך שימוש בקשת

אחורה אחת לכל היותר.

צומת x שאיננו s הוא צומת הפרדה אםם יש ל-x ילד y עבורו .low[y] ≥ pre[x] מתקיים

“yes”-וישונה ל “no”-שיאותחל ל ,art[x] נחזיק ערך x לכל צומתאםם נזהה את x כצומת הפרדה.

הערה: קשת {x,y} היא גשר אםם היא קשת עץ (x,y) (בחרנו כיוון .low[y] > pre[x]-בה”כ), ו

18

Page 36: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

19

Page 37: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

19

Page 38: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

0

19

Page 39: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

19

Page 40: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

2

19

Page 41: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

19

Page 42: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

19

Page 43: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

0

19

Page 44: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

0

1

19

Page 45: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

0

1

8

19

Page 46: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

0

1

18

19

Page 47: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

0

1

1

7

8

19

Page 48: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

0

1

1

7

8

9

19

Page 49: DFS

הדגמה

0

12

3 4

5

6

7

8

10

9

11

12

low בכחול: ערךוהקשת שקבעה.

0

02

22

0

0

1

1

7

8

9

9

19

Page 50: DFS

DFS_low(G,x) low[x] ← pre[x] ← pre_c++ for each y ∈ Adj[x] do if pre[y] = ∞ then DFS_low(G,y) if low[y] < low[x] then low[x] ← low[y] if low[y] ≥ pre[x] then art[x] ← “yes” else if pre[y] < low[x] then low[x] ← pre[y] end if end forend DFS_low

חישוב low עבור צומת שאיננו השורש

x ילד של y במקרה זה

x אב קדמון של y במקרה זה

מתת-העץ המושרש ב-y יש קשת אחורה לאב קדמון

של low[x] הנוכחי

20

Page 51: DFS

for each y ∈ Adj[x] do if {x,y} לא סרקנו עדיין את then push({x,y},stack) if pre[y] = ∞ then ... if low[y] ≥ pre[x] then art[x] ← “yes” bcc_c++ repeat e ← pop(stack) bcc[e] ← bcc_c while e ≠ {x,y} end if ... end ifend for

סימון הרכיבים האי-פריקים

נחזיק מחסנית של קשתות

זה מונה של מספר הרכיבים

את הלולאה של שליפת קשתותמהמחסנית צריך לבצע גם עבור

.s של השורש y כל ילד

שימו לב: ייתכן של-x יש מספר ילדיםשיזהו אותו כצומת הפרדה, ואז כל ילד

כזה יגרום לשליפת רכיב אי-פריק.21

Page 52: DFS

סיבוכיות

הסריקה לעומק לוקחת O(|V|+|E|) זמן.השינויים לחישוב low לא משנים את הסיבוכיות.

לכל קשת מבצעים O(1) פעולות מחסנית.סה”כ סיבוכיות הזמן:

סיבוכיות המקום: O(|V|+|E|)

O(|V|+|E|)

22

Page 53: DFS

תרגיל בית

הוכיחו שבכל פעם שמבצעים את לולאת repeat אכן קבוצת הקשתות הנשלפת מהמחסנית היא רכיב אי-

פריק.

23

Page 54: DFS

רכיבים קשירים היטב

.G הקלט: גרף מכוון

הפלט: חלוקה של G לרכיבים קשירים היטב.

הקלט

הפלט

.G=(V,E) הגדרה: נתון גרף מכווןיהי ∼ יחס שקילות על V, שמקיים x ∼ y אםם יש

.x-ל y-וגם מ y-ל x-מסלול מכוון מתתי הגרף הנפרשים על ידי מחלקות השקילות של ∼

.G נקראים הרכיבים הקשירים היטב של

שימו לב: תיתכנה קשתות של G שאין כלולות בשום רכיב קשיר היטב.

הגדרה

24

Page 55: DFS

הדגמה

25

Page 56: DFS

הדגמה

25

Page 57: DFS

KS(G) for each x ∈ V do post[x]←∞, from[x]←nil, scc[x]←∞ post_c ← 0, scc_c ← 0 for each x ∈ V do if post[x] = ∞ then DFS(G,x) end for sort(V,-post) for each x ∈ V do if scc[x] = ∞ then DFS_scc(GT,x) scc_c++ end if end for end KS

הגרף מתקבל מ-G על ידי הפיכת כל הקשתות.

Kosaraju-Sharir אלגוריתם

GT

נמיין את V בסדר post יורד

הערך scc[x] יציין את .x מספר הרכיב אליו שייך

26

Page 58: DFS

0, 7

1, 6 2, 3

3, 2

4, 1

5, 06, 5

7, 4

קשתות עץקשתות קדימהקשתות אחורהקשתות הצידה

זוגות המספרים על הצמתים:סדר הגילוי וסדר החזרה.

המספרים על הקשתות:סדר הסריקה.

1

23

4

5

6

78

9

1011

12

DFS הדגמה: תוצאות

27

Page 59: DFS

DFS_scc(G,x) scc[x] ← scc_c for each y ∈ Adj[x] do if scc[y] = ∞ then DFS_scc(G,y) end forend DFS_scc

איסוף רכיב קשיר היטב

28

Page 60: DFS

0, 3

3, 0 4, 4

5, 7

7, 5

6, 62, 1

1, 2

קשתות עץקשתות קדימהקשתות אחורהקשתות הצידה

זוגות המספרים על הצמתים:סדר הגילוי וסדר החזרה.

המספרים על הקשתות:סדר הסריקה.

5

67

10

9

8

12

411

21

3

DFS_scc הדגמה: תוצאות

באדום: סדר DFS-החזרה ב

7

6

5

4

2

3

0

1

29

Page 61: DFS

הוכחת נכונות

.G על DFS נתבונן בלולאה של הרצת אבחנה: הגרף הנפרש על ידי קשתות העץ הוא אוסף של עצים

מכוונים זרים הפורשים יחד את V(G). (כל קריאה מהפרוצדורה (.x-מייצרת עץ מושרש ב DFS(G,x)-ל KS

post את הצומת בעל ערך φ(x)-נסמן ב x ∈ V הגדרה: לכל.G-ב x-המירבי מבין כל הצמתים הנגישים מ

שימו לב: φ(φ(x)) = φ(x) (מדוע?)טענה: ב-G יש מסלול מכוון מ-φ(x) ל-x ולכן x ו-φ(x) באותו רכיב

קשיר היטב.

הגדרה

טענה

אבחנה

שימו לב

30

Page 62: DFS

7, 7

6, 7 3, 3

2, 2

1, 2

0, 25, 7

4, 7

קשתות עץקשתות קדימהקשתות אחורהקשתות הצידה

זוגות המספרים על הצמתים:.φ סדר החזרה וערך

φ הדגמה: חישוב

31

Page 63: DFS

הוכחת נכונות (המשך)

הוכחה: אם φ(x) = x אז בוודאי הטענה נכונה. אם חזרנו כבר מ-φ(x) לפני שגילינו את x אז post[φ(x)] < post[x], וזו סתירה

.φ(x) להגדרת נניח שגילינו את x לפני שגילינו את φ(x). אזי יהי z הצומת

האחרון במסלול מ-x ל-φ(x) שנתגלה לפני או בזמן גילוי x. יש כזה כי x כזה. כל הצמתים בקטע המסלול מ-z ל-φ(x) עדיין לא

נתגלו בזמן גילוי z. לכן כולם, בפרט φ(x) יתגלו בין גילוי z לחזרה z כי ,φ(x) וזו סתירה להגדרה של post[φ(x)] < post[z] לכן .z-מ

.x-נגיש מלכן, האפשרות היחידה היא ש-x נתגלה בין גילוי φ(x) לבין

החזרה מ-φ(x), כלומר, x נמצא בתת-העץ המושרש ב-φ(x), ולכן ∴ .x-ל φ(x)-יש מסלול מכוון מ

הוכחה

32

Page 64: DFS

הוכחת נכונות (המשך)

מסקנה: שני צמתים x,y נמצאים באותו רכיב קשיר היטב .φ(x) = φ(y) אםם

הוכחה: כל הצמתים באותו רכיב נגישים זה מזה, ולכן לכולם אותו ערך φ. מצד שני, x ו-φ(x) באותו רכיב וכך גם y ו-φ(y). לכן,

אם φ(x) = φ(y), אז x,y באותו רכיב.

מסקנה

הוכחה

33

Page 65: DFS

הוכחת נכונות (המשך)

DFS_scc(GT,x)-עכשיו נתבונן בקריאה להקריאות הקודמות (אם היו) ל-DFS_scc לא גילו את x, ולכן ב- אין אף מסלול מצומת שנתגלה בקריאות הקודמות ל-x, כלומר ב-G אין אף מסלול מ-x לצומת שנתגלה בקריאות הקודמות. אבל,

קבוצת הצמתים שנתגלתה בקריאות הללו כוללת את כל הצמתים .φ(x) = x ולכן post[x]-הגדול מ DFS-מ post עם ערך

הצמתים המתגלים בקריאה ל- הם בדיוק הצמתים שנגישים ב- מ-x. לכל צומת כזה y יש ב-G מסלול מ-y ל-x. אבל x בעל ערך post המירבי מבין כל הצמתים שנותרו,

כך ש-φ(y) = x. כלומר, הקריאה ל- מסמנת את ∴ .x הרכיב הקשיר היטב של

DFS_scc(GT,x)

DFS_scc(GT,x)

GT

GT

34