我想生成一个随机整数,它遵循均匀分布而不重复。例如,我将通过此代码生成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 ++的上述代码?感谢
这是我的代码
答案 0 :(得分:4)
看看你的代码,看起来你重新发明轮子。 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);
所有讨厌的东西都已完成,而不是你!
你真的想在[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;
}
}
}