Back to Home

Một câu đố đến lúc biết lời giải cũng không tin nổi!

100 tù nhân được đánh mã số từ 1 đến 100. Một căn phòng chứa 100 chiếc hộp đậy nắp, trên nắp có đánh thứ tự từ 1 đến 100, mỗi hộp có chứa 1 tờ giấy cũng đánh số từ 1 đến 100. Lần lượt mỗi tù nhân bước vào căn phòng và được mở ngẫu nhiên 50 hộp để kiểm tra tờ giấy bên trong hộp. Sau đó anh ta phải rời khỏi phòng và không được chia sẻ cho bất cứ tù nhân nào khác về bất cứ thông tin gì về các cái hộp trong phòng. Nếu tất cả 100 tù nhân này đều mở được hộp chứa tờ giấy có mã số trùng với mã số của mình thì tất cả đều được tha bổng, ngược lại tất cả sẽ bị hành quyết. Trước khi chơi trò chơi, các tù nhân được bàn bạc thoải mái chiến thuật chơi. Liệu rằng có phương pháp nào tối ưu cơ hội sống sót cho các tù nhân không?

Thoạt tiên, nếu phân tích theo cách thông thường, mỗi tù nhân được mở 50 hộp, và không được tiết lộ thông tin gì cho các tù nhân khác có thể được hiểu là:

  • Đây là một phép thử có xác suất là 50%50\%

  • Các phép thử hoàn toàn độc lập

Như vậy, xác suất để toàn bộ 100 tù nhân được tha (ai cũng mở được hộp mang tờ giấy có mã số của mình) là (12)100=12100\displaystyle \left( \frac 1 2 \right)^{100} = \frac 1 {2^{100}} . Một xác suất siêu siêu siêu nhỏ!!!

Tuy nhiên, Giáo sư Peter Bro Miltersen đã đưa ra một chiến lược tuyệt vời để đẩy xác suất thắng của trò chơi lên con số gần 3030% trong bài báo “The cell probe complexity of succinct data structures”. Bạn hoàn toàn có thể tìm kiếm bài báo này của ông trên internet.

Chiến thuật dò theo dây chuyền (Search loop)

Thực ra, giáo sư không hề đặt tên cho chiến thuật này, mình tạm thời đặt tên cho chiến thuật này dựa trên mô tả của nó:

  • Bước 1: Mỗi tù nhân mang mã số XXbước vào phòng, tìm hộp có nắp cùng với mã số của mình rồi mở nó ra và nhìn thấy tờ giấy trong hộp mang mã số YY

  • Bước 2: Nếu YY khớp với mã số XX của anh ta => dừng và rời khỏi phòng.

  • Bước 3: Nếu XYX\ne Ythì tiếp tục tìm đến hộp nó nắp có mã số là YY và quay lại Bước 2 cho đến khi tìm ra con số của mình hoặc buộc phải ngừng vì đã đạt đến 12\displaystyle \frac 1 2 số lần tìm kiếm

🤔 Yes, một chiến thuật cực kỳ đơn giản! Nhưng tại sao nó lại tăng khả năng chiến thắng lên một cách đáng kinh ngạc như vậy?

Các search loop…

Đầu tiên, có thể nhận xét rằng cách dò tìm dây chuyền như trên sẽ tạo ra một vòng loop tìm kiếm dây chuyền. Thật vậy, nếu bỏ qua điều kiện giới hạn số lượng hộp mở, khi một tù nhân mã số XX, bắt đầu mở nắp hộp mang nhãn XX, tìm thấy giá trị X1X_1, lại tìm kiếm hộp nhãn X1X_1, mở nắp và thấy giá trị X2X_2 và cứ tiếp diễn như vậy… Vì số lượng hộp là có giới hạn, nên tới một lúc nào đó, anh ta sẽ chắc chắn kiếm được hộp có giá trị XX . Chính lúc tìm thấy giá trị , cũng là lúc anh ta khép lại search loop (vì nếu vẫn làm theo chiến thuật dây chuyền, anh ta sẽ đến hộp mang nhãn XX ban đầu).

Như vậy chỉ có 2 trường hợp xảy ra với cách tìm kiếm như thế này:

  • Search loop có độ dài quá 5050 (quá giới hạn tìm kiếm), tù nhân phải ngừng tìm kiếm.

  • Hoặc, anh ta tìm được XX với search loop có độ dài bé hơn hoặc bằng 5050.

