Các ví dụ về thuật toán ngẫu nhiên
Các ví dụ về thuật toán ngẫu nhiên
Tiếp tục series về thuật toán ngẫu nhiên, trong bài viết này mình ghi lại 3 ví dụ điển hình trong họ bài toán này. Tất cả các ví dụ đều nằm trong cuốn sách Randomized Algorithms
Randomized Quicksort
Thuật toán quicksort có lẽ là một trong những thuật toán khá dễ hiểu khi tìm hiểu về các thuật toán ngẫu nhiên. Thử tưởng tượng ta cho quicksort thông thường chạy 10 lần với dữ liệu đã sắp xếp với randomized-quicksort cũng với cấu hình như vậy, ta sẽ thấy sự khác biệt lớn.
Thuật toán
Chứng minh
Cho dữ liệu đầu vào gồm
Như vậy, độ phức tạp của randomized-quicksort được tính thông qua quá trình sắp xếp mảng theo pivot mà chi phí chính nằm ở phép so sánh các phần tử, tổng chi phí chính là
Tuy nhiên, điều ta quan tâm hơn ở đây là kì vọng chi phí trong các lần thực thi:
Công thức trên được xây dựng dựa vào một tính chất của kì vọng: tính tuyến tính của kì vọng. Như vậy kì vọng của tổng các chi phí so sánh chính bằng tổng của từng kì vọng của biến ngẫu nhiên
Bài toán được qui về việc tính xác suất khi nào phép so sánh giữa hai phần tử
Nếu ta xem quá trình thực thi của randomized-quicksort là quá trình xây dựng cây nhị phân: với mỗi node chính là 1 pivot tại thời điểm gọi hàm partition, kết quả hàm partition ta có được 2 cây con bên trái và phải của node pivot dùng để so sánh. Nếu
Như vậy, để
Như vậy ta có:
Đặt
Random Mincut
Ví dụ
Giả sử ta có dữ liệu facebook của đám bạn cấp 3 và đang tò mò xem trong chục năm qua, những đứa bạn đó có lập thành nhóm chơi thân nào không. Dữ liệu đầu vào là danh sách các bạn trong lớp cấp 3 và mối quan hệ từng người với nhau (quan hệ bạn cấp 3, bạn đại học, đồng nghiệp, quan hệ nam nữ, vợ chồng).
Giả sử ta tạo một đồ thị với đỉnh là một người trong lớp, a có thể nối với b thông qua các cạnh nối:
- Bạn cấp 3 (cái này chắc chắn)
- Bạn đại học
- Đồng nghiệp
Việc tìm ra nhóm bạn thân - tức gắn bó với nhau sau thời gian cấp 3 chính là việc tìm cách tách đồ thị lớn này thành những đồ thị con.
Những bài toán chia cắt đồ thị gọi là graph cut, nếu trong bài toán yêu cầu tìm ra đoạn cắt nào có chi phí thấp nhất: cắt ít số cạnh nhất - thì đó chính là bài toán tìm mincut.
Trong ví dụ này ta xét đồ thị là một multigraph - tức đồ thị có thể có nhiều cạnh cùng nối chung hai điểm. Một số định nghĩa cho phép multigraph là đồ thị có các cạnh lặp (self-loop). Để thuận tiện cho việc chứng minh và minh hoạ, các đồ thị được đề cập trong bài là các đồ thị vô hướng.
Karger Mincut
Một quá trình quan trọng trong thuật toán Karger là Edge Contraction - gộp cạnh. Cho một cạnh $ e = {u, v}$, sau phép gộp cạnh ta sẽ có được một đỉnh mới là
Với các cạnh khác $ e’ = {u, w}$ hay
Một cách đơn giản: phép gộp cạnh sẽ nhập 2 đỉnh lại với nhau - xoá toàn bộ các cạnh nối 2 cạnh cũ và giữ lại những cạnh nối 2 đỉnh đó với các đỉnh khác trong đồ thị.
Thuật toán được mô tả như sau:
- Chọn ngẫu nhiên (theo phân phối đều) một cạnh trong đồ thị.
- Thực hiện phép gộp cạnh vừa chọn.
- Lặp lại bước (1) cho đến khi số đỉnh trong đồ thị còn lại 2.
- Output: min-cut là các cạnh còn lại trong đồ thị
Tính đúng đắn của giải thuật
Để có thể tính được độ phức tạp trong thời gian trung bình, ta cần quay lại một chút về các tính chất của đồ thị. Cho đa đồ thị (multigraph)
Gọi
Như vậy ta có:
Ta thấy xác suất để thuật toán gộp cạnh chọn đúng ngay 1 cạnh trong C chính là
kết hợp với bất đẳng thức phía trên, ta được:
Như vậy, xác suất để thuật toán gộp cạnh không chọn phải các cạnh của
Ta có $p_n \leq (1-\frac{2}{n})p_{n-1} $ .
Đồng thời ta cũng có $ p_2 = 1 $ lí do là bởi Karger chỉ chọn cạnh để gộp khi $ \vert V \vert > 2 $
Nên khi $ n=2 $ thì biến cố chọn phải cạnh để gộp nằm trong $ C $ chắc chắn không xảy ra.
Xác suất
Để dễ tưởng tượng hơn, ta có thể phân tích một chút về trường hợp Karger không tìm ra được mincut, rõ ràng xác suất đó chính là $ 1 - \frac{2}{n(n-1)}$, để tăng độ chính xác, ta có thể cho Karger chạy
Giả sử
Binary Planar Partitions
Giới thiệu

