来自两个列表的随机对

时间:2016-03-23 13:15:25

标签: c++ arrays algorithm random permutation

我的问题类似于this一个。

我有两个列表:X包含n元素,Y包含m元素 - 假设它们包含n x m矩阵的行和列索引A。现在,我想在矩阵k中的A随机位置写一些内容。

我想到了两个解决方案:

  1. x获取随机元素X,从y获取随机元素Y。检查某些内容是否已写入A[x][y],如果没有 - 写入。但如果k接近m*n,我可以永远这样拍摄。
  2. 创建一个m*n数组,其中包含所有可能的索引组合,将其洗牌,绘制第一个k元素并写入其中。但我在这里看到的问题是,如果nm都非常大,则新创建的n*m数组可能巨大(并且改组可能会占用一些时间也是如此。
  3. Karoly Horvath 建议将两者结合起来。我想我必须选择阈值t和:
  4. if( k/(m*n) > t ){
        use option 2.
    }else{
        use option 1.
    }
    

    有关如何挑选t的任何建议吗?

    我错过了其他(更好的)方法吗?

4 个答案:

答案 0 :(得分:4)

有一个elegant algorithm归因于Floyd的抽样而没有从一系列整数中取代。您可以通过C ++函数$rootScope.$broadcast[0, n*m)中的结果整数映射到坐标。

答案 1 :(得分:0)

最好的方法取决于你得到的矩阵有多满。如果你要填充超过一半的碰撞率(也就是已经“写入”的随机点)会很高并且会让你比你想要的更多地循环。

我不会产生所有可能性,但我会在你使用列表列表时构建它。一个用于X的所有可能值,并且从Y的可能值列表中开始。我将初始化X列表但不初始化Y列表。 每当你第一次选择x的值时,你创建一个字典或m个元素的列表,然后删除你使用的那个。然后下次你选择x你将有m-1个元素,一旦X值用完了元素,然后将其从列表中删除,这样它就不会被再次拾取..这样你就可以保证永远不会再次选择一个占用的空间,并且您不需要生成n * m个可能的选项。

答案 2 :(得分:0)

您有n x m个元素,例如10 x 20矩阵的200个元素。从200中挑选一个应该很容易。要点是,无论你做什么,你都可以将这两个维度平坦化为一个,从而减少问题的这一部分。

注意:

  • 使用floor divide和modulo操作从行索引中获取行和列。
  • 黑名单:将拾取的索引存储在一个集合中,以快速跳过已写入的索引。
  • 白名单:存储尚未在集合中选取的索引。如果这比黑名单更好,取决于你的设置有多满。
  • 使用正确的容器类型可能很重要,它不一定是std::set。对于黑名单,您只需要快速查找和快速插入,vector<bool>可能实际上工作得很好。对于白名单,您需要快速随机访问和快速删除,其余索引vector<unsigned>将是一个不错的选择。
  • 根据具体情况准备在任何一种方法之间切换。

答案 3 :(得分:0)

对于nxm矩阵,您可以考虑[0..n * m-1]矩阵元素的索引。

填写随机索引相当简单,只需生成0到n * m-1之间的随机数,这就是要填充的位置。

随后执行此操作可能会有点棘手:

  1. 你可以测试你已经写过某个位置的天气并重新生成随机数;但是当你填充矩阵时,你将有更多的索引再生。
  2. 更好的解决方案是将所有索引放在n * m个元素的向量中。生成索引时,将其从列表中删除,然后生成0到N-1之间的随机索引
  3. 示例:

    vector<int> indexVec;
    for (i=0;i<n*m;i++)
        indexVec.push_back(i);
    nrOfIndexes = n*m-1;
    while (nrOfIndexes>1) 
    {
       index = rand()% nrOfIndexes;
       processMatrixLocation(index); 
       indexVec.erase(indexVec.begin()+index);    
       nrOfIndexes--;
    }
    processMatrixLocation(indexVec[0]);