制作随机数的自定义分布

时间:2014-08-02 21:28:59

标签: c++11 random

我试图理解c ++ 11中不同的分发对象,我发现它势不可挡。我希望你们中的一些人可以并且将会有所帮助。


这就是为什么我要研究这一切:

我需要一个随机数生成器,我可以在每次使用时调整它,以便它更有可能再次生成相同的数字。我需要填写的第二个要求是我需要生成的随机数只是这些数字: {1, 2, 4, 8, 16, ..., 128}

第三个也是最后一个要求是在某些情况下我需要跳过上面一组中的一个或多个数字。

我的问题是我不了解各种分发对象的描述。因此,我无法确定需要使用哪些工具来满足我的上述需求。

有人可以告诉我我需要哪些工具以及如何使用它们?反应越清晰,越简洁,越详细。

2 个答案:

答案 0 :(得分:2)

您的范围可以使用[0,7]范围内的随机数j生成,然后计算:

1 << j

获取您的电话号码。 std::uniform_int_distribution<>对于在[0,7]中生成值非常方便。

此外,您可以使用std::bernoulli_distribution(返回随机bool)来确定下一个号码是否与最后一个号码相同,或者您是否应该生成新号码。 std::bernoulli_distribution默认为真/假的50/50,但您可以在bernoulli_distribution构造函数中将该分布自定义为您喜欢的任何内容(例如80/20或其他)。

如果这还不够清楚,只需使用一些代码即可。尝试编写代码,如果它不起作用,发布你的内容,我相信有人会帮忙。

哦,忘记了你的第三个要求:因为那只是把你的[0,7]代放在一个循环中,如果你想出一个你应该跳过的数字,那么迭代循环,否则突破它

答案 1 :(得分:1)

对于跳过数字我完全同意霍华德的说法,手动检查可能是要走的路,但可能有更好的方法来改变给定数字的生成概率。 另一种方法是使用discrete_distribution对象,它允许您指定生成任何给定值的概率,因此对于您的示例,它将类似于

std::default_random_engine entropy;
std::array<double, 128> probs;
probs.fill(1.0);
std::discrete_distribution<int> choose(probs.begin(), probs.end());

然后当你进入循环时,除了决定是否跳过之外,你可以将其中一个值增加一些,以增加它再次出现的几率,确保重新初始化离散值分发,像这样:

int x;
double myValue = 0.2;//or whatever increment you want
for (something; something else; something else else)
{
  x = choose(entropy);
  if (skip(x))
    continue;//alternately you could set probs.at(x) = 0
  //only if you never want to generate it again
  probs.at(x) += myValue;
  choose = std::discrete_distribution<int>(probs.begin(), probs.end());
  output(x);
}

其中跳过和输出是你的函数来决定是否应该跳过x并分别用生成的值做你想做的事情

相关问题