Cơ hội nào để tôi giành được giải thưởng cửa?


12

Chương ACM địa phương của tôi trao giải thưởng cửa cho những người đến dự các cuộc họp. Tuy nhiên, bạn sẽ tăng cơ hội chiến thắng nếu giải được câu đố lập trình (nhưng tôi luôn giải câu đố đó). Vì vậy, một số người có 1 mục, trong khi những người khác có 2. Nhưng hãy chờ! Cách chương trình xổ số hoạt động không phải bằng cách thêm vào một mục khác khi ai đó giải câu đố. Thay vào đó, nó theo dõi số lượng "cuộc sống" của một người, giảm dần rằng nếu người đó được chọn trong mỗi lần vượt qua thuật toán lấy mẫu ngẫu nhiên của nó. Vì vậy, nó hoạt động như thế này:

Doorknob: 1.  xnor: 2.  Justin: 2.  Alex: 1.  Dennis: 2.

Sau đó, chương trình chọn ngẫu nhiên một trong số đó [Doorknob, xnor, Justin, Alex, Dennis], giảm số (nói là chọn Justin):

Doorknob: 1.  xnor: 2.  Justin: 1.  Alex: 1. Dennis: 2.

Và lặp lại. Nếu số "cuộc sống" của ai đó được chuyển đến 0(hãy chọn Justinlại), họ sẽ bị xóa khỏi danh sách:

Doorknob: 1.  xnor: 2.  Alex: 1.  Dennis: 2.

Điều này tiếp tục cho đến khi có một người còn lại; người đó là người chiến thắng

Bây giờ câu hỏi thực sự là, xác suất mà tôi sẽ giành được là gì?


Bạn sẽ được cung cấp hai đầu vào:

  • n. Đây là số người tham gia thử thách
  • k. Đây là số người (trong số những người n) có 2 cuộc sống. Con số này luôn bao gồm bạn.

Vì vậy, nếu tôi có một chức năng pvà được gọi p(10, 5), đó sẽ là xác suất giành được giải thưởng khi có tổng cộng 10 người, 5 trong số đó chỉ có 1 mạng, trong khi 5 (bao gồm cả bạn) có 2 mạng.


Bạn dự kiến ​​sẽ đưa ra xác suất chiến thắng chính xác hoặc dưới dạng thập phân. Ở bất kỳ giá nào, câu trả lời phải chính xác đến và bao gồm vị trí thập phân thứ 4 sau dấu thập phân. Bạn có làm tròn số đó hay không là tùy thuộc vào bạn.

Giải pháp của bạn có thể là một giải pháp ngẫu nhiên đưa ra câu trả lời cho vị trí thập phân thứ 4 với xác suất cao . Bạn có thể cho rằng RNG tích hợp mà bạn sử dụng là thực sự ngẫu nhiên và nó phải đưa ra câu trả lời đúng với xác suất ít nhất 90%.

Hơn nữa, mã của bạn chỉ cần hoạt động n, k <= 1000, mặc dù tôi đã cung cấp các trường hợp thử nghiệm lớn hơn so với những người tò mò.


Các trường hợp thử nghiệm

Lưu ý: một số trong số này là công thức chung.

n,    k   |  output
----------+---------
1,    1   |  1
2,    2   |  0.5
2,    1   |  0.75
3,    1   |  11/18 = 0.611111111
1000, 1   |  0.007485470860550352
4,    3   |  0.3052662037037037
k,    k   |  1/k
n,    1   |  (EulerGamma + PolyGamma[1 + n])/n    (* Mathematica code *)
          |  (γ + ψ(1 + n))/n
10,   6   |  0.14424629234373537
300,  100 |  0.007871966408910648
500,  200 |  0.004218184180294532
1000, 500 |  0.0018008560286627948
---------------------------------- Extra (not needed to be a valid answer)
5000, 601 |  0.0009518052922680399
5000, 901 |  0.0007632938197806958

