如何从矩阵中有效地生成行的随机子集

时间:2009-11-19 13:06:27

标签: c++ stl

我有一个大的矩阵M实现为vector<vector<double> m行,即矩阵是n个列元素的m个向量的向量。

我必须创建该矩阵的两个行的子集,即A保持k行,B保持其他m-k行。必须随机选择行。

我不想使用除STL之外的任何库,因此也没有提升。

我考虑过两种方法:

  1. 生成行索引的std :: random_shuffle,将前k个索引指示的行复制到A,将其他m-k指示的行复制到B
  2. 做一个md :: random_shuffle,M。复制k行到A,m-k行到B
  3. 还有其他选项,以及上述两个选项在内存消耗和处理时间方面的比较如何?

    谢谢!

3 个答案:

答案 0 :(得分:2)

如果你不需要B是随机顺序,那么random_shuffle会比你需要的工作更多。

如果“STL”表示SGI的STL,则使用random_sample

如果“STL”表示C ++标准库,那么您没有random_sample。您可能希望复制实现,但在第一个n步骤之后停止。这会减少时间。

请注意,这些都会修改序列。根据你真正希望A和B结束的地方,以及谁拥有原始版本,这可能意味着你最终会为每一行做两个副本 - 一次将它放入一个可变容器中进行随机播放,然后再将其放入它的最终目的地。这比所需的内存和处理时间更多。要解决这个问题,您可以将swap行从临时容器中移出,然后移入A和B.或者复制算法,但要将其调整为:

  • 列出第一个向量的索引
  • 部分随机播放索引列表
  • 将前n个索引对应的行复制到A,其余的复制到B.

我不确定这是更快还是使用更少的内存,但我怀疑是这样。

random_shuffle的标准表示它执行“交换”。我希望这意味着它对于向量是有效的,但是你可能想要检查它是否实际上使用了优化的swap,而不进行任何复制。我认为这应该意味着,特别是因为自然实现就像Fisher-Yates一样,但我不确定是否应该采用标准中的语言来保证它。如果是复制,那么你的第二种方法将非常缓慢。如果它正在使用swap那么它们大致相当。向量上的swap将比索引上的swap略慢,但其中并没有很多。与复制行相比,交换向量或索引非常快,每个操作都有M个,所以我怀疑它会对总运行时间产生巨大影响。

[编辑:Alex Martelli最近抱怨滥用术语“STL”意味着C ++标准库。在这种情况下,它确实有所作为: - )]

答案 1 :(得分:1)

我认为random_shuffle指数是有意义的。

如果您需要避免复制单个行的开销,并且不介意共享数据,您可以使A和B矩阵成为指向原始矩阵中行的指针的向量。

答案 2 :(得分:0)

最简单的方法:使用随机整数生成器,并在单独的容器中排队每行的偏移量(假设每个列向量中的行具有相同的偏移量)。您使用的容器将更多地取决于它的最终用途。 (记住要处理size_t限制,并将偏移容器的生命与Matrix本身联系起来)。

编辑:用偏移代替指针 - 更有意义,也更安全。

原文:快速问:每个(内部)向量是一行还是一列?

即。 M是列的向量还是行的向量?