C#:Random.NextDouble 方法停止应用程序
C#: Random.NextDouble method stalling out application
我从 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()
执行最小-最大归一化,根据输入和 运行ge 生成 0-1 的数字。但是,这些似乎都不会导致问题。
如果我理解正确,那么 dist
和 utils.normalize(dist, 0, 4)
的值永远不会改变。
所以如果 int_covalence = 8
那么 dist = 4
和 utils.normalize(dist, 0, 4) = 1
,正确吗?
由于生成 0.0
的机会非常小,这将使 catenation
实际上总是大于 1
并且检查 if (catenation < 0 || catenation > 1)
总是正确的。
为什么不直接生成样本而不是使用拒绝抽样?
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
返回的任何内容。如果我们这样写,我们就可以看到“不可能”的情况,并且可以做一些事情,而不仅仅是循环。
我从 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()
执行最小-最大归一化,根据输入和 运行ge 生成 0-1 的数字。但是,这些似乎都不会导致问题。
如果我理解正确,那么 dist
和 utils.normalize(dist, 0, 4)
的值永远不会改变。
所以如果 int_covalence = 8
那么 dist = 4
和 utils.normalize(dist, 0, 4) = 1
,正确吗?
由于生成 0.0
的机会非常小,这将使 catenation
实际上总是大于 1
并且检查 if (catenation < 0 || catenation > 1)
总是正确的。
为什么不直接生成样本而不是使用拒绝抽样?
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
返回的任何内容。如果我们这样写,我们就可以看到“不可能”的情况,并且可以做一些事情,而不仅仅是循环。