为什么样本不随机填充我的矢量?

问题描述 投票:4回答:2

我正在尝试玩具sample程序:

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{}() });

Live Example

bar总是按顺序包含foo的内容。这是一个gcc实现问题,还是我一再不幸?

c++ algorithm dictionary vector random
2个回答
2
投票

抽样是关于返回更大人口的一些子集。

它不是以随机顺序或任何其他顺序返回元素。它可以,但那并不是它的真正含义。

cppreference暗示在此声明中订购:

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

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

这也是有道理的,因为,与注释中提到的类似,为了高效,您首先需要确定要选择哪些元素,然后通过迭代器并选择元素,因为您只能迭代一个方向到另一个方向。因此,将元素保持在相同的顺序应该是微不足道的。

至于何时不使用ForwardIterator,它无法保证订单的方式。因此,即使它看起来似乎是随机排序的,依靠这个也是不明智的,因为排序的随机性可能依赖于实现,它可能有也可能没有高entropy

如果你想要一个随机的订单,你应该shuffle它。


5
投票

qazxsw poi从你传递的范围中选择元素。来自qazxsw poi(强调我的):

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

如果n大于序列中元素的数量,则选择last-first元素。

我认为文档可以更清楚,但是如果请求的元素数量更大,则仅返回std::sample,只有在每个元素最多选择一次时才有意义。

尝试:

cppreference

last-first获得两个随机样本。

另请注意

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

也就是说,你总是得到相同的结果并不是运气不好。

© www.soinside.com 2019 - 2024. All rights reserved.