Một câu hỏi đặt ra rằng liệu có khi nào dây chuyền này ngừng giữa chừng ngay tại hộp nhãn XkX_kmà ko tạo ra một search loop không? Không! Vì:

  • Lý do bạn mở mộp hộp nhãn XkX_k nào đó là vì trước đó bạn đã tìm thấy giá trị XkX_k ở một hộp khác.

  • Mỗi giá trị XkX_k chỉ xuất hiện 1 lần duy nhất, nếu đã tìm thấy XkX_k ở hộp khác rồi thì hộp mang nhãn XkX_k không thể có giá trị là XkX_k.

Xác suất các search loop

Chúng ta có 100100 chiếc hộp, như vậy, sẽ có thể có 100100 độ dài của các vòng loop được tạo ra:

  • Độ dài 11 tương ứng với hộp có chứa giá trị cùng với nhãn của nó.

  • Độ dài 100100 tương ứng với một dây chuyền mở ra tất cả 100100 hộp.

Như vậy để chiến thắng trò chơi, nhất định không tồn tại một loop có độ dài quá 5050. Nghĩa là, tỷ lệ chiến thắng có thể được tính bằng 11 trừ cho tổng xác suất để tồn tại loop có độ dài từ 51,52,51,52,\dots đến 100100

😵‍💫 Xác suất để xảy ra loop độ dài k là bao nhiêu?

Gọi P(L=kP(L=k là tỷ lệ để có loop độ dài kk trong nn phần tử. Tỷ lệ này được tính bằng tổng số loop độ dài kk với nn phần tử SnkS_n^k , chia cho số hoán vị tạo ra được từ nn phần tử SnS_n.

  • Sn=n!S_n=n!

  • SnkS_n^k = [số loop riêng biệt độ dài kk từ nn phần tử] ×\times [số hoán vị của kk phần tử trong loop đó] = n.(n1)(n2)(n(k1))k×(nk)!=n!k\displaystyle \frac {n.(n-1)(n-2)\dots(n-(k-1))} {k} \times (n-k)! = \frac {n!} k

Vậy:

P(L=k)=SnkSn=n!kn!=1k\boxed{ P(L=k) = \frac {S_n^k} {S_n} = \frac {\frac{n!}{k}} {n!} = \frac 1 k}

Như vậy, ta tính được tỷ lệ thắng cuộc của các tù nhân nếu áp dụng chiến thuật trên là:

P(win)=1(151+152++1100)10.69=0.31P(win) = 1 - (\frac {1} {51} + \frac {1} {52} + \dots + \frac {1} {100}) \approx 1 - 0.69 = 0.31

Một cách tổng quát:

P(win)=1n2n1xdx=1(ln2nlnn)\boxed {P(win) = 1 - \int_n^{2n}\frac 1 xdx = 1 - (\ln|2n| - \ln|n|)}

Khi n+:n \to +\infty:

ln2nlnn=ln2nlnn=ln2n+ln1n=ln(2n.1n)=ln20.693    P(win)=10.693=0.307\begin{align*} \ln |2n| - \ln |n| &= \ln 2n - \ln n \\ &= \ln 2n + \ln \frac 1 n \\ &= \ln (2n. \frac 1 n) = \ln2 \approx 0.693 \\ &\implies P(win) = 1 - 0.693 = 0.307 \end{align*}

Demo

Và như thường lệ, xin gửi đến bạn đọc một demo thực tế:

  • Bạn sẽ thấy danh sách nn hộp trong hình, nhiệm vụ của bạn là phải giải cứu được n/2n/2 số lượng tù nhân

  • Bằng cách mở nắp hộp sao cho trong n/2n/2 lần mở, bạn phải tìm được ô chứa số tương ứng với tù nhân đó

  • Chú ý là mỗi lần giải cứu được một tù nhân, các con số ẩn trong những cái hộp sẽ bị xáo trộn lại nhằm tránh việc người chơi nhớ vị trí cũ.

💡 Mình có bổ sung thêm phần simulator để máy chơi 100 ván và đếm số lần chiến thắng của máy. Chiến thuật của máy vẫn là chọn lựa mở hộp theo các vòng loop, tù nhân thứ i sẽ mở hộp thứ i đầu tiên.

Comments

0/300

Leave name/email blank to comment anonymously

No comments yet. Be the first to comment!