VÉT CẠN VÀ CHIA ĐỂ TRỊGiảng viên hướng dẫn: Phó Giáo sư Tiến sĩ Trần Cao Đệ Nhóm thực hiện: Vương Huỳnh Long1- Nguyễn Ngọc Giàu1 - Phạm Thị Cẩm Tú1 Quách Luyl Đa1 - Nguyễn Hoàng Tiển1- L
Trang 1VÉT CẠN VÀ CHIA ĐỂ TRỊ
Giảng viên hướng dẫn: Phó Giáo sư Tiến sĩ Trần Cao Đệ
Nhóm thực hiện:
Vương Huỳnh Long1- Nguyễn Ngọc Giàu1 - Phạm Thị Cẩm Tú1
Quách Luyl Đa1 - Nguyễn Hoàng Tiển1- Lê Thị Thùy Vân2
1 Lớp: Hệ thống thông tin K19
2 Lớp: Hệ thống thông tin K18
Tóm tắt nội dung Tìm cặp điểm gần nhất là một bài toán kinh điển trong khoa học máy tính Hiện nay, có nhiều thuật toán để giải bài toán này, tuy nhiên bài báo chỉ trình bày hai phương pháp giải: phương pháp Vét cạn và phương pháp Chia để trị Với từng phương pháp, bài báo trình bày ý tưởng, giải thuật bằng mã giả, độ phức tạp lý thuyết, kết quả thực nghiệm của phương pháp khi giải bài toán Tìm cặp điểm gần nhất Cuối cùng, từ độ phức tạp lý thuyết và kết quả thực nghiệm làm cơ sở đưa ra kết luận về tính hiệu quả của hai giải thuật
Keywords: Cặp điểm gần nhất, vét cạn, chia để trị, closest pair, brute force, divide and conquer
1 Phát biểu bài toán
Cho tập P = {p1, p2, , pn} với pi = (xi, yi) và d(pi, pj) là khoảng cách Euclidean giữa điểm pi
và pj Hãy tìm ra một cặp điểm pi và pj sao cho d(pi, pj) là nhỏ nhất, tức là pi và pj là 2 điểm gần nhất.[1]
Hình 1 Cặp điểm gần nhất có màu đỏ
2 Lịch sử giải quyết bài toán
– Giải thuật Vét cạn: giải thuật này không có tác giả Độ phức tạp của giải thuật là O(n2) – Giải thuật Chia để trị: giải thuật này do Bentley và Shamos trình bày năm 1976 Độ phức tạp của giải thuật là O(n log n) [2]
– Giải thuật cải tiến từ Chia để trị của Bentley và Shamos: giải thuật này do Moham-mad Zaidul Karim và Nargis Akter đề xuất Giải thuật này chia bài toán thành n phần thay
vì 2 phần Giải thuật này trong nhiều trường hợp có độ phức tạp nhỏ hơn O(n log n) [3]
3 Tìm cặp điểm gần nhất bằng giải thuật Vét cạn
3.1 Ý tưởng
Ý tưởng giải thuật Vét cạn gồm 03 bước, cụ thể như sau:
Trang 21 Tính tất cả các khoảng cách giữa các điểm trong tập P.
2 Xác định khoảng cách nhỏ nhất trong các khoảng cách vừa tìm được
3 Cặp điểm có khoảng cách ngắn nhất là cặp điểm gần nhất
Ví dụ: cho một phẳng gồm các điểm như Hình 2
Hình 2 Mặt phẳng gồm 5 điểm
1 Lần lượt tính các khoảng cách: AB, AC, AD, AE, BA, BC, BD, BE, CA, CB, CD, CE, DA,
DB, DC, DE, EA, EB, EC, ED
2 Giá trị đoạn BC là nhỏ nhất
3 B và C là cặp điểm ngắn nhất
Mặt phẳng có 5 điểm, với mỗi điểm cần tính khoảng cách của nó với 4 điểm còn lại nên cần 20 phép tính khoảng cách Tổng quát hóa, với mặt phẳng có n điểm, mỗi điểm cần tính khoảng cách với (n − 1) điểm còn lại Vậy, số phép tính khoảng cách trong mặt phẳng có n điểm là n(n − 1) phép tính Tuy nhiên, nhận thấy có sự lặp lại trong quá trình tính toán các khoảng cách và số phép tính lặp lại này chiếm một nửa các phép tính khoảng cách nên loại bỏ các phép tính bị trùng thì số phép tính khoảng cách cần thiết là n(n−1)2
3.2 Giải thuật
Algorithm 1 Thuật toán tìm cặp điểm gần nhất bằng vét cạn
1: procedure BruteForce(P)
2: mindist = ∞
3: n = P.Count
// P.Count là số lượng điểm của tập P
4: for i = 1 n − 1 do
5: for j = i + 1 n do
6: d = dist(Pi, Pj)
7: if (d < mindist) then
9: closestP air = (Pi, Pj)
12: end for
13: return closestP air
14: end procedure
3.3 Độ phức tạp
Độ phức tạp của giải thuật được tính như sau:
– Độ phức tạp của chương trình con dist (phép tính căn và bình phương) là O(1)
– Độ phức tạp của các lệnh 2, 3, 5, 7, 8, 9 là O(1)
– Độ phức tạp của lệnh 5 là O(n − i)
– Độ phức tạp của lệnh 4, cũng chính là độ phức tạp của toàn chương trình
T (n) =X
i=1
n − 1(n − i) = n(n − 1)
2)
Vậy, độ phức tạp của thuật toán Vét cạn cho bài toán tìm cặp điểm gần nhất là T (n) = O(n2)
Trang 34 Chia để trị
Bài báo trình bày thuật toán Chia để trị do hai tác giả Bentley và Shamos trình bày lần đầu tiên vào năm 1976
4.1 Ý tưởng giải thuật
Ý tưởng giải thuật Chia để trị gồm 07 bước, cụ thể như sau:
1 Chia P thành thành 2 tập có số lượng điểm bằng nhau Điểm chia cắt gọi là xmed
2 Tìm cặp điểm gần nhất trong nửa trái có khoảng cách là dL
3 Tìm cặp điểm gần nhất trong nửa phải có khoảng cách là dR
4 Tính d = min(dL, dR)
5 Tạo tập PLR= các điểm Pi có tọa độ x thuộc [xmed− d, xmed+ d]
6 Tìm cặp điểm gần nhất trong tập PLR có khoảng cách là dLR
7 So sánh dL, dR, dLR sẽ tìm ra được cặp điểm gần nhất
Ví dụ: Cho mặt phẳng P như hình 3
Hình 3 Mặt phẳng P gồm 7 điểm
Điểm chia cắt là điểm P4, nửa vùng bên trái là các điểm P2, P3, P7, nửa vùng bên phải là các điểm P5, P1, P6 Khoảng cách ngắn nhất trong nửa trái, nửa phải lần lượt là dL= dist(P2, P3)
và dR= dist(P1, P6) nên d = min(dL, dR) = dR Từ d tìm được các điểm PLR = {P4, P5, P7} là các điểm có tọa độ x ∈ [xmed− d, xmed+ d] trong tập P Tiếp tục tìm đoạn ngắn nhất trong
PLR là dLR = dist(P4, P7) Từ phép tính min(dL, dLR, dR) = dLR → đoạn ngắn nhất là đoạn
dLR, nên cặp điểm gần nhất là (P4, P7)
Hình 4 Cặp điểm gần nhất (P , P )
Trang 44.2 Giải thuật
Algorithm 2 Thuật toán tìm cặp điểm gần nhất bằng Chia để trị
Prepair: PX= P.OrderBy(p => p.X); PY = P.OrderBy(p => p.Y )
1: procedure ClosestPair(PX, PY)
2: if (PX.Count <= 3) then
3: return BruteForce(PX)
4: end if
5: n = PX.Count/2 ; dLR= ∞
6: PLef t= PX.T ake(0, n − 1) ; PRight= PX.Skip(n, PX.Count)
7: dL= ClosestP air(PLef t, PY) ; dR= ClosestP air(PRight, PY)
8: d = min(dL, dR)
9: PLR= PY.W here(p => abs(PX[n].X − p.X) <= d)
10: for each pi∈ PLR do
11: for j = i + 1 i + 5 do
12: if dist(pi, pj) < d then
13: dLR= dist(pi, pj)
17: end for
18: return min(dL, dLR, dR)
19: end procedure
4.3 Độ phức tạp
Gọi T (n) là độ phức tạp của giải thuật với dữ liệu đầu vào n Xét:
– Khi số điểm ≤ 3 thì dừng đệ quy và tính khoảng cách giữa 3 điểm bằng Vét cạn, tốn O(1) – Quá trình đệ quy (chia để trị):
1 Chia: Xác định điểm phân giới n trên tập PX, tốn O(1)
2 Trị: Đệ quy trên nửa trái, nửa phải, tốn 2T (n/2)
3 Tổng hợp: là thời gian tìm ra dLR
• d = min(dL, dR) → tốn O(1)
• PLR= PY.W here(p => abs(PX[n].X − p.X) <= d) → tốn O(n)
Hình 5 Chỉ có 6 điểm tạo ra khoảng cách bằng d trong hình chữ nhật (d, 2d)
• Trong một hình chữ nhật kích thước (d, 2d) như Hình 5 thì chỉ có 6 điểm tạo ra khoảng cách bằng với d Mặt khác, các điểm trong tập PLR được sắp xếp tăng dần theo tọa độ Y nên với một điểm thuộc PLR chỉ cần tính khoảng cách từ nó với 5 điểm lân cận kế tiếp Tốn O(5n) → O(n)
→ độ phức tạp cho quá trình tổng hợp là O(n)
– Thành lập và giải phương trình cho thuật toán chia để trị:
2T (n
2) + n if n > 3→ O(n log n) Vậy, độ phức tạp của khi áp dụng Chia để trị cho bài toán này là T (n) = O(n log n)
Trang 55 Thực nghiệm
Theo lý thuyết, khi giải bài toán tìm cặp điểm gần nhất, độ phức tạp của thuật toán Vét cạn là O(n2) và thuật toán Chia để trị là O(n log n), tức là thuật toán Chia để trị tốt hơn thuật toán Vét cạn Như vậy, cần cài đặt hai giải thuật Vét cạn và Chia để trị Áp dụng hai giải thuật này lên nhiều tập dữ liệu khác nhau với các tiêu chí đánh giá hợp lý nhằm kiểm tra tính đúng đắn của lý thuyết
5.1 Phương pháp sinh dữ liệu
– Sinh ngẫu nhiên
– Không trùng
– Khoảng cách ngắn nhất giữa các điểm là 20 pixel
– Tọa độ các điểm nằm trong ‘khung chứa ảnh’ của chương trình DEMO
– Sinh đủ số lượng điểm yêu cầu thì dừng
5.2 Các tiêu chí đánh giá
– Kết quả của hai thuật toán phải giống nhau trong mọi trường hợp
– Trong đa số trường hợp thì thuật toán Chia để trị có thời gian chạy máy ít hơn Vét cạn – Khi dữ liệu lớn dần thì cả hai thuật toán đều có thời gian chạy máy tăng lên, nhưng thuật toán Vét cạn có thời gian chạy máy tăng rất nhanh (O(n2) tức là cho kết quả chậm khi dữ liệu lớn), còn chia để trị thì tăng không đáng kể (O(n log n) )
5.3 Các chiến lược đánh giá
Chiến lược 1:
– Mục đích: Cho thấy với tập dữ liệu có số điểm ‘đủ lớn’ thì Chia để trị tìm ra cặp điểm nhanh hơn Vét cạn
– Phương pháp:
input: N tập dữ liệu, mỗi tập có kích thước K
output: Xuất kết quả để so sánh và vẽ đồ thị
procedure TestCase1(N)
for n ∈ N do
kq_BF.Add(BruteF orce(n))
kq_DC.Add(DivideAndConquer(n))
end for
GhiFile(kq_BF+kq_DC,‘kq.xml’)
end procedure
– Kết quả:
Hình 6 Bên trái là kết quả chạy 30 tập dữ liệu, mỗi tập có 300 điểm, bên phải là kết quả chạy của 30 tập dữ liệu, mỗi tập có 500 điểm, đường màu xanh là thời gian chạy của Chia để trị, đường màu nâu là thời gian chạy của Vét cạn
Trang 6Chiến lược 2:
– Mục đích: Cho thấy khi dữ liệu tăng dần thì Vét cạn chạy lâu hơn Chia để trị nhiều lần →
Lý thuyết ≈ Thực nghiệm
– Phương pháp:
input: Kmin, Kmax: K.thước dữ liệu nhỏ nhất, lớn nhất
k : bước tăng output: Xuất kết quả để so sánh và vẽ đồ thị
procedure TestCase2(N)
for i = Kmin; i < Kmax; i = i + k do
kq_BF.Add(BruteF orce(i))
kq_DC.Add(DivideAndConquer(i))
end for
GhiFile(kq_BF+kq_DC,‘kq.xml’)
end procedure
Hình 7 Bên trái là kết quả chạy của tập dữ liệu từ 10, 15, 20, , 200 điểm Bên trái là kết quả chạy của tập dữ liệu từ 100,120,140, , 300 điểm
6 Kết luận
– Về lý thuyết:
• Vét cạn: O(n2)
• Chia để trị: O(nlogn)
– Về thực nghiệm: dựa vào kết quả đồ thị
• Khi tập dữ liệu nhỏ thì thời gian chạy của hai thuật toán không chênh lệch, nhưng khi
dữ liệu đủ lớn thì giải thuật Chia để trị chạy nhanh hơn giải thuật Vét cạn Hình minh họa: 6
• Khi tập dữ liệu lớn dần thì cả hai giải thuật đều có thời gian chạy máy tăng nhưng:
∗ Vét cạn: tăng rất nhanh
∗ Chia để trị: tăng rất chậm
∗ Hình minh họa: 7
Từ kết quả tính toán trên lý thuyết và kết quả thực nghiệm, nhận thấy rằng để giải quyết bài toán Tìm cặp điểm gần nhất với tập dữ liệu đủ lớn, thuật toán Chia để trị cho kết quả tốt hơn thuật toán Vét cạn rất nhiều lần về mặt thời gian
Tài liệu
1 T C Đệ, Phân tích và Thiết kế Giải thuật nâng cao 01, Lý Tự Trọng, Cần Thơ, Việt Nam: Đại học Cần Thơ, 2012
2 J L Bentley and M I S (1976), “Proceedings of the 8th annual acm symposium on theory of computing,” in STOC ’76 New York, NY, USA: ACM, pp 220–230
3 N A Mohammad Zaidul Karim, “Optimum partition parameter of divide and conquer algorithm for solving closest pair problem,” International Journal of Computer Science and Information Technology (IJCSIT) Vol 3, No 5, Oct 2011, vol 3, pp 211–219, Oct 2011