Đối với một vài kiểm tra khác, hãy thực hiện p(n, 1) * nnhư sau:

n     |  output
------+---------
1     | 1
2     | 1.5 
3     | 1.8333333333333335
10    | 2.928968253968254
100   | 5.1873775176396215
-------------------------- Extra (not needed to be a valid answer)
100000| 12.090146129863305

Tôi không còn quen thuộc với các thẻ trên trang web này; Nếu bạn nghĩ về một thẻ thích hợp hơn, xin vui lòng chỉnh sửa!
Justin

Câu hỏi liên quan chặt chẽ về math.se: math.stackexchange.com/q/1669715/72616
Justin

Vậy, P (n, k) = ((k-1) / n) P (n, k-1) + ((nk) / n) P (n-1, k) + (1 / n) Q ( n, k - 1), trong đó Q (n, k) = ((nk - 1) / n) Q (n - 1, k) + (k / n) Q (n, k - 1) và Q (1 , 0) = 1 ...
Nữ tu bị rò rỉ

@KennyLau Tôi sẽ không cố gắng diễn giải nó, nhưng hãy cẩn thận với liên kết math.se, vì nó sử dụng một định nghĩa hơi khác về chức năng (tôi tin klà bị tắt bởi một)
Justin

2
Có thể thực hiện một mô phỏng ngẫu nhiên với đủ các thử nghiệm mà câu trả lời là chính xác đến vị trí thập phân thứ tư với xác suất cao, mặc dù tất nhiên là không chắc chắn?
xnor

Câu trả lời:


2

MATL , 42 byte

:<~QXJx`J`tf1Zry0*1b(-tzq]f1=vts3e8<]6L)Ym

Điều này sử dụng một cách tiếp cận xác suất (Monte Carlo). Thí nghiệm được thực hiện với số lượng lớn thời gian, từ đó xác suất được ước tính. Số lượng thực hiện được chọn để đảm bảo rằng kết quả là chính xác đến thập phân thứ tư với xác suất ít nhất 90%. Tuy nhiên, điều này mất một thời gian rất dài và rất nhiều bộ nhớ. Trong liên kết bên dưới số ngộ đã được giảm một yếu tố của 10 6 để chương trình kết thúc trong một amout thời gian hợp lý; và chỉ số thập phân đầu tiên được đảm bảo chính xác với xác suất ít nhất 90%.

EDIT (29 tháng 7 năm 2016): do thay đổi ngôn ngữ, 6L cần được thay thế bằng 3L. Liên kết dưới đây kết hợp sửa đổi đó.

Hãy thử trực tuyến!

Lý lịch

Gọi p là xác suất được tính. Thí nghiệm được mô tả trong thử thách sẽ được thực hiện trong một số lần n . Mỗi lần, bạn giành được giải thưởng ( thành công trực tiếp ) hoặc bạn không. Gọi N là số lần thành công. Xác suất mong muốn có thể được ước tính từ Nn . N càng lớn , ước tính sẽ càng chính xác. Câu hỏi chính là làm thế nào để chọn n để thực hiện với độ chính xác mong muốn, cụ thể là, để đảm bảo rằng ít nhất 90% số lần lỗi sẽ nhỏ hơn 10 −4 .

Phương pháp Monte Carlo có thể là

  • Kích thước cố định : giá trị n được cố định trước (và sau đó N là ngẫu nhiên);
  • Biến kích thước : n được xác định khi đang bay bằng kết quả mô phỏng.

Trong số các loại thứ hai, một phương pháp được sử dụng phổ biến là sửa N (số lần thành công mong muốn) và tiếp tục mô phỏng cho đến khi đạt được số lần thành công đó . Do đó n là ngẫu nhiên. Kỹ thuật này, được gọi là lấy mẫu nhị thức nghịch đảo hoặc Monte Carlo nhị phân âm , có ưu điểm là độ chính xác của công cụ ước tính có thể bị giới hạn. Vì lý do này, nó sẽ được sử dụng ở đây.

