我为这个问题的简单性道歉,它刚刚过了凌晨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!
答案 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);
}