C#和Java之间的随机行为差异:种子

时间:2009-04-11 14:31:45

标签: c# java math

我在一个类中有一个Random,它旨在在不同的上下文中生成随机序列:这是从Java代码移植的结果。 在Java版本中,一切正常,因为java.lang.Random类具有方法setSeed,它允许动态更改种子值。

Random rnd = new Random();
...
rnd.nextInt();
...
rnd.setSeed(seedValue);

这会生成一致的结果,因为每次设置种子值时,结果都是随机的。

不幸的是,在C#中,行为有很大不同,因为Random类需要在构造时设置种子:

Random rnd = new Random(seedValue);
...
rnd.Next();
...

因此,我每次都必须使用给定的种子构建一个新的Random实例,在某些备用情况下,它会生成与之前调用相同的值。

是否可以动态地在C#中设置Random实例的种子,而不会丢失全局实例的一致性?

非常感谢!

3 个答案:

答案 0 :(得分:1)

通常我为我的应用程序创建一个Random实例,在实例化后设置种子可以依赖于每次调用Next给我一个新的随机数。诀窍是确保种子尽可能随机。在C#应用程序中使用Random是一个很好的例子,说明Singleton非常适合。

有多种方法可以在种子中获得不同的随机性优势,并且有一些很好的SO问题可以解决这个问题。

以下示例是我使用的方法。

m_randomURL = "https://www.random.org/cgi-bin/randnum?num=1&min=1&max=1000000000";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m_randomURL);
StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
Random rand = new Random(Convert.ToInt32(stIn.ReadToEnd()));

random.org使用大气噪声产生随机性,显然用于彩票等。

答案 1 :(得分:0)

尝试将Random实例包装为伪代码:

class MyRandom {
   private Random random;

   public void setSeed(long seed) {
        random = new Random(seed);
        ...

   public long next() {
        return random.next();

答案 2 :(得分:0)

首先,我不希望setSeed在运行时期间在Random上多次调用Random FreeCell 这样做是为了让你可以通过写下使用的种子来“加载”游戏实例。

如果您更改种子,它应该像重置 Random实例,因此如果您重新注册它应该没有冲突。 class MyRandom { private Random random = new Random(DateTime.Now.Ticks); public void setSeed(long seed) { random = new Random(seed * this.random.next()); ... public long next() { return random.next(); } class MyClass { private MyRandom random = new MyRandom(); public void Test() { random.setSeed(seedValue); int x = random.next(); random.setSeed(seedValue); int y = random.next(); // x,y will be different in most of the cases now } } 只是基础算法的包装器。

如果你想每次都收到不同的结果(即使你使用setSeed),你可以试试这个:

{{1}}

这将改变随机生成器的种子应该如何工作的前/后条件,但可能适合你。