Xem xét một thuật toán để kiểm tra xác suất mà một số nhất định được chọn từ một tập hợp N số duy nhất sau một số lần thử cụ thể (ví dụ, với N = 2, xác suất trong Roulette (không 0) là bao nhiêu cố gắng cho Black để giành chiến thắng?).Máy phát điện số ngẫu nhiên libc thiếu sót?
Phân bố chính xác cho điều này là pow (1-1/N, X-1) * (1/N).
Tuy nhiên, khi tôi kiểm tra điều này bằng cách sử dụng mã sau, luôn có một rãnh sâu tại X = 31, độc lập với N và độc lập với hạt giống.
Đây có phải là một lỗ hổng nội tại không thể ngăn chặn do các chi tiết cụ thể của PRNG đang sử dụng, đây có phải là lỗi thực sự hay tôi nhìn thấy điều gì đó hiển nhiên?
// C
#include <sys/times.h>
#include <math.h>
#include <stdio.h>
int array[101];
void main(){
int nsamples=10000000;
double breakVal,diffVal;
int i,cnt;
// seed, but doesn't change anything
struct tms time;
srandom(times(&time));
// sample
for(i=0;i<nsamples;i++){
cnt=1;
do{
if((random()%36)==0) // break if 0 is chosen
break;
cnt++;
}while(cnt<100);
array[cnt]++;
}
// show distribution
for(i=1;i<100;i++){
breakVal=array[i]/(double)nsamples; // normalize
diffVal=breakVal-pow(1-1/36.,i-1)*1/36.; // difference to expected value
printf("%d %.12g %.12g\n",i,breakVal,diffVal);
}
}
Thử nghiệm trên một up-to-date Xubuntu 12.10 với libc6 gói 2.15-0ubuntu20 và Intel Core i5-2500 SandyBridge, nhưng tôi phát hiện này đã là một vài năm trước đây trên một máy tính Ubuntu cũ.
Tôi cũng đã thử nghiệm điều này trên Windows 7 bằng Unity3D/Mono (không chắc chắn phiên bản Mono nào), và ở đây mương xảy ra ở X = 55 khi sử dụng System.Random, trong khi Unity's Unity.Random không có mương nhìn thấy được (ít nhất là không cho X < 100).
Sự phân bố:
Sự khác biệt:
Tôi không nghĩ bất cứ ai tuyên bố rằng các chức năng ngẫu nhiên trong glibc đặc biệt là "chất lượng cao" .Nếu bạn muốn một cái gì đó tốt hơn, sau đó sử dụng Mersenne Twister hoặc một số "chuyên nghiệp cấp" RNG.Cái được cung cấp bởi các thư viện C [và các thư viện tương tự khác] có xu hướng được viết cho sự đơn giản, không phải là "sự hoàn hảo". –
1) chính nên trả về int 2) modulo 36 là nghi ngờ, tôi đề nghị bạn đầu tiên thử modulo 32, hoặc sức mạnh khác của hai. – wildplasser
Tôi có thể xác nhận hành vi này (Debian Sid) cho cả hai modulo 36 và 32. – liori