为什么样本没有随机填充我的载体?

时间:2018-09-08 15:51:19

标签: c++ algorithm dictionary vector random

我正在尝试一个玩具sample程序:

form = ArticleForm(request.POST or None, initial={'user': request.user})

Live Example

但是map<int, char> foo { { 1, 'a' }, { 2, 'b' }, { 3, 'c' } }; vector<pair<decltype(foo)::key_type, decltype(foo)::mapped_type>> bar(size(foo)); sample(begin(foo), end(foo), begin(bar), size(foo), mt19937{ random_device{}() }); 始终按顺序包含bar的内容。这是gcc的实现问题,还是我只是一再不幸?

2 个答案:

答案 0 :(得分:5)

std::sample从您通过的范围中选择元素。来自cppreference(强调我的):

  

从序列[first;最后)   可能的样本具有相同的出现概率,并写出   选定的元素放入输出迭代器中。随机数是   使用随机数生成器g生成。

     

如果n大于序列中的元素数,则选择倒数第一的元素。

我认为文档可能会更清晰,但是如果请求的元素数量更多,则仅返回last-first,只有在每个元素最多选择一次的情况下才有意义。

尝试:

map<int, char> foo { { 1, 'a' }, { 2, 'b' }, { 3, 'c' } };
vector<pair<decltype(foo)::key_type, decltype(foo)::mapped_type>> bar(size(foo)-1);

sample(begin(foo), end(foo), begin(bar), bar.size(), mt19937{ random_device{}() });

foo中抽取两个随机样本。

还要注意

  

仅当PopulationIterator满足以下条件时,算法才稳定   ForwardIterator的要求

也就是说,获得始终相同的结果并不只是幸运的事。

答案 1 :(得分:2)

抽样是关于返回更大总体的某些子集。

它不打算以随机顺序或任何其他顺序返回元素。 可以,但这并不是它的真正目的。

cppreference提示此语句中的顺序:

  

仅当PopulationIterator满足ForwardIterator的要求时,算法才稳定

此处的“稳定”表示它将以与输入相同的顺序返回结果,因此,使用ForwardIterator保证该顺序不是是随机的。相关:What is stability in sorting algorithms and why is it important?

这也很有意义,因为与注释中提到的类似,要高效,您首先需要确定要选择的元素,然后遍历迭代器并选择元素,因为您可以只从一个方向迭代到另一个方向。因此,将元素保持相同的顺序应该很简单。

对于,当您不使用ForwardIterator时,它不能保证订单的一种方式。因此,即使看起来似乎是随机排序的,也不要依赖于此,因为该排序的随机性可能取决于实现,并且它可能具有较高的entropy

如果您想要随机订单,则应shuffle