【问题标题】:Get seed of Random object without passing in the seed?在不传递种子的情况下获取随机对象的种子?
【发布时间】:2014-06-14 15:39:56
【问题描述】:

随机对象是否总是包含种子,即使没有给定种子?如果可以,可以get这个种子吗?

动机: 我希望我的程序是随机的,但我希望能够随时重现它。我目前所做的是生成一个随机数,将其存储并将其作为种子放入我用于实际程序的另一个随机对象中。这样,如果我想复制任何东西,我就可以查找生成的种子。

我想知道 JavaC# 的这一点,因为它们是我的主要语言,这个问题让我在两种语言中工作过几次。

【问题讨论】:

  • 您当前的方法是一个很好的方法。种子用于在 ​​RNG 中生成更大的状态集 - 并且该状态通常可见。
  • 对于.NET,网上资料(referencesource.microsoft.com/#mscorlib/system/…)显示它使用Environment.TickCount来初始化随机对象,但是没有办法取回值。

标签: java c# random


【解决方案1】:

如果您不为随机构造函数提供种子,则会为您隐式生成种子。要设置种子并在代码中的其他位置再次使用它或重现任何内容,请尝试以下操作:

long seed = System.currentTimeMillis();
Random rand = new Random(seed);
System.out.println(seed);

【讨论】:

  • 这其实很有趣,简单,有效,高效。
  • 这就是你在 Java 中可以做到的。不确定 C#,因为我是 Java 开发人员。希望对你有帮助
  • 很难选择获胜的答案,我想你可以使用代表而不是@Douglas :)。答案几乎是一样的。
  • 是的,使用的算法几乎相同。唯一的区别是用于实现结果的语言。现在刚刚检查了他的答案:) 谢谢
  • @JeeshuMittal:这个答案是在我之前发布的,鉴于两者都满足您的要求,那么我同意选择这个作为接受的答案。
【解决方案2】:

要从 C# 的角度回答您的第一个问题,只需查看文档 - MSDN。对于Random classes 无参数构造函数,它说:

使用与时间相关的默认种子值初始化 Random 类的新实例

是的,如果您不提供种子,运行时将使用默认种子。

再次,查看文档,您会发现如果不提供种子,您将找不到使用的种子。

至于希望能够始终如一地产生随机数,您可以创建一个 IRandomNumberGenerator 接口并创建 2 个实现。一个会调用Random 类,另一个可以用于测试目的,并且会简单地返回你想要的任何东西。然后你可以使用依赖注入来控制使用哪个实现。

【讨论】:

  • 谢谢,但我不是在寻找双重实现。我只是不希望任何用户在那里放置自己的种子,但如果我出于某种原因需要或想要复制我希望能够。所以在所有情况下,我都需要能够知道种子。看到其他 cmets 和答案,看起来我已经以正确的方式做。
  • 虽然您确实可以使用 Environment.TickCount 作为默认种子,但它没有记录在案,这意味着您依赖于实现细节。您可能 99.9999% 确信这个细节永远不会改变,但不能保证它不会改变。
【解决方案3】:

对于C#,没有简单的方法可以从已经初始化的对象中获取种子。做你想做的事情的最好方法是按照你已经在做的方式去做(生成种子,保存它,然后在新的 Random 对象中使用它)。

另一种可能性是在 Random 对象的(隐式)初始化之后保存其二进制序列化版本。这样,虽然您没有种子,但您仍然可以重新生成相同的“随机”数字序列。

来源:documentationStackOverflow question

老实说,我非常怀疑 Java 是否有办法做到这一点,因为它会(至少在我的拙见中)是一种安全漏洞。

【讨论】:

    【解决方案4】:

    在 .NET Framework 中,调用Random() 构造函数等同于调用Randoom(Environment.TickCount)。因此,您可以通过自己读取(和存储)Environment.TickCount,然后根据该值初始化您的 Random(int) 来满足您的要求。

    因此,而不是调用:

    Random myRandom = new Random();
    

    你可以使用:

    int seed = Environment.TickCount;
    // optionally store seed for later reuse
    Random myRandom = new Random(seed);
    

    【讨论】:

    • 所以 int seed = Environment.TickCount;随机(种子)基本上是我要求的?可能会有一两个毫秒的差异,但我可以接受。
    • @MennoGouw:是的。除了将种子存储在外部(例如将其写入磁盘)之外,不会有任何性能差异(至少,绝对不是毫秒级的)——JIT 编译器可能会为两个初始化生成相同的代码。跨度>
    猜你喜欢
    • 1970-01-01
    • 2021-12-18
    • 2017-02-01
    • 2018-07-29
    • 2011-09-06
    • 2021-12-11
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    相关资源
    最近更新 更多