Binary Planar Partitions (trong trường hợp tổng quát là Binary Space Partitions) là một phương pháp phổ biến được sử dụng nhằm chia cắt không gian thành các tập lồi (convex set) chứa các siêu phẳng - hyperplane. Sự chia cắt này tạo nên một cấu trúc dữ liệu được gọi là cây BSP.
BSP có nhiều ứng dụng, đặc biệt là trong các bài toán về đồ hoạ. Điển hình như trong bài toán dựng hình (xác định đối tượng nào được dựng trong khung hình từ góc một góc nhìn nào đó), trong hệ thống CAD, phát hiện va chạm trong robotics, cũng như trong các bài toán chứa các cấu trúc không gian phức tạp.
Trong trường hợp tổng quát, cây BSP, từ mỗi node của mình sẽ chia không gian thành hai nửa siêu phẳng, từ mỗi nửa siêu phẳng đó sẽ tiếp tục được chia cắt thành các nửa siêu phẳng nhỏ hơn sao cho những node lá cuối cùng sẽ chứa 1 đối tượng mà thuộc không gian. Có thể thấy cây BSP là trường hợp tổng quát của cây k-d, và Quadtree.
Ví dụ
Để đơn giản bài toán ta xét trường hợp mặt phẳng với dữ liệu đầu vào là tập các đoạn thẳng sao cho từng cặp trong tập không giao nhau
- Chọn ngẫu nhiên (theo phân phối đều) một hoán vị
trong tập hoán vị của (gồm phần tử). - Tồn tại một vùng chứa nhiều hơn 1 đoạn thẳng:
2.a Cắt vùng này bởi đường thẳng
trong đó là phần tử đầu tiên trong hoán vị (ở đây đường thẳng sẽ chứa ) sao cho cắt vùng đang xét.
Phân tích
Gọi biến
Ở đây ta muốn xét xem kì vọng số lần thuật toán này cắt phải một đoạn thẳng trong tập đầu vào
Bài toán được quy về việc tính xác suất

Bởi đường thẳng chứa
Cho một đoạn
Cận trên được tính như sau:
Tài liệu tham khảo
migrate từ một bài viết cũ năm 2016, nhờ Deepseek chuyển sang markdown nên khả năng cao sẽ có hallucations.