在 MATLAB 中查找互补向量的快速方法

Posted

技术标签:

【中文标题】在 MATLAB 中查找互补向量的快速方法【英文标题】:Quick way of finding complementary vectors in MATLAB 【发布时间】:2018-05-17 03:45:08 【问题描述】:

我有一个由N 行二进制向量组成的矩阵,即

mymatrix = [ 1 0 0 1 0;
             1 1 0 0 1;
             0 1 1 0 1;
             0 1 0 0 1;
             0 0 1 0 0;
             0 0 1 1 0;
             ....       ]

我想在哪里找到行组合,当它们加在一起时,我得到了准确的信息:

[1 1 1 1 1]

所以在上面的例子中,可以使用的组合是1/31/4/52/6

我现在的代码是:

i = 1;
for j = 1:5
    C = combnk([1:N],j); % Get every possible combination of rows
    for c = 1:size(C,1)
        if isequal(ones(1,5),sum(mymatrix(C(c,:),:)))
            combisi = C(c,:);
            i = i+1;
        end
    end
end

但正如您想象的那样,这需要一段时间,尤其是因为那里有 combnk

有什么有用的算法/函数可以帮助我加快速度?

【问题讨论】:

这是 set cover problem,它是 NP 完全的,这意味着对于大量向量,它的计算成本非常高。特别是如果您有兴趣找到所有解决方案。你的向量可能有多大?只有 5 个元素的向量,您最多可以有 32 行,这应该是可管理的。 【参考方案1】:
M = [
 1 0 0 1 0;
 1 1 0 0 1;
 0 1 1 0 1;
 0 1 0 0 1;
 0 0 1 0 0;
 0 0 1 1 0;
 1 1 1 1 1
];

% Find all the unique combinations of rows...
S = (dec2bin(1:2^size(M,1)-1) == '1');

% Find the matching combinations...
matches = cell(0,1);

for i = 1:size(S,1)
    S_curr = S(i,:);
    
    rows = M(S_curr,:);
    rows_sum = sum(rows,1);
    
    if (all(rows_sum == 1))
        matches = [matches; find(S_curr)];
    end
end

以良好的风格化方式显示您的比赛:

for i = 1:numel(matches)
    match = matchesi;
    
    if (numel(match) == 1)
        disp(['Match found for row: ' mat2str(match) '.']);
    else
        disp(['Match found for rows: ' mat2str(match) '.']);
    end
end

这将产生:

找到第 7 行的匹配项。

为行找到匹配项:[2 6]。

为行找到匹配项:[1 4 5]。

为行找到匹配项:[1 3]。

在效率方面,在我的机器中,这个算法正在完成大约2 milliseconds的匹配检测。

【讨论】:

以上是关于在 MATLAB 中查找互补向量的快速方法的主要内容,如果未能解决你的问题,请参考以下文章

排序向量查找的更快版本 (MATLAB)

MATLAB:2个向量中所有索引的快速相关计算

怎样用matlab进行列向量归一化?

MATLAB:在向量和向量数组之间进行均方根误差的最快方法

在MATLAB中查找子集的索引

matlab常用函数