2009-09-17 46 views
1

我一直在写一些C#代码进行训练练习,其中我必须创建一个随机矩形的数组。C中的随机数生成#

问题是由我的GetRandomRectangle函数生成的矩形总是相同的。 我正在使用System.Random来生成矩形的坐标。

我意识到这是因为Random对象是使用默认构造函数创建的,因此具有相同的种子。我已经修改它为每个矩形现在获得不同的种子,并且它工作正常。

问题是 - 它如何决定'默认种子'?我注意到它似乎也没有随着时间的推移而变化,使用种子2创建的矩形将始终具有相同的尺寸。

这可能是我可以谷歌的东西,但很高兴听到你们的意见和信息。

谢谢:)

+0

它是如何决定默认种子的?根据你的发现不是随机的! - 当然,没有像随机的东西,但这是一个完全不同的讨论。 – Bryan

+0

Duplicate:http:// stackoverflow。com/questions/807892/why-does-this-method-return-the-same-random-string-each-time – Guffa

+0

我意识到这个问题,并不认为它是重复的。该用户想知道他们的代码为什么不起作用。我知道这是因为种子,并且想知道更多关于随机数生成中使用的机制。 –

回答

11

默认种子是从系统时钟中获取的。

我在猜测你的GetRandomRectangle方法正在快速连续调用,并且每次都会立即调用一个新的Random实例。当你这样做时,Random的每个实例将从系统时钟中获取相同的种子,这就是为什么你的方法每次都会创建相同的矩形。

一种解决方案是创建实例的Random一个并传递到您的方法:

Random rng = new Random(); 

Rectangle foo = GetRandomRectangle(rng); 
Rectangle bar = GetRandomRectangle(rng); 
Rectangle baz = GetRandomRectangle(rng); 

// ... 

public Rectangle GetRandomRectangle(Random rng) 
{ 
    // create the rectangle using rng 
} 
+0

即使当我这样做时,我运行我的程序,然后关闭它,然后在几秒之间再次运行它,它似乎产生相同的一组矩形。有趣... –

+0

因为它使用时间戳作为种子。它应该使用tickcount来保证不会获得相同的种子。 –

+1

@cemkalyoncu:默认的'Random'构造函数使用'Environment.TickCount'作为种子。我认为这不是问题。 – LukeH

0

当您使用的种子,这意味着你想同样的顺序从种子开始

尝试没有种子的构造函数

1

实际上,默认的Random()构造函数是时间依赖的,应该在运行应用程序时提供不同的输出第二次。如果你每次都得到相同的矩形,其他的东西一定会发生。

手动提供种子将始终为您提供相同的伪随机数序列。

您应该只需要实例化一个单一的Random对象来生成所有的随机数。不要为每个矩形创建一个新的实例。

+0

@Thorarin:如果您快速连续创建多个Random类型的实例(例如,在一个紧密的循环中),那么它们将使用相同的种子:在这种情况下,系统时钟的速度不够快,不足以提供一个唯一的值每个实例。 – LukeH

+0

@Luke:因此我对使用单个实例发表评论。 – Thorarin

1

我也习惯使用它,但是我发现这个类的产生远没有足够的随机值。我转而使用加密命名空间中的随机函数。这里是一个非常简单的版本,没有错误检查或屏幕大小转换:

 byte[] randomBytes = new byte[4]; 
    RandomNumberGenerator numberGenerator = System.Security.Cryptography.RandomNumberGenerator.Create(); 
    numberGenerator.GetNonZeroBytes(randomBytes); 
    int x = randomBytes[0]; 
    int y = randomBytes[1]; 
    int width = randomBytes[2]; 
    int height = randomBytes[3]; 
    System.Drawing.Rectangle block = new Rectangle(x, y, width, height); 
+3

随机类生成足够用于大多数用途的随机数,如果正确使用它的话。只有在需要非常好的随机性时才需要密码随机生成器,例如创建加密密钥。 – Guffa

0

林没有C#专家,但这个可能会奏效。

public Rectangle GetRandomRectangle() 
{ 
     static Random rng=new Random(); 
     // create the rectangle using rng 
}