【问题标题】:Trouble with C# Random classC# Random 类的问题
【发布时间】:2010-09-25 01:19:01
【问题描述】:

我有一个代表硬币的类,可以使用 Coin.Flip() 方法翻转它。 Flip() 使用 random.Next(2);获得代表正面或反面的 0 或 1。这很好用.. 有点。

对于该程序,我需要制作 2 个硬币,比如说 coin1 和 coin2。

coin2 总是需要在 coin1 之后直接翻转,我可以这样做:

coin1.Flip();
coin2.Flip();

应该可以吧?

好吧,它没有!每次我运行这两行代码时,两个硬币的值都相同!

面值存储在Coin类里面的face中,定义如下:

private int face;

我没有发现我所做的事情有任何问题,但是每次我运行代码时,它们最终都是相同的。

哦,还有,在 Coin 类中定义随机也是这样:

private Random random = new Random();

感谢您的帮助!

编辑:这里是 Flip(),虽然 random 是静态的,但它现在可以工作了。

    public void Flip() {
        face = random.Next(2);
    }

【问题讨论】:

  • 你能展示一下 Flip 的实现吗?
  • 注意:如果将其设为静态,您还应该同步它或使其特定于线程,因为它未列为线程安全

标签: c# random


【解决方案1】:

随机数生成器需要一个种子值。具有相同种子的 RNG 将产生相同的随机数流。

默认情况下,System.Random 使用当前时间作为种子。如果您几乎立即创建两个实例,它们可能都具有相同的时间值,因此会产生相同的随机数序列。

您可以将 Random 移动到静态成员,以便所有 Coin 共享相同的 RNG,但请注意 System.Random 未记录为线程安全,因此您不能在没有同步的情况下在不同线程上使用多个 Coin。

【讨论】:

  • 谢谢伙计,我在发帖后就在考虑这个问题。会试一试。
  • 这样好多了。再次感谢!
  • 为你的 Coin() 创建一个重载可能是个好主意,它允许你传入一个随机流,并且默认构造函数采用静态随机流。这样,您可以通过为每个线程创建单独的 rng 来解决任何同步问题
  • 我对所有的术语都不是很好,但是我阅读你的评论的方式是这样的:每当我想要一个新的 RNG 时使用重载版本,并在我需要时使用标准构造函数使用已经创建的 RNG。我不是多线程,所以我认为我不需要这样做,只是想了解一下。谢谢!
【解决方案2】:

我的猜测是,您可能想在类级别重新定义您的 random 变量:

private static Random random = new Random();

这将使对Flip() 的每次调用都使用相同的生成器,而不是不断地重新设置种子。如果您在每次调用时都创建 Random 实例,并且两次调用非常接近,那么您可能会获得相同的种子,从而获得相同的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2011-08-20
    • 2021-11-21
    • 2016-03-11
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多