生成一个随机数,该数字不会偏向正的适当分数

时间:2013-03-14 10:05:42

标签: c# math probability

我为这个问题的简单性道歉,它刚刚过了凌晨3点,我想不到:)

我需要在0.25到10.0之间得到一个随机数n,但我需要P( 0.25 <= n < 1.0 ) == P( 1.0 < n <= 10.0 ) && n != 1.0

现在我的当前代码偏向1.0 <= n <= 10.0,如此:

Double n = new Random().NextDouble(); // 0 <= n <= 1.0
n = 0.25 + (10.0 * n);

当然,如果n == 10.25最初为n = 1.0,也会出现错误。

的Ta!

5 个答案:

答案 0 :(得分:4)

如果我理解正确,你想要这个:

var random = new Random();
Double n1 = random.NextDouble(); // 0 <= n < 1.0
Double n = random.NextDouble(); // 0 <= n < 1.0
if (n1 < 0.5)
    n = 0.25 + 0.75 * n; // 0.25 <= n < 1.0
else
    n = 10.0 - 9.0 * n; // 1 < n <= 10

答案 1 :(得分:1)

此功能应该有效:

double GetRandomValue(Random rand)
{
    return rand.Next(0, 2) == 0 
           ? 0.25 + 0.75 * rand.NextDouble() 
           : 10.0 - 9.0 * rand.NextDouble();
}

第一个随机值选择是否应使用低于或高于1的值。对于大于1的值,您希望在范围中包含10.0,因此减法。

答案 2 :(得分:0)

Double n = new Random().NextDouble(); // 0 <= n <= 1.0
Double extremlySmallValue = 0.00000001;
n *= 9.75; // 0 <= n <= 9.75
n += 0.25; // 0.25 <= n <= 10.0
//few ifs now:
if(n == 10.0)
    n -= extremlySmallValue;
else if (n==1.0)
    n += extremlySmallValue;

它不是完美的线性分布,但我认为它是可以接受的,因为Random也不能提供完美的线性分布。当你得到1.0或10.0时,你也可以制作另一个NextDouble()

答案 3 :(得分:0)

我认为就是这样。

Double n = new Random().NextDouble();
n = n < 0.5? (0.25 + (0.75 * n * 2)) : 1.0 + double.Epsilon + (9.0 * n * 2);

double.Epsilon确保您不会获得n=1.0,因为NextDouble()会生成0 <= n < 1.0

答案 4 :(得分:0)

你没有说出你想要在每个范围内分配什么,但是,假设你想要均匀性,只需将NextDouble范围的下半部分线性映射到较低范围,上半部分到顶部范围。

然而,需要一点点思考才能使目标间隔的半开放正确。 NextDouble会在[0, 1)中返回一个双精度数(即低包含和高排除)。我们可以将这一半分为[0, 0.5)[0.5, 1),但由于您所需的上限为(1, 10],我们应该在转换过程中翻转上限。

var n = myRandom.NextDouble();
if (n < 0.5)
{
    // Map from [0, 0.5) to [0.25, 1.0)
    return 0.25 + (n * 1.5);
}
else
{
    // Map from [0.5, 1.0) to (1.0, 10] by reversing the input range
    var flipped = 1.0 - n;
    // Now flipped is in [0.5, 0), which is to say (0, 0.5]
    // So scale up by 18 times to get a value in (0, 9], and shift
    return 1 + (flipped * 18);
}