可能重复:
有偏随机数生成器
有一次,我需要一个随机数生成器,其中至少有两个数字的概率比其他数字高。
即例如:1000 序列中的随机 1->10。数字 A=3 和 B=7。
A - 应该重复大约。至少 20% 的时间。B - 应该重复大约。至少 30% 的时间。
这应该至少涵盖 1000 序列的 50%。此外,A 和 B 的插入本身应该有点可能/随机。不只是每第 N 步添加 A 和 B。不需要完全/精确控制。
有任何想法吗?
我是一个菜鸟 - c++ 风格的代码将不胜感激!
一种方法是随机生成一个介于 0.0 和 1.0 之间的数字,然后根据该数字选择要生成的数字。例如,要实现您的示例场景(伪代码):
let "result" be an array of 1000 integers
let "i" be an integer
for i = 1 to 1000:
let "j" be a random number between 0.0 and 1.0
if j < 0.2:
let result[i] be 3
else if j < 0.5:
let result[i] be 7
else:
let "k" be an integer
do, while k = 3 or k = 7:
let "k" be a random number in the range 1 to 10
let result[i] be k
end
基本上,j
用于将范围 1 到 10 划分为三个部分 - 一部分覆盖范围的 0% 到 20%(第一个if
),第二个覆盖范围的 20% 到 50%(即 30% 宽,第二个if
),最后一个覆盖剩余的 50%。根据我们随机落入的部分,我们选择适当的数字来生成。
您应该为此使用该<random>
库。
#include <random>
#include <iostream>
#include <algorithm>
#include <iterator>
int main() {
// create a discrete distribution where the third object has 20% probability and
// the seventh has 30%
std::vector<double> probabilities(10, 5.0/8.0);
probabilities[2] = 2.0;
probabilities[6] = 3.0;
std::discrete_distribution<int> dist(begin(probabilities),end(probabilities));
// our underlying source of randomness
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
// create a function object that uses the distribution and source of randomness to
// produce values from 1 to 10
auto rand = [&]{ return dist(eng) + 1; };
std::vector<int> x;
// store 1000 random values
for (int i=0;i<1000;++i)
x.push_back(rand());
// count how many of each value, to verify that 3 comes out ~200 times and 7 comes
// out ~300 times
for (int i=1;i<=10;++i)
std::cout << i << ": " << count(begin(x),end(x),i) << '\n';
// print all the values
copy(begin(x),end(x),std::ostream_iterator<int>(std::cout, " "));
}