2014-03-25 20 views
6

In Matlab, habe ich eine Matrix A von nicht negativen Einträgen. Siehe die folgende:Finden Sie die Nachbarn aller Nullen Elemente in einer Matrix

Ich möchte die Nachbarn aller Nullelemente erwarten das Nullelement. Dies bedeutet, dass ich in einem Vektor v die Nachbarn von A (1, 1), A (2, 5), A (3, 1), A (3, 6), A (4, 5) und A (5, 1) und wenn einer dieser Nachbarn Null ist, dann speichere ich ihn nicht.

Mit Nachbarn von Element (i, j) meine ich die Elemente, die weit entfernt von (i, j) um ein Element sind, dh A (i, j + 1), A (i, j-1) , A (i-1, j), A (i-1, j-1), A (i-1, j + 1), A (i + 1, j), A (i + 1, j-1), und A (i + 1, j + 1). Jedes Element (i, j) hat 7 Nachbarn.

Ich speichere keine Wiederholungselemente. Das heißt, wenn zum Beispiel A (1, 1) = 0 und A (1,3) = 0 und A (1,2) = 1 ist, werde ich A (1, 2) nur einmal speichern.

In meinem vorherigen Beispiel der Vektor v wird diese:

v=[2 1 8 1 2 4 5 2 9 8 5 5 8 4 6 5 8 3]; 

Wie dies ohne Schleifen in Matlab zu tun?

Das ist mein Code für quadratische Matrix: cl_ ist die Zahl der Null in meiner Matrix. ix_ ist der Zeilenindex der Nullelemente und iy_ ist der Spaltenindex der Nullelemente.

for i_=1:length(cl_) 
    ixn1_(1:2)=ix_(i_); 
    ixn2_(1:3)=ix_(i_)-1; 
    ixn3_(1:3)=ix_(i_)+1; 
    iyn1_=iy_(i_)-1; 
    iyn2_=iy_(i_)+1; 
    iyn3_(1:3)=[iy_(i_)-1, iy_(i_), iy_(i_)+1]; 
    ixn_{i_}=[ixn1_, ixn2_, ixn3_]; 
    iyn_{i_}=[iyn1_, iyn2_, repmat(iyn3_, 1, 2)]; 
end 
% find the neighbors 
+0

@LuisMendo Ich habe meine Frage aktualisiert. – npisinp

Antwort

3

Wenn Sie die Reihenfolge behalten möchten, in dem Sie in Ihrer Frage gesagt haben, dies könnte es sein -

-Code

%%// Given data 
A=[0 2 3 5 4 7 8 
    1 8 2 7 5 2 9 
    0 1 2 4 8 0 5 
    2 4 8 6 0 5 8 
    1 1 2 5 8 3 6]; 

%%// Find indices that have value zero 
[indx,indy] = find(A==0); 

%%// OP seems to be travelling row-wise, so sort the indices column-wise 
[indx,y1] = sort(indx); 
indy = indy(y1); 

%%// Get the 8 neighboring row and column offsets 
row1 = bsxfun(@plus,indx,[-1 -1 -1 0 0 1 1 1]); 
col1 = bsxfun(@plus,indy,[-1 0 1 -1 1 -1 0 1]); 

%%// Get the valid positions 
valid_pos = row1>0 & row1<=size(A,1) & col1>0 & col1<=size(A,2); 

%%// Get valid row and column numbers and then valid indices 
ind1 = (valid_pos.*col1-1).*size(A,1) + valid_pos.*row1; 

%%// Get valid linear indices 
ind1 = reshape(ind1',1,numel(ind1)); %%//' 
ind1 = ind1(ind1>0); 

%%// Find the unique indices without sorting 
[~, idxs, ~] = unique(ind1, 'first'); 
ind1 = ind1(sort(idxs)); 

%%// Get matrix values from indices and remove the zeros themselves 
OUT = A(ind1); 
OUT(OUT==0) = []; 

Ausgabe

OUT = 

    2  1  8  1  2  4  5  2  9  8  5  5  8  4  6  5  8  3 
2

Nun zuerst, ich nehme an, Sie wissen über den Befehl „find“: zum Beispiel topbot=find(abs(zz)==H); findet alle Elemente von zz, die gleich H sind und speichert sie in einem langen Vektor „topbot“.

Das einzige unglückliche Ding ist, dass es Matrixpositionen als eine einzelne Zahl speichert, also (3,1) wird als 3 usw. gespeichert. Wenn Sie also die Zeile und Spalte wollen, lautet die Formel column = ceiling((number-1)/numrows) und row = number mod numrows (nein die Syntax ist nicht richtig, aber Sie bekommen die Idee). (BEARBEITEN: Whoops, Mathe ist super hart und aus einem Fehler sind überall)

Danach sollte es nur eine Frage der Entfernung von Duplikaten sein und sicherstellen, dass Sie keine negativen Zeilen oder Spalten bekommen.

Schließlich können Matrixwerte von einem einzigen Index aufgerufen werden. Wenn A also eine 8 mal 8 Matrix ist, ist A(15) das gleiche wie der Aufruf .

5

Wenn Sie nicht besorgt über die Reihenfolge der Werte sind:

mask = A==0; 
neighborMask = xor(conv2(double(mask),ones(3),'same')>0,mask); 
v = A(neighborMask) 
Verwandte Themen