Cụ thể, với nhị phân âm Monte Carlo x = ( N 1) / ( n 1) là một ước lượng không thiên vị của p ; và xác suất mà x lệch khỏi p nhiều hơn một tỷ lệ nhất định có thể được giới hạn trên. Theo phương trình (1) trong bài viết này (cũng lưu ý rằng các điều kiện (2) được thỏa mãn), lấy N = 2,75 · 10 8 hoặc lớn hơn đảm bảo rằng p / x thuộc khoảng [1,0001, 0,9999] với ít nhất 90% xác suất. Cụ thể, điều này ngụ ý rằng x đúng đến vị trí thập phân thứ 4 với xác suất ít nhất 90%, như mong muốn.

Mã giải thích

Mã sử ​​dụng N = 3e8để lưu một byte. Lưu ý rằng thực hiện nhiều mô phỏng này sẽ mất nhiều thời gian. Mã trong liên kết sử dụng N = 300, chạy trong một khoảng thời gian hợp lý hơn (dưới 1 phút trong trình biên dịch trực tuyến cho các trường hợp thử nghiệm đầu tiên); nhưng điều này chỉ đảm bảo rằng số thập phân đầu tiên là chính xác với xác suất ít nhất 90%.

:        % Take k implicitly. Range [1 ... k]
<~       % Take n implicitly. Determine if each element in the previous array is
         % less than or equal than n
Q        % Add 1. This gives an array [2 ... 2 1 ... 1]
XJx      % Copy to clipboard J. Delete from stack
`        % Do...while. Each iteration is a Monte Carlo realization, until the 
         % desired nunber of successes is reached
  J      %   Push previously computed array [2 ... 2 1 ... 1]
  `      %   Do...while. Each iteration picks one door and decrements it, until
         %   there is only one
    t    %     Duplicate
    f    %     Indices of non-zero elements of array
    1Zr  %     Choose one of them randomly with uniform distribution
    y0*  %     Copy of array with all values set to 0
    1b(  %     Assign 1 to chosen index
    -    %     Subtract
    tzq  %     Duplicate. Number of nonzero elements minus 1. This is falsy if
         %     there was only one nonzero value; in this case the loop is exited
  ]      %   End do...while
  f1=    %   Index of chosen door. True if it was 1 (success), 0 otherwise
  v      %   Concatenate vertically to results from previous realizations
  ts3e8< %   Duplicate. Is the sum less than 3e8? If so, the loop is exited
]        % End do...while
6L)      % Remove last value (which is always 1)
Ym       % Compute mean. This gives (N-1)/(n-1). Implicitly display

Haha Tôi đã không nhận ra rằng 90% sẽ làm cho nó trở nên khó khăn :-)
Justin

Có, số thập phân thứ tư với độ tin cậy 90% là một yêu cầu thực sự mạnh mẽ :-)
Luis Mendo

2

Bình thường, 34 byte

Mc|!*HJ-GHch*J+*tHgGtH*gtGHKh-GHKG

Bộ kiểm tra

Xác định hàm đệ quy ghi nhớ xác định glấy n , k làm đối số. g 1000 500trả về 0.0018008560286627952trong khoảng 18 giây (không bao gồm trong bộ thử nghiệm ở trên vì nó bỏ qua trình thông dịch trực tuyến).

Một bản dịch Python 3 gần đúng sẽ là

@memoized
def g(n,k):
    return (not k*(n-k) or (1+(n-k)*((k-1)*g(n,k-1)+g(n-1,k)*(n-k+1)))/(n-k+1))/n

1

JavaScript (ES6), 65 byte

f=(n,k,d=n-k)=>(!d||(f(n-1,k)*++d*--d+1+(--k&&f(n,k)*k*d))/++d)/n

Đừng thử với số lượng lớn mặc dù; thậm chí f (30, 10) mất một khoảng thời gian đáng chú ý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.