【问题标题】:Uniform random numbers—don't include upper bound统一随机数——不包括上限
【发布时间】:2018-12-22 23:34:14
【问题描述】:

我想生成一些随机数,比如从minmax。问题是rand()[0, RAND_MAX] 范围内生成数字。将此缩放到 [min, max] 会导致每个数字的范围为 1,但 max 除外,它在 RAND_MAX 次中出现一次。如果我设定上限max + 1,我可能仍会得到max + 1 作为值。基本上,有没有办法使范围[min, max + 1)

这是我的一些代码:

int u_rand(int min, int max)
{
    return (int)((double)rand() / RAND_MAX * (max - min + 1)) + min; //has a chance to spit out max + 1
}

【问题讨论】:

标签: c


【解决方案1】:

您的方法不会产生均匀分布。最接近均匀分布的方法是使用模运算符%

int u_rand(int min, int max)
{
     return min + rand() % (max - min + 1);
}

同样,这不是完全统一的,而是相当接近和简单(假设您的范围 max - min 与 RAND_MAX 相比较小,并且 rand() 实现得很好)。

【讨论】:

  • 不会称之为“接近统一”。其实离它还很远。
  • @klutt 如果我们“假设”rand() 是一致的,那么如果与RAND_MAX 相比,范围 (max - min + 1) 较小,则该方法相当接近。这完全取决于 OP 的目标,即寻求简单性或准确的统一性。
  • 是的,这两个是两个非常关键的假设,如果你想声称你的函数生成“相当统一”的数字,你真的需要提到这一点。至少你需要提到,对于更大的范围,分布是可怕的。
【解决方案2】:

以下应提供来自 [min, max) 的随机数的均匀分布

int u_rand(int min, int max) {
    int threshold = RAND_MAX - RAND_MAX % (max - min);
    int num = rand();
    while (num >= threshold) {
        num = rand();
    }
    return num % (max - min) + min;
}

它会丢弃不能在 [min, max) 之间平均分配的部分范围,如果在此范围内选择了一个数字,它将改为绘制一个新数字,直到它在可接受的范围内得到一个。这确实意味着生成随机数需要多长时间没有硬性限制,但从统计上讲,它会优于确定性变体。注意我也避免在任何地方使用浮点运算,因此也没有由于舍入而产生的细微偏差。您的数字将与 rand() 提供的原始范围一样统一。

【讨论】:

  • 这看起来适用于我正在使用的数字,但如果 max > RAND_MAX 会起作用吗?
  • 仅当max - min <= RAND_MAX。我相信扩展支持范围的最简单方法是将调用rand() 替换为另一个函数,该函数将多次调用rand() 以产生更大的随机数,并将RAND_MAX 替换为适当的值。跨度>
  • 我不喜欢这个答案。当然,它会按照它所说的那样做,但是很少需要完美的一致性——通常,您实际上需要的只是在没有立即明显模式的范围内生成一堆数字.也就是说,这是一个很好的答案,它解释了它的作用,而且都是关于特定的均匀分布,所以不是 -1。只是建议添加“不过,您应该仔细检查是否需要统一性。很多用例不需要,如果您是其中之一,您可以通过删除 threshold 计算并检查来跳过它。”
【解决方案3】:

简答:删除+1

长答案:(max - min + 1) 计算您尝试获取数字的范围的宽度——也就是说,它跨越的数字的总数。有了这个,没有+ min,你会得到[0, max-min+1)中的数字。然后+ min 偏移从min 开始,所以你最终得到[min, max-min+1+min),又名[min, max+1),又名[min, max]。如果您想排除 max,请将范围的宽度缩小一倍,但偏移量相同:

(int)((double)rand() / RAND_MAX * (max - min)) + min

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    相关资源
    最近更新 更多