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 se­ries 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 quick­sort 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 quick­sort thông thường chạy 10 lần với dữ liệu đã sắp xếp với ran­dom­ized-quick­sort 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 n phần tử khác nhau. Gọi Si,1in là phần tử rank i (phần tử nhỏ thứ i) trong mảng, đồng thời ta có Xij biến ngẫu nhiên bằng 1 nếu xuất hiện phép so sánh của 2 phần tử SiSj trong quá trình thực thi, bằng không nếu không xuất hiện phép so sánh nào.

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à i=1nj>iXij.

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:

E[i=1nj>iXij]=i=1nj>iE[Xij]

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 Xij. Gọi pij là xác suất để Xij=1. Ta có:

E[Xij]=pij1+(1p)0=pijE[i=1nj>iXij]=i=1nj>ipij

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ử SiSj xuất hiện.

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 SiSj nằm ở hai nhánh con trái-phải thì phép so sánh giữa hai phần tử này chắc chắn không xảy ra. Như vậy SiSj có quan hệ cha con - một trong hai phần tử phải thuộc node cấp lớn hơn của node kia. Một giả thuyết khác cần xem xét đó là xác suất các số được chọn làm pivot phải bằng nhau (uniform dis­tri­b­u­tion) - có được giả thuyết này ta mới tính được độ phức tạp trong thời gian trung bình được.

Như vậy, để Xij=1 khi và chỉ khi một trong hay vị trí Si hoặc Sj được chọn, và đó là $p_{ij} = \frac{2}{j - i + 1} $ (Xác suất này được tính khi loại đi xác suất chọn phải những pivot nằm bên trái của Si hoặc nằm bên phải của Sj)

Như vậy ta có:

E[i=1nj>iXij]=i=1nj>i2ji+1

Đặt k=ji+1, ta được:

i=1nj>ipiji=1nk=1ni+11k2i=1nk=1n1k=2nk=1n1k

k=1n1k chính là chuỗi har­mony và tổng này sẽ hội tụ về xấp xỉ của ln(n). Và như vậy

E[i=1nj>iXij]2nlogn

Random Mincut

Ví dụ

Giả sử ta có dữ liệu face­book 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 min­cut.

Trong ví dụ này ta xét đồ thị là một multi­graph - 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 multi­graph 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

Minh hoạ thuật toán Karger

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à uv trong đó tất cả các cạnh nối từ u đến v hay ngược lại đều bị loại bỏ, đồng thời các cạnh lặp (self-loop) cũng bị xoá bỏ.

Với các cạnh khác $ e’ = {u, w}$ hay e={v,w} đều trở thành e={uv,w}.

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:

  1. Chọn ngẫu nhiên (theo phân phối đều) một cạnh trong đồ thị.
  2. Thực hiện phép gộp cạnh vừa chọn.
  3. Lặp lại bước (1) cho đến khi số đỉnh trong đồ thị còn lại 2.
  4. 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=(V,E) gồm các đỉnh V và các cạnh E. Gọi d(v) là bậc của đỉnh v là tổng số các cạnh liên thuộc với v. Ta có tính chất sau:

vVd(v)=2|E|

Gọi C là lát cắt có kích thước nhỏ nhất k - tức số lượng các cạnh trong lát cắt đó là k. Do đó, bậc tối thiểu của mỗi cạnh trong đồ thị này là k. Bởi nếu tồn tại một đỉnh có bậc nhỏ hơn k thì lát cắt k không phải là lát cắt nhỏ nhất.

Như vậy ta có:

nkvVd(v)=2|E||E|nk2

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|E|

kết hợp với bất đẳng thức phía trên, ta được:

k|E|2knk=2n

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 C là $p_n $.

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 pn có cận như sau:

pni=0n3(12ni)=2n(n1)

Để 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 min­cut, 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 k lần. Lúc này, xác suất Karger không tìm ra được min­cut là: $ \left (1 - \frac{2}{n(n-1)} \right )^k$. Có một bất đẳng thức thú vị ở đây:

14(11x)x1e

Giả sử k=n(n1)2lnn ta có được kết quả khá đẹp như sau:

(12n(n1))n(n1)2lnn(1e)n(n1)2lnn=(1e)lnn=1n

Binary Planar Partitions

Giới thiệu

Một ví dụ về cây BSP

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 - hy­per­plane. 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 ro­bot­ics, 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 S={s1,s2,,sn}, out­put của bài toán là một cây BSP mà mỗi vùng trong mỗi node lá chỉ chứa 1 một đoạn thẳng.

  1. 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 {1,2,,n} (gồm n! phần tử).
  2. 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 l(si) trong đó i là phần tử đầu tiên trong hoán vị (ở đây đường thẳng l sẽ chứa si) π sao cho si cắt vùng đang xét.

Phân tích

Gọi biến Xij là biến ngẫu nhiên và Xij=1 khi đường thẳng chứa si cắt sj trong một vòng gọi đệ quy nào đó, Xij=0 trong trường hợp ngược lại.

Ở đâ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 S.

E(X)=E[i=1ni=1nXij]=i=1ni=1nE[Xij]=i=1ni=1nPr[Xij=1]

Bài toán được quy về việc tính xác suất Pr[Xij=1]. Gọi t là giao điểm của sisj, index(i,j)=t nếu si cắt t1 đoạn thẳng trước khi giao với sj, như ví dụ bên dưới sij=4. Trường hợp hai đoạn thẳng không cắt nhau thì Sij=.

Ví dụ về giá trị index(i, j)

Bởi đường thẳng chứa si bất kì có thể tiến vô cùng về hai phía nên tồn tại hai đoạn sao cho index(si,sj)=index(si,sk). Nếu index(si,sj)=t ta gọi si1,si2,,sit là những đoạn thẳng mà si sẽ cắt trước khi giao với sj, xác suất để sự kiện này xảy ra là 1t+1

Cho một đoạn sk cố định và m{0,1,2,dots,n2} tồn tại tối đa hai đoạn thẳng sl sao cho index(sl,sk)=m

Cận trên được tính như sau:

E[X]=i=1nj=1nPr[Xij=1]i=1nj=1n1index(i,j)+1i=1nk=2n2k=2nlnn

Tài liệu tham khảo

  1. Introduction to Randomized Algorithms
  2. Randomised Algorithms
Note

mi­grate từ một bài viết cũ năm 2016, nhờ Deepseek chuyển sang mark­down nên khả năng cao sẽ có hal­lu­ca­tions.