2010-04-28 74 views
9

Xin chào, tôi đang gặp một số sự cố khi tạo các số ngẫu nhiên với C# Bây giờ tôi có chức năng này.Cuộc gặp gỡ ngẫu nhiên không quá ngẫu nhiên

public Color getRandomColor() 
{ 
    Color1 = new Random().Next(new Random().Next(0, 100), new Random().Next(200, 255)); 
    Color2 = new Random().Next(new Random().Next(0, 100), new Random().Next(200, 255)); 
    Color3 = new Random().Next(new Random().Next(0, 100), new Random().Next(200, 255)); 
    Color color = Color.FromArgb(Color1, Color2, Color3); 
    Console.WriteLine("R: " + Color1 + " G: " + Color2 + " B: " + Color3 + " = " + color.Name); 
    return color; 
} 

Bây giờ bạn có thể nhận thấy rằng có ALOT ngẫu nhiên mới() ở đó, đó là vì tôi muốn loại bỏ xác suất có thể là lỗi giống nhau.

Tôi hiện đang chạy chức năng này 8 lần, một vài lần. Bây giờ, đây là những điều đặt ra.

R: 65 G: 65 B: 65 = ff414141 
R: 242 G: 242 B: 242 = fff2f2f2 
R: 205 G: 205 B: 205 = ffcdcdcd 
R: 40 G: 40 B: 40 = ff282828 
R: 249 G: 249 B: 249 = fff9f9f9 
R: 249 G: 249 B: 249 = fff9f9f9 
R: 94 G: 94 B: 94 = ff5e5e5e 
R: 186 G: 186 B: 186 = ffbababa 

R: 142 G: 142 B: 142 = ff8e8e8e 
R: 190 G: 190 B: 190 = ffbebebe 
R: 19 G: 19 B: 19 = ff131313 
R: 119 G: 119 B: 119 = ff777777 
R: 119 G: 119 B: 119 = ff777777 
R: 75 G: 75 B: 75 = ff4b4b4b 
R: 169 G: 169 B: 169 = ffa9a9a9 
R: 127 G: 127 B: 127 = ff7f7f7f 

R: 73 G: 73 B: 73 = ff494949 
R: 27 G: 27 B: 27 = ff1b1b1b 
R: 125 G: 125 B: 125 = ff7d7d7d 
R: 212 G: 212 B: 212 = ffd4d4d4 
R: 174 G: 174 B: 174 = ffaeaeae 
R: 0 G: 0 B: 0 = ff000000 
R: 0 G: 0 B: 0 = ff000000 
R: 220 G: 220 B: 220 = ffdcdcdc 

Như bạn có thể thấy điều này không phải ngẫu nhiên một lần nữa, nhưng tại sao liều này lại xảy ra? và làm thế nào tôi có thể chống lại nó?

+0

Tôi đã có cùng một vấn đề này tạo ra các màu ngẫu nhiên trong một phạm vi chuẩn hóa. Cách nhanh chóng mà không cung cấp hạt giống là để hoán đổi một vài giá trị với nhau bằng cách sử dụng cùng một luồng ngẫu nhiên. Thiếu độ chính xác nhưng có thể được sử dụng để phân phối ngẫu nhiên nhiều hơn một chút. Ví dụ: int x = rng.Next()^rng.Next(); int magnitude = x * x; giá trị float = x/(float) độ lớn; –

+0

Sử dụng phương pháp này, bạn có thể tạo phân phối màu tốt hơn một chút bằng cách sau. Màu = color = new Màu ( (byte) (rand.Next (0, 255)^rand.Next (0, 255)), (byte) (rand.Next (0, 255)^rand.Next (0, 255)), (byte) (rand.Next (0, 255)^rand.Next (0, 255)), (byte) (rand.Next (0, 255)^rand.Next (0 , 255))) –

Trả lời

28

Bạn đang tạo một Random mới cho mỗi giá trị bạn cần.

Thử tạo đối tượng Random duy nhất và gọi hàm .Next() nhiều lần.

public Color getRandomColor() 
{ 
    Random rand = new Random(); 

    Color1 = rand.Next(rand.Next(0, 100), rand.Next(200, 255)); 
    Color2 = rand.Next(rand.Next(0, 100), rand.Next(200, 255)); 
    Color3 = rand.Next(rand.Next(0, 100), rand.Next(200, 255)); 
    Color color = Color.FromArgb(Color1, Color2, Color3); 
    Console.WriteLine("R: " + Color1 + " G: " + Color2 + " B: " + Color3 + " = " + color.Name); 
    return color; 
} 

