418531 ภาคต้น 2552/โจทย์ปัญหาอัลกอริทึมเกี่ยวกับกราฟ/เฉลยข้อ 6.3

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา

สังเกตว่าหลังจากการรัน DFSALL แล้วจะได้ อะเรย์ pre และ post มา ซึ่งอะเรย์ pre จะบอกถึงเวลาที่ node นั้น ๆ เริ่มต้นถูกสำรวจ ส่วนอะเรย์ post จะบอกถึงเวลาที่ node นั้น ๆ สำรวจเสร็จ ดังนั้นเราจะได้ว่า node สอง node ใด ๆ ถ้า pre ของ u มากกว่า pre ของ v แสดงว่า node u ถูกสำรวจก่อน node v (มิเช่นนั้นก็กลับกัน) ส่วนถ้า post ของ u มากกว่า post ของ v ก็จะได้ว่า การสำรวจ u เสร็จทีหลังการสำรวจ v นอกจากนี้การสังเกตว่า topological ordering คือการนำ node ในกราฟมาเรียงลำดับจากซ้ายไปขวา แล้ว edge ทุก edge ในกราฟจะชี้จากซ้ายไปขวา พิจารณา edge ที่ชี้จาก u ไป v ใน DAG ใด ๆ จะได้ว่า post ของ u ต้องมากกว่า post ของ v เสมอ (ความจริงจากข้อย่อย 6.1) ดังนั้น ถ้าเราทำการหา DFSALL แล้วทำการ order node จาก node ที่มีค่า post มากไปน้อย เราก็จะได้ topological ordering ตามที่เราต้องการ (มีข้อสังเกตอีกอย่างคือ เนื่องจากค่าในอะเรย์ post เป็นค่าของเวลา และเมื่อทำการบันทึกค่าของเวลาที่ node ใด ๆ ถูกสำรวจเสร็จแล้ว เราจะทำการเพิ่มค่าของตัวแปร clock ขึ้นอีกหนึ่ง จึงทำให้ค่าของอะเรย์ post เหล่านี้ไม่ซ้ำกันในแต่ละช่อง ดังนั้นถ้าเราเรียงตามค่า post ก็จะไม่มี node สอง node ใด ๆ อยู่ในลำดับซ้ำกันนั่นเอง)

จากแนวคิดข้างต้น นำมาเขียนเป็น pseudocode ได้ดังนี้

ในส่วนของอัลกอริทึม DFSALL จะทำเหมือนเดิม แต่ DFS จะทำการเพิ่มอะเรย์ order ให้เก็บลำดับการเรียงที่เราต้องการ โดยจะทำการใส่ค่าให้อะเรย์นี้เมื่อ node นั้นถูกสำรวจเรียบร้อยแล้ว และการใส่ค่าจะใส่จากหลังไปหน้า

<geshi lang="c"> DFS(u) {

   j = n
   pre[u] = clock
   clock = clock + 1
   explored[u] = 1
   
   for i = 1 to d[u] do
   {
       v = a[u][i]
       if explored[v] = 0 then
       {
           parent[v] = u
           DFS(v)
       }
   }
   post[u] = clock
   order[j] = u // อะเรย์ order เก็บลำดับของการเรียงที่เราต้องการ
       j = j-1 //การใส่ลำดับของ node นี้จะใส่จากหลังมาหน้า
   clock = clock + 1

} </geshi>


<geshi lang="c"> DFSALL() {

    for u = 1 to n do
         if explored[u] = 0 then
         {
              parent[u] = 0
              DFS(u)
         }

} </geshi>

<geshi lang="c"> Topological_DFSALL()

   DFSALL()
   for i = 1 to n do
       print order[i]

</geshi>