【问题标题】:C#: Random.NextDouble method stalling out applicationC#:Random.NextDouble 方法停止应用程序
【发布时间】:2020-11-27 06:56:23
【问题描述】:

我从Random.NextDouble() 收到了一些不一致的行为。

控制台通常会死机,cpu 使用率会急剧增加,直到我关闭它。我运行调试器,发现冻结的原因是Random.NextDouble()。我添加了一些用于调试目的的行,但代码如下:

        double generateCatenationRate()
        {
            double catenation = 999.999; //random value to see if it pops up down there
            double uniformValue;
            double int_covalence = covalence.original;
            double dist = int_covalence - 4;


            int counter = 0;
            while (true)
            {
                counter++;
                uniformValue = utils.getRandomDouble(); //goes bad here!
                if (uniformValue <= 0.15)
                {
                    catenation = Math.Abs(utils.normalize(dist, 0, 4)) + uniformValue;

                    if (catenation < 0 || catenation > 1)
                    {
                        if (counter > 10000)
                        {
                            Console.WriteLine("Went nuclear!");
                            break; //break so console doesn't stall out
                        }
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }

            }
            Console.WriteLine("Took "+counter+" iterations.");
                return 1 - catenation;
        }

还有:

        public static double getRandomDouble()
        {
            Init();
            return random.NextDouble();
        }

最后:

        private static void Init()
        {
            if (random == null) random = new Random();
        }

它通常不会停止,但连续运行几次会产生如下输出:

Took 4 iterations.
Took 3 iterations
Took 3 iterations.
Took 23 iterations.
Took 12 iterations.
Took 4 iterations.
Went nuclear!
Took 10007 iterations.

谁能解释为什么Random.NextDouble() 偶尔会造成无限循环?环顾四周,我怀疑这与价值观的播种方式有关,但任何见解都会受到赞赏;很想解决这个问题。

谢谢!

编辑: covalence.original 始终是 1 到 8(含)之间的整数。 normalize() 执行最小-最大归一化,根据输入和范围生成一个从 0 到 1 的数字。然而,这些似乎都不会导致问题。

【问题讨论】:

  • 你的normalize()方法是做什么的?
  • 那么covalence.original的值是多少?
  • 您可以使用调试器(在Console.WriteLine("Went nuclear!"); 行设置断点来检查distcatenation 的值,并可能在您的方法中找到缺陷。
  • 抱歉——请参阅编辑
  • 为什么不打印 uniformValue 的值,而您却在执行 Console.WriteLine("Went nuclear!"); ?然后你就会知道在调试器下用什么来测试它。

标签: c# .net visual-studio random mono


【解决方案1】:

如果我理解正确,那么 distutils.normalize(dist, 0, 4) 的值永远不会改变。
所以如果int_covalence = 8 那么dist = 4utils.normalize(dist, 0, 4) = 1,对吗?

由于生成0.0 的机会非常小,这将使catenation 几乎总是大于1 并且检查if (catenation &lt; 0 || catenation &gt; 1) 总是正确的。

【讨论】:

  • 我遗漏了一些代码,但 dist = 4 恰好有 12% 的时间,所以有时我不会注意到每当 utils.normalize(dist, 0, 4) = 1 它爆炸时。感谢您指出这一点——我需要停止尝试在凌晨 1 点之后进行编程:/
【解决方案2】:

为什么不直接生成样本而不是使用拒绝抽样?

    public static double generateCatenationRate(Random rng, double coval_norm) {
        double low = Math.abs(coval_norm) + 0.15;
        double delta = 1. - low;
        if (delta < 0) {
            throw new IllegalArgumentException("impossible given covalence");
        }
        return low + delta * rng.nextDouble();
    }

其中coval_norm 是您从utils.normalize 返回的任何内容。如果我们这样写,我们就能看到“不可能”的情况,并且可以做一些事情,而不仅仅是循环。

【讨论】:

    猜你喜欢
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 2011-08-19
    • 1970-01-01
    相关资源
    最近更新 更多