【问题标题】:MATLAB quick find of a vector in matrixMATLAB快速查找矩阵中的向量
【发布时间】:2017-04-17 05:08:06
【问题描述】:

我有一段代码以下列方式工作。 有一个大小为n x 2 的矩阵。每个元素都是介于 1 和某个最大值之间的整数,例如 m

我要在这个矩阵中搜索行,即给定[v1, v2],输出这个的索引。

现在,我正在使用:

k = find(ismember(edges, [v1, v2], 'rows'));

但是,这是我的代码中的瓶颈,因为这是线性时间。

我想实现一些 hashmap 类型的结构来快速查找。有什么简单的方法可以做到这一点?

【问题讨论】:

  • m的范围是多少?你看过containers.Map吗?
  • 我假设您希望通过一些预处理来加速大量查询,对吗?

标签: matlab performance search matrix


【解决方案1】:

既然你知道列的数量,这又如何(假设边是要搜索的矩阵):

idx = find(edges(:,1)==v1 & edges(:,2)==v2);

请注意,根据您使用索引的方式,您最好使用途中创建的逻辑索引:

idx = edges(:,1)==v1 & edges(:,2)==v2;

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    R2016b 及以后:

    find(all(edges == [v1 v2], 2))
    

    之前:

    find(all(bsxfun(@eq, edges, [v1 v2]), 2))
    

    【讨论】:

      【解决方案3】:

      试试下面的代码:

      M = [5 2; 10 1; 3 2; 4 4; 5 0]
      N = [4 4]
      ind=find(all(repmat(N,size(M,1),1)==M,2));
      

      ind 是矩阵包含 N 中特定数字的行。

      【讨论】:

        【解决方案4】:

        使用accumarray 可以制作邻接矩阵来加快搜索速度:

        A = accumarray(edges,1,[m m],@any,false)
        

        你可以使用索引来搜索它

        if(A(v1,v2))...
        

        如果m 非常大,您可以创建一个稀疏矩阵:

        A = accumarray(edges,1,[m m],@any,false,true)
        

        或者如果你需要它的索引,邻接矩阵可以这样创建:

        A = accumarray(edges,1:size(edgaes,1),[m m],@any,0,true);
        

        所以

        index = A(v1,v2)
        

        【讨论】:

          【解决方案5】:

          让我的代码速度提高 30-40 倍的一个选项是对整个第一列进行比较,捕获一组索引,然后仅在这些索引处检查第二列的值:

          ind = find(edges(:, 1) == v1);
          k = ind(edges(ind, 2) == v2);
          

          如果您仍然需要比这更快地完成它,您可以使用containers.Map class 预先计算每个可能的[v1 v2] 到它出现的行索引列表的映射。需要注意的是,映射的键类型不能是数字向量,但由于您处理的是整数(理想情况下 m 不会太大),您可以将 [v1 v2] 转换为 2 个字符的 ASCII 键.以下是构建地图的方法:

          mapObj = containers.Map('KeyType', 'char', 'ValueType', 'any');
          [R, C] = meshgrid(1:m);
          keys = [R(:) C(:)];
          for keyIndex = 1:(m*m)
            v = keys(keyIndex, :);
            ind = find(edges(:, 1) == v(1));
            mapObj(char(v)) = ind(edges(ind, 2) == v(2));
          end
          

          您可以像这样快速访问地图中的值:

          k = mapObj(char([v1 v2]));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-07-16
            • 1970-01-01
            • 2011-11-30
            • 1970-01-01
            • 2020-02-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多