如何在C ++中生成统一的随机整数而不重复

时间:2015-12-30 10:28:24

标签: c++ g++ visual-studio-2015

我想生成一个随机整数,它遵循均匀分布而不重复。例如,我将通过此代码生成6个统一编号

 vector<int> container;
 container.reserve(lossNum);
 std::vector<unsigned int>::iterator it;
 // Our Random Generator
 std::mt19937 eng{ std::random_device{}() };
 int max_num=6
 for (int i = 0; i<max_num; i++) {
     unsigned int q = std::uniform_int_distribution<unsigned int>{ 0, max_num }(eng);

     do {
         q = std::uniform_int_distribution<unsigned int>{ 0, max_num }(eng);
         it = std::find(container.begin(), container.end(), q);
     } while (it != container.end());

     container.push_back(q);
 }

我运行代码120.000时间并绘制图形。但该数字并未显示均匀分布。我的代码有什么问题?我正在使用visual studio 2015来运行它。

另外,如果我在linux(Ubuntu)环境中运行。如何修改标准C ++的上述代码?感谢

enter image description here

这是我的代码

2 个答案:

答案 0 :(得分:4)

  1. 代码示例
  2. 看看你的代码,看起来你重新发明轮子。 MSVC 2015应支持std::shuffle,因此您可以执行以下操作:

    int max_num = 6;
    // Create vector
    std::vector<int> container(max_num);
    // Fill it with numbers 0, 1, ..., max_num - 1)
    std::iota(container.begin(), container.end(), 0)
    // Create random engine generator
    std::mt19937 eng{ std::random_device{}() };
    // shuffle it!!
    std::shuffle(container.begin(), container.end(), eng);
    

    所有讨厌的东西都已完成,而不是你!

    1. 随机性
    2. 你真的想在[0,6]中生成6个数字吗? 为什么不是7号才能拥有所有这些?

      我在计算机上测试了你的代码,重复了12万次,我有: 0缺少17335次 1缺少16947次 2缺少17054次 3失踪17116次 4失踪17330次 5失踪17114次 6缺少17105次

      这里看起来很一致,但我使用g ++。可能是msvc std库存在问题,但由于不使用它,我无法提供更多信息。

答案 1 :(得分:1)

永远不要那样做:

do {
     q = std::uniform_int_distribution<unsigned int>{ 0, max_num }(eng);
     it = std::find(container.begin(), container.end(), q);
 } while (it != container.end());

您正在挑选一个元素,然后拒绝,如果您之前已经选择过它。在计算方面,这是一个禁忌。

你想要的是一种名为Knuth shuffle(又名Fisher-Yates shuffle)的东西。 这种算法允许您随机选择一个向量的元素(这里是一个带有6个数字[0; 6 []的向量),无需替换。

&#34; Fisher-Yates洗牌类似于从帽子中随机挑选编号的票(组合:可辨别的物品)而不用替换,直到没有剩下。&#34;在Knuth Shuffle wikipedia article

充值代码:

#include <stdlib.h>

/* Arrange the N elements of ARRAY in random order.
Only effective if N is much smaller than RAND_MAX;
if this may not be the case, use a better random
number generator. */
void shuffle(int *array, size_t n)
{
    if (n > 1) {
        size_t i;
        for (i = 0; i < n - 1; i++) {
            size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
            int t = array[j];
            array[j] = array[i];
            array[i] = t;
        }
    }
}