【问题标题】:c++ random numbers, evenly distributedc++随机数,均匀分布
【发布时间】:2021-12-28 01:59:48
【问题描述】:

我需要在 c++ 中生成两个值之间的随机数,可以这样生成(范围 1 到 6) :

#include <iostream>
#include <random>

int main(int argc, char* argv[]){
 srand(time(NULL));

for (int j = 0; j < 6 ; j++) {
    randomNumber = rand() % 6 + 1;
    cout << randomNumber;

return 0;
}

但我还需要确保它对范围内的每个数字至少生成一次,例如:范围[1,6],则必须至少生成一次 1,2,3,4,5 和 6。

还有一点,生成的数字必须是均匀分布的,比如如果要在[1,6]范围内生成20次迭代,每个数字(1,2,3,4,5,6)应该有在 20 次迭代中产生的数量大致相同。示例:1,3,5,2,4,6,2,4,6,1,3,5,6,5,4,3,5,2,1.... 而不是这样:1, 3,5,6,6,6,2,6,4,4,4,4,4,4...

如果有人知道如何解决这个问题,我将非常感谢你。 谢谢!!!

【问题讨论】:

  • 将所有数字添加到容器中是否有效,然后从容器中获取数字,如果你用完就重新洗牌吗?还有另一个数学问题可以做到这一点,但我不记得它的名字了
  • 我认为你可以使用一个 int 向量,将你想要的所有数字添加为输出,然后将向量中的元素打乱,最后从末尾检索它们
  • 如果你想保证所有号码都会出现,这不是随机的。
  • 添加前请阅读标签说明,generate 标签是关于名为 Generate 的框架,与本题无关。
  • coliru.stacked-crooked.com/a/d4fadd1893f7893d 据我所知,这种做你想做的事,但它不是真正随机的。

标签: c++ random numbers


【解决方案1】:

这就是 C++ 标准库的用武之地。在我的脑海中输入:

#include <random>

int get_rand_in_1_6()
{
  static std::random_device rnd;
  return std::uniform_int_distribution <int> ( rnd )( 1, 6 );
}

结果将均匀分布。

(不过,您可能不会在前六次迭代中得到每一个。均匀分布并不能保证任何特定子区间内的任何特定值,只是该数字同样可能和其他任何出现一样。如果有足够的迭代次数,你会看到的。)

[编辑 2]:IDR 最小迭代次数的精确数学公式,以保证您至少看到每个数字一次 - 我疯狂地猜测大约 15 次拉动以保证这一点。

【讨论】:

  • 感谢@Dúthomhas
  • 对于包含所有结果的最小拉取次数没有保证,至少有一个您没有看到的值的概率在数学上非零适用于所有样本量。然而,它很快变得如此接近于零,以至于没有人会关心。有点像房间里的所有空气分子同时冲到一个角落的概率——理论上它可能发生,但我认识的人都不担心会因此窒息。
【解决方案2】:

如果我理解正确,std::shuffle 可能会对您有所帮助:

std::random_device rd;
std::mt19937 gen(rd());
int numbers[] = {1, 2, 3, 4, 5, 6};

for (int j = 0; j < 20 ; j++) {
    if (j % 6 == 0) { std::shuffle(numbers, numbers + 6, gen); }
    std::cout << numbers[j % 6];
}

Demo

然后你就有了随机排列的序列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多