2012-04-28 5 views
23

Không chắc chắn cách khác để giải thích điều này, vì vậy tiêu đề mô tả khá nhiều vấn đề.Tại sao System.Random cho '1' nhiều lần liên tiếp, sau đó không phải trong một thời gian, sau đó một lần nữa?

Ngẫu nhiên không được khởi tạo lại mọi phần của vòng lặp. Đó là một thành viên tĩnh của một lớp mà tôi luôn luôn gọi từ các lớp khác.

Tôi không sử dụng hạt giống tùy chỉnh.

Mã khởi động là:

public static Random random = new Random(); 

     for (int x = 0; x < 75; x++) 
     { 
      if (main.random.Next(11) == 1) 
      { 
       tiles[heightMap[x] - 1][x] = 4; 
       tiles[heightMap[x] - 2][x] = 4; 
       tiles[heightMap[x] - 3][x] = 4; 
       tiles[heightMap[x] - 4][x] = 4; 
       tiles[heightMap[x] - 5][x] = 4; 
       tiles[heightMap[x] - 5][x - 1] = 5; 
       tiles[heightMap[x] - 6][x - 1] = 5; 
       tiles[heightMap[x] - 6][x] = 5; 
       tiles[heightMap[x] - 5][x + 1] = 5; 
       tiles[heightMap[x] - 6][x + 1] = 5; 
      } 
     } 

này (Tôi biết đây không phải là một cách tuyệt vời - đó là thô sơ và tạm thời) tạo ra một cái cây.

Tuy nhiên địa hình của tôi thường trông giống như thế này, với nhiều cây nhóm:

☁☁☁☁☁☁☁☁☁☁

bất cứ ai có thể đưa ra cái nhìn sâu sắc tại sao điều này đang xảy ra? Có cách nào tốt hơn thay vì sử dụng lớp System.Security.Cryptography.Random?

Tôi mong đợi trung bình 9 khoảng cách trên mỗi cây, nhưng nó giống như 7 và sau đó 3 cây chặt chẽ với nhau.

enter image description here

+15

http://dilbert.com/strips/comic/2001-10 -25/ –

+0

Truyện tranh đẹp, rất đúng. :( –

+3

Ngẫu nhiên không có nghĩa là thay đổi thường xuyên trong các kết quả thay thế. Theo thời gian, trình tự như thế này được phân bố đồng đều. – codekaizen

Trả lời

35

Đây là một sự hiểu lầm xác suất; tất cả các bạn biết là tại bất kỳ điểm, cơ hội nhận được một cây trong khe tiếp theo là, giả sử phân bố đồng đều, 1 trong 11.

do đó Cơ hội nhận được một khoảng cách từ 0 là 1/11

cơ hội nhận được một khoảng cách trên 1 là do 10/11 * 1/11

cơ hội nhận được một khoảng cách 2 là như vậy, 10/11 * 10/11 * 1/11

vv

Tất cả 10/11 thêm đó (tốt, nhân) lên! Vì vậy, chúng ta hãy viết một tiện ích:

decimal accountedFor = 0M; 
for (int i = 0; i <= 20; i++) 
{ 
    decimal chance = 1M/11M; 
    for (int j = 0; j < i; j++) chance *= 10M/11M; 
    accountedFor += chance; 
    Console.WriteLine("{0:00}: {1:00.0%}\t({2:00.0%})", i, chance, accountedFor); 
} 

Mà cho:

00: 09.1%  (09.1%) 
01: 08.3%  (17.4%) 
02: 07.5%  (24.9%) 
03: 06.8%  (31.7%) 
04: 06.2%  (37.9%) 
05: 05.6%  (43.6%) 
06: 05.1%  (48.7%) 
07: 04.7%  (53.3%) 
08: 04.2%  (57.6%) 
09: 03.9%  (61.4%) 
10: 03.5%  (65.0%) 
11: 03.2%  (68.1%) 
12: 02.9%  (71.0%) 
13: 02.6%  (73.7%) 
14: 02.4%  (76.1%) 
15: 02.2%  (78.2%) 
16: 02.0%  (80.2%) 
17: 01.8%  (82.0%) 
18: 01.6%  (83.6%) 
19: 01.5%  (85.1%) 
20: 01.4%  (86.5%) 

điều này giải thích sự thiên vị cho những khoảng trống nhỏ. Chú thích; vào thời điểm chúng tôi đạt đến khoảng cách 20, chúng tôi đạt dưới 1,5% cơ hội lãnh thổ và chiếm 85% tất cả các kết quả có thể - 15% còn lại sẽ được trải rộng trong phần còn lại của vô hạn (nghĩa là khoảng cách kích thước 13212 là có thể, nhưng rất khó xảy ra).

Vì vậy, đây là một mô phỏng:

int[] gapCounts = new int[21]; 

int gap = 0; 
// simulate a few gaps using your algo 
var random = new Random(); 
for (int x = 0; x < 100000; x++) 
{ 
    if (random.Next(11) == 1) 
    { // count that gap 
     gapCounts[gap]++; 
     gap = 0; 
    } 
    else 
    { 
     gap++; 
     if(gap >= gapCounts.Length) 
     { // just skip anything too large, sorry 
      gap = 0; 
     } 
    } 
} 

decimal total = gapCounts.Sum(); 
for(int i = 0 ; i < gapCounts.Length ; i++) 
{ 
    Console.WriteLine("{0:00}: {1:00.0%}", i, gapCounts[i]/total); 
} 

với sản lượng gì mà những giá trị này sẽ thay đổi mỗi chạy:

00: 11.0% 
01: 09.4% 
02: 08.6% 
03: 07.9% 
04: 07.3% 
05: 06.5% 
06: 05.4% 
07: 05.4% 
08: 04.7% 
09: 04.5% 
10: 04.4% 
11: 03.4% 
12: 03.5% 
13: 03.0% 
14: 02.9% 
15: 02.4% 
16: 02.5% 
17: 02.2% 
18: 01.9% 
19: 01.5% 
20: 01.7% 
+0

Câu trả lời rất hay, kudo. – yamen

+0

Có, hiển thị phiên bản tích lũy đang chạy ở trên, nó sẽ được khai sáng. – yamen

+0

Nhưng nó có vẻ nghiêng rất nhiều về phía 1 và 7, trong khi các con số như 2 rất hiếm khi được chọn (Trong một chuỗi gồm 75 số, 2 chỉ được chọn bốn lần, và tôi nhận được kết quả này rất nhiều). Nó cũng có vẻ rất phổ biến để có được ba 7 trong một hàng, và sau đó không phải bất kỳ 7 trong một thời gian rất dài. Đây không chỉ là một lần chạy, tôi nhận được rất nhiều mẫu tương tự như ba lần xuất hiện 7 và hiếm hoi đó. Từ quan điểm toán học, tôi có thể thấy bạn đến từ đâu, nhưng tôi chỉ nghĩ đó là lớp .NET System.Random không có thuật toán đủ tốt. –