在MATLAB中从矩阵中选择某些零元素

时间:2014-06-11 07:07:13

标签: arrays matlab matrix

假设我有这个矩阵:

M =

90     0    40     0
 0     0    10    60
55    15     0    10
 0    15     5     0

我想找到所有的零,这样一旦我从行i和列j中选择零,就会从行i和列{{1>中再添加零应该选择。在这个例子中,从左到右,从上到下扫描,我应该得到的行和列是:

j

MATLAB代码会为我产生什么?

2 个答案:

答案 0 :(得分:1)

查找每行中的第一个零(如果有)

[ind1, ind2] = max(M.'==0);
result = [find(ind1); ind2(ind1)].';

在你的例子中,这给出了

result =
     1     2
     2     1
     3     3
     4     1

查找每行中的第一个零(如果有),忽略之前使用过的列

M2 = M; %// make a copy of M2. It will be overwritten
[R C] = size(M2);
cols = NaN(R,1); %// initiallize. This will store the result for each row
ind = false(R,1); %// intiallize. This will indicate rows that have a valid zero
for r = 1:R %// for each row
    c = find(M2(r,:)==0,1); %// find first valid zero, if any
    if ~isempty(c)
        cols(r) = c; %// store result
        ind(r) = true; %// this row has been found to have a valid zero
        M2(:,c) = inf; %// this col can no longer be used
    end
end
result = [find(ind) cols(ind)]; %// build result. Only rows with a valid zero

在你的例子中:

result =
     1     2
     2     1
     3     3
     4     4

答案 1 :(得分:1)

鉴于OP最初选择每行第一零的问题,路易斯·门多的回答是正确的。但是,通过评论中的讨论,这一要求现已发生变化。理解(至少从我从代码片段和要求中收集到的内容)是,一旦您在行i和列j中选择零,就不再有来自所有行的零应选择i和所有列j 。由于for循环通常在MATLAB中不受欢迎,我看到没有别的选择,只能用循环来做。

我的方法如下:

  1. 找到矩阵中的所有零,找到它们的行和列位置,并将每个位置放在不同的列表中。
  2. 虽然我们仍然需要考虑零:
    • 将此行和列放入列表
    • 从行列表中删除包含此行的所有索引。
    • 从列列表中删除包含此列的所有索引
  3. 重复步骤#2,直到我们的行和列位置列表为空。
  4. 不用多说,这是代码。

    clear all;
    close all;
    
    M =[90,0,40,0;0,0,10,60;55,15,0,10;0,15,5,0];
    
    %// Find row and column locations
    %// find traverses columns first, so I had to
    %// transpose and swap J,I so that it reports
    %// row locations first.
    [J,I] = find(M.' == 0);
    
    %// List of co-ordinates that meet our criteria
    rowCoords = [];
    
    %// While there is still one zero to consider...
    while (~isempty(I) && ~isempty(J))
        %// Store these for processing
        rowToAdd = I(1);
        colToAdd = J(1);
        %// Add to the list
        rowCoords = [rowCoords; [rowToAdd colToAdd]];  
    
        %// Remove all row and column co-ordinates
        %// that share the same row and column
        rowsToRemove = I == rowToAdd | J == colToAdd;
        I(rowsToRemove) = [];
        J(rowsToRemove) = [];
    end
    

    因此,我们终于得到:

    rowCoords = 
    
     1        2
     2        1
     3        3
     4        4
    

    目前还不清楚OP是否想要Luis Mendo所提供的内容,或者我在评论中所解释的内容。 OP验证了我如何指定他的要求是他真正想要的,但我们仍然没有任何验证。 OP:请验证。