【问题标题】:How to generate all pairs from two vectors in MATLAB using vectorised code?如何使用向量化代码从 MATLAB 中的两个向量生成所有对?
【发布时间】:2011-11-18 19:17:12
【问题描述】:

现在我不止一次需要在 MATLAB 中生成所有可能的两个向量对,我使用 for 循环来执行这些循环,这占用了相当多的代码行,即

vec1 = 1:4;
vec2 = 1:3;
i = 0;
pairs = zeros([4*3 2]);
for val1 = vec1
    for val2 = vec2
         i = i + 1;
         pairs(i,1) = val1;
         pairs(i,2) = val2;
    end
end

生成 ...

1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1 
4 2
4 3

一定有更好的方法来做到这一点,这更像是 MATLAB'esque?

n.b. nchoosek 不做我需要的反向对(即2 11 2),我不能只是反向并附加nchoosek 输出,因为对称对将被包含两次。

【问题讨论】:

标签: matlab combinations


【解决方案1】:

试试

[p,q] = meshgrid(vec1, vec2);
pairs = [p(:) q(:)];

请参阅MESHGRID documentation。虽然这不是该功能的用途,但如果你眯着眼睛看它很有趣,那么你所要求的正是它的作用。

【讨论】:

  • 太棒了。我知道meshgrid 和二维向量的序列化,但从未考虑过以这种方式使用它们。
【解决方案2】:

你可以使用

a = 1:4;
b = 1:3;
result = combvec(a,b);
result = result'

【讨论】:

  • 请注意,这需要神经网络工具箱。对于那些拥有它的人来说,这似乎是最好的解决方案。
  • 这样比公认的解决方案更好,因为它可以推广到多个向量。
  • @neuronet 我知道回复晚了,但值得未来的访问者知道,与接受的大型向量解决方案相比,这非常慢。
【解决方案3】:

收集的另一种解决方案:

[idx2, idx1] = find(true(numel(vec2),numel(vec1)));
pairs = [reshape(vec1(idx1), [], 1), reshape(vec2(idx2), [], 1)];

【讨论】:

  • +1:我删除了我的解决方案,我更喜欢你的解决方案。我冒昧地纠正它,以获得vec1vec2 的组合。
  • @EitanT:不需要重塑。来自find 的索引始终应该是列向量,以及vec1(idx1) 等。
  • 我认为重塑是必要的。鉴于idx1 是一个向量(不管是行还是列),如果vec1 是一个行向量,那么vec1(idx1) 也将是一个行向量。 vec2 也是如此。
【解决方案4】:

您可以使用repmat 复制矩阵,然后使用reshape 将结果转换为列向量。

a = 1:4;
b = 1:3;
c = reshape( repmat(a, numel(b), 1), numel(a) * numel(b), 1 );
d = repmat(b(:), length(a), 1);
e = [c d]

e =

     1     1
     1     2
     1     3
     2     1
     2     2
     2     3
     3     1
     3     2
     3     3
     4     1
     4     2
     4     3

当然,你可以去掉上面例子中的所有中间变量。

【讨论】:

    【解决方案5】:

    您可以使用普通的旧矩阵运算,例如在

    x = [3,2,1];
    y = [11,22,33,44,55];
    v = [(ones(length(y),1) * x)(:), (ones(length(x), 1) * y)'(:)]
    

    编辑:这是 Octave 语法,MATLAB 将如下所示:

    x = [3,2,1];
    y = [11,22,33,44,55];
    A = ones(length(y),1) * x;
    B = (ones(length(x), 1) * y)';
    v = [A(:) B(:)]
    

    在这两种情况下,结果都是

    v =
     3    11
     3    22
     3    33
     3    44
     3    55
     2    11
     2    22
     2    33
     2    44
     2    55
     1    11
     1    22
     1    33
     1    44
     1    55
    

    【讨论】:

    • 这不是有效的 MATLAB 语法。
    【解决方案6】:

    您正在寻找的是cartesian product

    cartprod 是实现它的函数。你可以在 linear-algebra 包中找到它,所以你需要这样做:

       >> pkg install -forge linear-algebra
       >> pkg load linear-algebra 
       >> sortrows(cartprod(1:4,1:3))                                            
        ans =                                                                                           
           1   1                                                                  
           1   2                                                                  
           1   3                                                                  
           2   1                                                                  
           2   2                                                                  
           2   3                                                                  
           3   1                                                                  
           3   2                                                                  
           3   3                                                                  
           4   1                                                                  
           4   2                                                                  
           4   3    
    

    【讨论】:

    【解决方案7】:

    这里有一种更 MATLAB'esque 的方式来查找组合。这个也可以很容易地扩展到超过 2 个向量(以及非数字组合):

    v1 =   1:  1:  3;
    v2 =  11: 11: 44;
    v3 = 111:111:555;
    
    dimensions = cellfun(@numel, {v1,v2,v3});
    
    [i1,i2,i3] = ind2sub(dimensions, 1:prod(dimensions));
    
    combinations = [v1(i1); v2(i2); v3(i3)]'
    

    【讨论】:

      【解决方案8】:

      从版本 R2015a 开始,您可以使用 repelemrepmat 执行此操作:

      >> vec1 = 1:4;
      >> vec2 = 1:3;
      >> pairs = [repelem(vec1(:), numel(vec2)) ...
                  repmat(vec2(:), numel(vec1), 1)]
      
      pairs =
      
           1     1
           1     2
           1     3
           2     1
           2     2
           2     3
           3     1
           3     2
           3     3
           4     1
           4     2
           4     3
      

      这种类型的解决方案避免了一些其他解决方案(例如基于 meshgrid 的解决方案)所需的额外中间变量,这可能导致较大向量的内存问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-18
        • 1970-01-01
        相关资源
        最近更新 更多