代码之家  ›  专栏  ›  技术社区  ›  andreas buykx

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

  •  1
  • andreas buykx  · 技术社区  · 15 年前

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

    我必须创建矩阵行的两个子集,即A容纳K行,B容纳其他M-K行。必须随机选择行。

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

    我认为有两种方法:

    1. 生成一个std::随机移动行索引,将前k个索引指示的行复制到a,将其他m-k指示的行复制到b。
    2. 执行标准:随机移动m。将k行复制到a,将m-k行复制到b

    还有其他的选项吗?上面的两个选项在内存消耗和处理时间方面是如何比较的?

    谢谢!

    3 回复  |  直到 15 年前
        1
  •  2
  •   Steve Jessop    15 年前

    如果你不需要B按随机顺序排列,那么随机洗牌比你需要的工作更多。

    如果“stl”是指sgi的stl,那么使用 random_sample .

    如果“STL”指的是C++标准库,那么你就没有随机抽样。您可能希望复制实现,但在第一个 n 步骤。这将缩短时间。

    请注意,这两者都在适当的位置修改了序列。根据您实际希望a和b结束的位置,以及谁拥有原始文件,这可能意味着您最终要对每行进行两次复制-一次将其放入可变容器中进行随机播放,然后再次将其放入最终目的地。这比需要的内存和处理时间更多。为了解决这个问题,你也许可以 swap 从临时容器中取出行,并放入A和B中。或复制算法,但要使其适应:

    • 列出第一个向量的索引
    • 部分无序排列索引列表
    • 将前n个索引对应的行复制到a,其余的复制到b。

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

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

    [编辑:Alex Martelli最近抱怨“STL”这个词的滥用意味着C++标准库。在这种情况下,它确实有区别:-)]

        2
  •  1
  •   Nate Kohl    15 年前

    我认为 random_shuffle 指数有意义。

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

        3
  •  0
  •   Fox    15 年前

    最简单的方法是:使用一个随机整数生成器,在一个单独的容器中对每行的偏移量进行排队(假设每行在每列向量中的偏移量相同)。您使用的容器将更多地取决于其最终用途。(记住要注意尺寸限制,并将偏移容器的寿命与矩阵本身联系起来)。

    编辑:用偏移替换指针-更合理更安全。

    奥利格: 快速问:每个(内部)向量是一行还是一列?

    也就是说,m是列的向量还是行的向量?