【问题标题】:Shuffle vector of vectors in C++C++ 中向量的洗牌向量
【发布时间】:2015-08-09 13:36:47
【问题描述】:

考虑vector<vector<int> > Vec

我想洗牌 Vec 内每个 vector<int> 中的 int 值,并对 vector< vector<int> > 执行洗牌。

如何在 C++ 中做到这一点?

我的主要目标是随机化一个整数矩阵,我使用vector<vector<int> > Vec 实现了它。

目前,我正在尝试这样做:

unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

for(int i=0;i<Vec.size();i++) {
    shuffle(Vec[i].begin(), Vec[i].end(), std::default_random_engine(seed));
}
shuffle(Vec.begin(),Vec.end()); 
// gives an error: 
cluster.cpp:36:27: error: no matching function for call to ‘shuffle(std::vector<std::vector<int> >::iterator, std::vector<std::vector<int> >::iterator)’

【问题讨论】:

  • 什么错误?我们应该猜吗?
  • 您使用#include &lt;algorithm&gt; 并使用std::shuffle()(限定名)吗?
  • 是的,我确实包含了它们。
  • 您似乎对每个 使用相同的种子。此外,您在最后一次致电 std::shuffle 时没有提供随机引擎

标签: c++ c++11 random c++14


【解决方案1】:

您可以使用shuffle 操作随机打乱数组中的元素。所以你可以使用它两次来随机化数组。但是,它留下的问题是数字连续打乱,行也打乱。这不是完全随机的洗牌,因为约束仍然存在。

要获得真正的随机洗牌,我建议您将矩阵复制到一维向量中,对该向量进行洗牌,然后将其重塑为矩阵。

洗牌向量的代码如下

#include <algorithm>
#include <random>

auto engine = std::default_random_engine{};
std::shuffle(std::begin(vector), std::end(vector), engine);

【讨论】:

  • 如果速度对您很重要,您还可以将 2d 向量实现为 1d 向量,地址方案为 [a][b] = [a*TotalRowSize+b] 以便您不要必须将整个矩阵复制到一维向量来对其进行洗牌,然后将其全部复制回来。假设行的大小都相同。
  • @RyanP 而且速度也更快,因为您保证了连续存储。
  • @vsoftco :我不明白你的评论是什么意思。向量的向量也将具有连续存储。 RyanP 的解决方案更快的唯一原因是它避免了从 2D 向量复制到 1D 向量的开销。
  • @therainmaker 不,向量向量将具有连续存储的指针,每个指针指向一行。但是,根本无法保证(通常情况并非如此)为每一行分配的内存是相邻的。基本上,vector&lt;vector&lt;T&gt;&gt; 是对T** 的复杂包装。
  • @vsoftco 非常感谢。我不知道是这样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 2013-10-20
  • 2020-10-12
  • 2021-05-04
  • 1970-01-01
  • 2013-12-18
  • 2021-08-14
相关资源
最近更新 更多