Taken từ MSDN documentation on Random object:

Theo mặc định, các nhà xây dựng parameterless của lớp Random sử dụng đồng hồ hệ thống để tạo ra giá trị hạt giống của nó, trong khi nhà xây dựng tham số của nó có thể mất một giá trị Int32 dựa trên số ve trong thời điểm hiện tại. Tuy nhiên, vì đồng hồ có độ phân giải hữu hạn, sử dụng hàm tạo tham số để tạo các đối tượng ngẫu nhiên khác nhau trong kế tiếp tạo các trình tạo số ngẫu nhiên tạo ra các dãy số ngẫu nhiên giống nhau

+4

Đúng, đây là câu trả lời. Các trường hợp ngẫu nhiên được tạo ra rất nhanh chóng sau khi cái kia có khuynh hướng đưa ra cùng một giá trị. Tôi cho rằng điều này là bởi vì họ nhận được hạt giống của đồng hồ máy tính, nhưng đó là không có gì nhiều hơn phỏng đoán hoang dã. –

+1

Chính xác. Random có ​​2 hàm tạo. Một tham số không mất sử dụng thời gian hiện tại như hạt giống. Bạn cũng có thể sử dụng một số nguyên. Vì vậy, nó sẽ sử dụng đối số bạn vượt qua như hạt giống. – emzero

+0

Mã của tôi trông giống như trong phần bắt đầu, chúng tôi đã tạo ra nhiều ví dụ để xem liệu trình trợ giúp đó có phải không. Nhưng bây giờ chúng tôi nhận được R: 164 G: 78 B: 145 = ffa44e91 R: 206 G: 20 B: 149 = ffce1495 R: 206 G: 20 B: 149 = ffce1495 R: 73 G: 60 B: 94 = ff493c5e R: 147 G: 94 B: 101 = ff935e65 R: 212 G: 123 B: 61 = ffd47b3d R: 98 G: 79 B: 70 = ff624f46 R: 85 G: 110 B: 79 = ff556e4f Nó ngẫu nhiên hơn một chút, nhưng nếu bạn thấy kết quả 2 và 3 thì chúng giống nhau. – Androme

1

Ngẫu nhiên hoạt động tốt hơn khi sử dụng một trường hợp.

Hãy thử điều này: đối tượng

public Color getRandomColor() 
{ 
    var random = new Random(); 
    Color1 = random.Next(random.Next(0, 100), random.Next(200, 255)); 
    Color2 = random.Next(random.Next(0, 100), random.Next(200, 255)); 
    Color3 = random.Next(random.Next(0, 100), random.Next(200, 255)); 
    Color color = Color.FromArgb(Color1, Color2, Color3); 
    Console.WriteLine("R: " + Color1 + " G: " + Color2 + " B: " + Color3 + " = " + color.Name); 
    return color; 
} 
+0

Chỉnh sửa mọi thứ nhưng chậm hơn so với sử dụng một ngẫu nhiên đơn lẻ là gì? Chắc chắn nó không 'ngẫu nhiên hơn'? – Will

+1

Nó thậm chí sẽ giúp trả về cùng một màu "ngẫu nhiên" mỗi khi hàm được gọi. – Miles

5

Bạn đang tạo nhiều ngẫu nhiên liên tục, khiến chúng được gieo với cùng/gần như timestamp cùng. Do đó tạo ra các số ngẫu nhiên nhưng bằng nhau trong số đó.

Hãy thử tạo một trường hợp ngẫu nhiên và sử dụng cho tất cả các số ngẫu nhiên của bạn.

7

Mỗi new Random()seeded with the current time.

Nếu bạn tạo một số trường hợp Random liên tiếp nhanh chóng và máy của bạn chạy đủ nhanh để chúng đủ gần nhau để lấy cùng một hạt giống, chúng sẽ trả lại cùng một chuỗi giá trị!

Sử dụng một đơn Random, gọi .Next() để nhận được từng giá trị.

Bây giờ bạn có thể nhận thấy rằng có những ALOT của Random mới() có, đó là bởi vì tôi muốn để loại bỏ các khả năng mà nó có thể là cùng một lỗi dụ.

Đây là sai lầm; một dòng các số từ một đơn Random được phân bố đều - nỗ lực đã biến nó thành ngẫu nhiên.