Nghịch lý sinh nhật hoặc tại sao PRNG tạo ra các bản sao thường xuyên hơn bạn có thể nghĩ.
Có một số vấn đề đang diễn ra trong vấn đề của OP. Một là nghịch lý ngày sinh như đã đề cập ở trên và thứ hai là bản chất của những gì bạn đang tạo ra, vốn dĩ không đảm bảo rằng một số nhất định sẽ không lặp lại.
Nghịch lý sinh nhật áp dụng khi giá trị đã cho có thể xuất hiện nhiều lần trong khoảng thời gian của trình tạo - và do đó có thể xảy ra trùng lặp trong một mẫu giá trị. Ảnh hưởng của Nghịch lý sinh nhật là khả năng thực sự nhận được các bản sao như vậy là khá đáng kể và khoảng thời gian trung bình giữa chúng nhỏ hơn người ta có thể nghĩ. Sự bất hòa này giữa xác suất nhận thức và xác suất thực tế khiến Nghịch lý Sinh nhật trở thành một ví dụ điển hình về sự thiên lệch nhận thức , trong đó một ước tính trực quan ngây thơ có khả năng sai cực kỳ lớn.
Sơ lược nhanh về Máy tạo số ngẫu nhiên giả (PRNG)
Phần đầu tiên của vấn đề là bạn đang lấy giá trị hiển thị của bộ tạo số ngẫu nhiên và chuyển đổi nó thành một số nhỏ hơn nhiều, vì vậy không gian của các giá trị có thể bị giảm đi. Mặc dù một số trình tạo số giả ngẫu nhiên không lặp lại các giá trị trong khoảng thời gian của chúng, phép biến đổi này sẽ thay đổi miền thành một miền nhỏ hơn nhiều. Miền nhỏ hơn sẽ làm mất hiệu lực của điều kiện 'không lặp lại', vì vậy bạn có thể mong đợi khả năng lặp lại đáng kể.
Một số thuật toán, chẳng hạn như PRNG congruential tuyến tính ( A'=AX|M
) làm độc đáo đảm bảo cho toàn bộ thời gian. Trong LCG, giá trị được tạo chứa toàn bộ trạng thái của bộ tích lũy và không có trạng thái bổ sung nào được giữ lại. Bộ tạo là xác định và không thể lặp lại một số trong khoảng thời gian - bất kỳ giá trị tích lũy đã cho nào chỉ có thể ngụ ý một giá trị liên tiếp có thể có. Do đó, mỗi giá trị chỉ có thể xuất hiện một lần trong khoảng thời gian của bộ tạo. Tuy nhiên, khoảng thời gian của một PRNG như vậy là tương đối nhỏ - khoảng 2 ^ 30 đối với các triển khai điển hình của thuật toán LCG - và không thể lớn hơn số lượng các giá trị riêng biệt.
Không phải tất cả các thuật toán PRNG đều có chung đặc điểm này; một số có thể lặp lại một giá trị nhất định trong khoảng thời gian. Trong bài toán OP, thuật toán Mersenne Twister (được sử dụng trong mô-đun ngẫu nhiên của Python ) có khoảng thời gian rất dài - lớn hơn nhiều so với 2 ^ 32. Không giống như PRNG tuyến tính công suất, kết quả không hoàn toàn là một hàm của giá trị đầu ra trước đó vì bộ tích lũy chứa trạng thái bổ sung. Với đầu ra số nguyên 32 bit và khoảng thời gian ~ 2 ^ 19937, nó không thể cung cấp một bảo đảm như vậy.
Mersenne Twister là một thuật toán phổ biến cho PRNG vì nó có các đặc tính thống kê và hình học tốt và một khoảng thời gian rất dài - các đặc điểm mong muốn cho một PRNG được sử dụng trên các mô hình mô phỏng.
Các thuộc tính thống kê tốt có nghĩa là các số được tạo bởi thuật toán được phân phối đồng đều và không có số nào có xác suất xuất hiện cao hơn đáng kể so với các số khác. Các thuộc tính thống kê kém có thể tạo ra sai lệch không mong muốn trong kết quả.
Các properies hình học tốt có nghĩa là tập hợp N số không nằm trên một siêu phẳng trong không gian N chiều. Các đặc tính hình học kém có thể tạo ra các tương quan giả trong mô hình mô phỏng và làm sai lệch kết quả.
Một khoảng thời gian dài có nghĩa là bạn có thể tạo ra rất nhiều số trước khi chuỗi kết thúc ở đầu. Nếu một mô hình cần một số lượng lớn các lần lặp lại hoặc phải chạy từ một số hạt giống thì 2 ^ 30 hoặc các số rời rạc có sẵn từ một triển khai LCG điển hình có thể không đủ. Thuật toán MT19337 có khoảng thời gian rất dài - 2 ^ 19337-1, hoặc khoảng 10 ^ 5821. Để so sánh, tổng số nguyên tử trong vũ trụ được ước tính vào khoảng 10 ^ 80.
Số nguyên 32 bit được tạo bởi MT19337 PRNG không thể đại diện cho đủ các giá trị riêng biệt để tránh lặp lại trong một khoảng thời gian lớn như vậy. Trong trường hợp này, các giá trị trùng lặp có khả năng xảy ra và không thể tránh khỏi với một mẫu đủ lớn.
Tóm lại, Nghịch lý sinh nhật
Bài toán này ban đầu được định nghĩa là xác suất để hai người bất kỳ trong phòng có cùng ngày sinh. Điểm mấu chốt là bất kỳ hai người nào trong phòng đều có thể sinh nhật chung. Mọi người có xu hướng hiểu sai vấn đề một cách ngây thơ như xác suất một người nào đó trong phòng chia sẻ sinh nhật với một cá nhân cụ thể, đó là nguồn gốc của sự thiên vị nhận thức thường khiến mọi người đánh giá thấp xác suất. Đây là giả định không chính xác - không có yêu cầu đối với trận đấu phải dành cho một cá nhân cụ thể và bất kỳ hai cá nhân nào cũng có thể trùng khớp.
Xác suất trận đấu xảy ra giữa hai cá nhân bất kỳ cao hơn nhiều so với xác suất trận đấu với một cá nhân cụ thể vì trận đấu không nhất thiết phải đến một ngày cụ thể. Thay vào đó, bạn chỉ phải tìm hai cá nhân có cùng ngày sinh. Từ biểu đồ này (có thể được tìm thấy trên trang Wikipedia về chủ đề này), chúng ta có thể thấy rằng chúng ta chỉ cần 23 người trong phòng để có 50% cơ hội tìm thấy hai người trùng khớp theo cách này.
Từ mục nhập Wikipedia về chủ đề này, chúng ta có thể có được một bản tóm tắt tốt đẹp. Trong bài toán OP, chúng ta có 4.500 'sinh nhật' có thể xảy ra, thay vì 365. Đối với một số giá trị ngẫu nhiên nhất định được tạo (tương đương với 'người'), chúng ta muốn biết xác suất của bất kỳ hai giá trị giống nhau nào xuất hiện trong dãy.
Tính toán ảnh hưởng có thể xảy ra của Nghịch lý sinh nhật đối với vấn đề của OP
Đối với một chuỗi 100 số, chúng ta có
các cặp (xem phần Tìm hiểu vấn đề ) có khả năng khớp (tức là cặp đầu tiên có thể khớp với số thứ hai, thứ ba, v.v., cặp thứ hai có thể khớp với số thứ ba, thứ tư, v.v.), vì vậy số lượng kết hợp có thể phù hợp hơn là chỉ 100.
Từ Tính toán xác suất, chúng tôi nhận được một biểu thức của
. Đoạn mã Python sau đây thực hiện một đánh giá ngây thơ về xác suất xảy ra một cặp phù hợp.
from math import log10, factorial
PV=4500
SS=100
numerator = factorial (PV)
denominator = (PV ** SS) * factorial (PV - SS)
log_prob_no_pair = log10 (numerator) - log10 (denominator)
print 1.0 - (10 ** log_prob_no_pair)
Điều này tạo ra kết quả hợp lý là p = 0,669 cho một trận đấu xảy ra trong 100 số được lấy mẫu từ tập hợp 4500 giá trị có thể. (Có thể ai đó có thể xác minh điều này và đăng nhận xét nếu nó sai). Từ đó, chúng ta có thể thấy rằng độ dài của các lần chạy giữa các số phù hợp mà OP quan sát được có vẻ khá hợp lý.
Chú thích cuối trang: sử dụng xáo trộn để nhận một chuỗi các số giả ngẫu nhiên duy nhất
Hãy xem câu trả lời này dưới đây của S. Mark để biết phương tiện nhận được một bộ số ngẫu nhiên duy nhất được đảm bảo. Kỹ thuật mà người đăng đề cập đến lấy một mảng số (do bạn cung cấp, để bạn có thể biến chúng thành duy nhất) và xáo trộn chúng thành một thứ tự ngẫu nhiên. Việc vẽ các số theo thứ tự từ mảng xáo trộn sẽ cung cấp cho bạn một chuỗi các số giả ngẫu nhiên được đảm bảo không lặp lại.
Chú thích: PRNG bảo mật về mặt mật mã
Thuật toán MT không an toàn về mặt mật mã vì nó tương đối dễ dàng để suy ra trạng thái bên trong của bộ tạo bằng cách quan sát một chuỗi số. Các thuật toán khác như Blum Blum Shub được sử dụng cho các ứng dụng mật mã nhưng có thể không phù hợp với các ứng dụng mô phỏng hoặc số ngẫu nhiên chung. Các PRNG an toàn về mặt mật mã có thể đắt tiền (có thể yêu cầu tính toán bignum) hoặc có thể không có các đặc tính hình học tốt. Trong trường hợp của loại thuật toán này, yêu cầu chính là nó phải không khả thi về mặt tính toán để suy ra trạng thái bên trong của bộ tạo bằng cách quan sát một chuỗi giá trị.