Closet pairs and merge sort

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

ข้อสังเกต1:ถ้ามีคู่ของจุด คู่ที่อยู่ใกล้กันกว่าระยะทาง หมายความว่า จุดทั้งสองจะต้องอยู่ในแถบ เท่านั้น ดังภาพ

Border.JPG

ข้อสังเกต 2: ถ้าสมมติดว่าแบ่งแถบ ออกเป็นช่อง ๆ แต่ละช่องมีความกว้างและความยาวเป็น ดังภาพ

Devide.JPG

ข้อสังเกต 3: ถ้ามีจุด ที่อยู่ใกล้กัน เป็นระยะห่างน้อยกว่า และจะมีตารางขนาด 4 x 4 ที่แต่ละช่องมีความกว้าง ที่ อยู่ในตารางนั้นเสมอ ดังภาพ

4mul4.JPG

ข้อสังเกต 4: ถ้านำเซต และเซต มารวมกัน แล้วคัดเฉพาะจุดที่อยู่ในแถบ จากนั้นเรียงจุดที่คัดมาจากน้อยไปมากใส่ใน array ชื่อ P ตามแนวแกน y แล้ว ถ้า และ เป็นคู่ที่อยู่ใกล้กันเป็นระยะห่างน้อยกว่า และ แล้ว

ดังนั้นถ้า สมมติว่าเรียงจุดตามที่กำหนดไว้ข้างต้น หาจุดที่อยู่ใกล้กันเป็นระยะห่างน้อยกว่า ได้ในเวลา


Closet_Pairs(p,n)

if n <= 1
return d= \infinity
else if n = 2
return d(P[0],P[1]) // ระยะทางระหว่างสองจุดนั้น
else
k <-- n/2 // เวลาการทำงานส่วนนี้คือ O(1)
L<--(P[0], P[1], P[2], ..., P[k-1]) // เวลาการทำงานส่วนนี้คือ O(n)
R<--(P[k], P[k+1], P[k+2], ..., P[n-1]) // เวลาการทำงานส่วนนี้คือ O(n)
d_L, P_L[0], P_L[1] <-- Closet_Pair(L, k) // เวลาการทำงานส่วนนี้คือ T(n/2)
d_R, P_R[0], P_R[1] <-- Closet_Pair(R, n-k) // เวลาการทำงานส่วนนี้คือ T(n/2)
P' <-- Merge(L', R') // ตามแนวแกน y , เวลาการทำงานส่วนนี้คือ O(n)
d' <-- min (d_R, d_L) // เวลาการทำงานส่วนนี้คือ O(n)
P <- จุดใน P' ที่อยู่ในช่วง [x'-d',x'+d'] // เวลาการทำงานส่วนนี้คือ O(n)
for i = o to n-16 // loop for นี้มีเวลาการทำงาน O(n)
for j = i to i+15
if d(P[i],P[j]) < d' // ถ้าระยะห่างระหว่าง P[i] กับ P[j] น้อยกว่า d'
d'<-- d[P[i],P[j])
return d', คู่ของจุดที่อยู่ใกล้กันที่สุด, P'


Partition (a, l, r, x)

k <-- l
for i=l to r
if a[i] <= x
swap(a[i],a[k])
k <-- k +1
return k


Quicksort (a, l, r)

if r-l+1 <= 1
ไม่ต้องทำอะไร
else
x <-- choose pivot (a, l, r)
l <-- partition (a, l, r, x)
Quicksort (a, l, k-1)
Quicksort (a, k, r)


วิธีการเลือก pivot

1. เลือกตัวแรก x<-- a[l]
2. เลือกตัวสุดท้าย x<-- a[r]
3. tri-median ค่าตัวกลางของ a[l], a[r], a[(l+r)/2]
4. สุ่ม p<-- random (l, r)
x <-- a[p]


ให้ เวลาการทำงานของ Quicksort เมื่อ

เมื่อ

เมื่อ


พิจารณาเวลาการทำงานกรณีแย่ที่สุด คือแบ่งแล้วได้ด้านหนึ่งมีสมาชิกอยู่หนึ่งตัว แล้วอีกด้านเป็นตัวที่เหลือ ( หรือ ) ดังนั้นเวลาการทำงานจะเป็นดังนี้

เมื่อ

เมื่อ

ซึ่งกรณีนี้ท้ายที่สุดแล้ว


พิจารณาเวลาการทำงานกรณีดีที่สุด คือแบ่งแล้วได้ครึ่ง ๆ พอดี ( ดังนั้นเวลาการทำงานจะเป็นดังนี้

เมื่อ

เมื่อ

ซึ่งกรณีนี้ท้ายที่สุดแล้ว


แต่ถ้าเป็นกรณีสุ่มค่า pivot x แล้ว จะเป็น random variable ดังนั้นเวลาการทำงานจะคิดเป็นกรณีเฉลี่ย คือ