生成具有矢量集/对的组合矩阵

时间:2014-10-09 21:53:32

标签: matlab

我想从一组矢量中找到所有元素组合。我发现以下answer完美无缺。但是,我的一些载体配对在一起。例如,如果我有向量[15, 20][60, 70],我只想获得组合[15, 60][20, 70](因为15不能结合70)。

因此,对于以下向量:

vectors = {[1 2], [3 6 9], [10 20 30]} % [3 6 9] and [10 20 30] are paired

,应该给予

combs = [ 1     3    10
          1     6    20
          1     9    30
          2     3    10
          2     6    20
          2     9    30 ]

对于这个简单的例子,我可以使用vectors = {[1 2], [3 6 9]}使用链接中的组合代码,并通过连接来生成第三列:

combs = [combs, repmat([10 20 30], 1, size(combs, 1)/size([10 20 30], 2))'];

然而,我的情况并非那么简单。例如,我想有一个适用于矢量的代码:

vectors = {[1 2], [3 6 9], [10 20 30], [3 4 5], [55 66 77], [555 666 777], [101 201]} 
% [3 6 9] and [10 20 30] are a pair. 
% [55 66 77] and [555 666 777] are a pair.

1 个答案:

答案 0 :(得分:2)

首先需要定义哪些向量是“链接的”。使用您的示例,

vectors = {[1 2] [3 6 9] [10 20 30] [3 4 5] [55 66 77] [555 666 777] [101 201]};
linked = [1 2 2 3 4 4 5]; %// equal numbers mean those vectors are linked

然后你可以稍微修改一下所提到的答案:

  1. 将每个向量减少为值1,2,3的等价向量,...让我们称之为“int-vector”。

  2. 仅考虑每个链接矢量集中的一个“代表性”int-vector生成组合。

  3. 为剩余的int-vectors(链接到其代表)填充复制的值(列)。这就是为什么我们使用int-vectors而不是vector:每个非代表只是其代表的副本。

  4. 使用索引将int向量转换为实际向量。

  5. 代码:

    intVectors = cellfun(@(x) 1:numel(x), vectors, 'uniformoutput', 0); %// transform
    %// each vector into integers 1, 2, 3,...
    [~, u, v] = unique(linked); 
    uIntVectors = intVectors(u); %// choose one int-vector as representative of each
    %// linked set
    m = numel(vectors); %// number of vectors
    n = numel(uIntVectors); %// number of representatives (int-vectors)
    combs = cell(1,n);
    [combs{end:-1:1}] = ndgrid(uIntVectors{end:-1:1});
    combs = combs(:,v); %// include non-representatives (linked int-vectors) 
    combs = cat(m+1, combs{:});
    combs = reshape(combs,[],m); %// combinations of representatives (int-vectors)
    num = max(combs, [], 1); %// number of elements of each vector
    vectorsCat = [vectors{:}]; %// concatenate all vectors
    cnum = cumsum(num(1:end-1));
    combs(:,2:end) = bsxfun(@plus, combs(:,2:end), cnum); %// transform integers
    %// so that they can index vectorsCat
    combs = vectorsCat(combs); %// do the indexing to get final result
    

    为简洁起见,让我们简化你的例子:

    vectors = {[1 2], [3 6 9], [10 20 30], [3 4 5]};
    linked = [1 2 2 3]; 
    

    产生

    1     3    10     3
    1     3    10     4
    1     3    10     5
    1     6    20     3
    1     6    20     4
    1     6    20     5
    1     9    30     3
    1     9    30     4
    1     9    30     5
    2     3    10     3
    2     3    10     4
    2     3    10     5
    2     6    20     3
    2     6    20     4
    2     6    20     5
    2     9    30     3
    2     9    30     4
    2     9    30     5