Я не знаю, есть ли лучшая альтернатива, которая должна дать вам прямые результаты, но вот один из подходов, который может служить вашей цели.
Ваш вклад:
>> A
A =
0 1 1 0 1
1 0 0 1 0
0 1 1 0 1
1 0 0 1 0
0 1 1 0 1
Метод 1
Принимая первую строку и первый столбец, как колонного Mask (maskCol
) и Row-Mask (maskRow
) соответственно.
Получить маску из которых значений содержит те в обоих первом ряду, и первый столбец
maskRow = A(:,1)==1;
maskCol = A(1,:)~=1;
переставить строки (в соответствии с Роу-маской)
out = [A(maskRow,:);A(~maskRow,:)];
Дает примерно следующее:
out =
1 0 0 1 0
1 0 0 1 0
0 1 1 0 1
0 1 1 0 1
0 1 1 0 1
Перестановка столбцы (в соответствии с колонной маской)
out = [out(:,maskCol),out(:,~maskCol)]
дают желаемые результаты:
out =
1 1 0 0 0
1 1 0 0 0
0 0 1 1 1
0 0 1 1 1
0 0 1 1 1
Просто проверить, являются ли индексы, где они должны быть или если вы хотите соответствующие переупорядоченные индексы;)
Перед перестановке:
idx = reshape(1:25,5,[])
idx =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
После повторной организации (тот же процесс, который мы делали раньше)
outidx = [idx(maskRow,:);idx(~maskRow,:)];
outidx = [outidx(:,maskCol),outidx(:,~maskCol)]
Выход:
outidx =
2 17 7 12 22
4 19 9 14 24
1 16 6 11 21
3 18 8 13 23
5 20 10 15 25
Метод 2
Для Generic случае, если вы заранее не знаете матрицу, здесь процедура, чтобы найти логику maskRow
и maskCol
используется:
Возьмите первый ряд. Рассмотрим его как маску столбца (maskCol
).
Для второй строки до последней строки повторяется следующий процесс.
Сравните текущую строку с maskCol
.
Если какое-либо одно значение совпадает с maskCol
, а затем найти элемент мудрых логических ИЛИ и обновлять его как новый maskCol
Повторите этот процесс до последней строки.
Тот же процесс для нахождения maskRow
, в то время как столбец используется вместо итераций.
Код:
%// If you have a square matrix, you can combine both these loops into a single loop.
maskCol = A(1,:);
for ii = 2:size(A,1)
if sum(A(ii,:) & maskCol)>0
maskCol = maskCol | A(ii,:);
end
end
maskCol = ~maskCol;
maskRow = A(:,1);
for ii = 2:size(A,2)
if sum(A(:,ii) & maskRow)>0
maskRow = maskRow | A(:,ii);
end
end
Вот пример, чтобы попробовать, что:
%// Here I removed some 'ones' from first, last rows and columns.
%// Compare it with the original example.
A = [0 0 1 0 1
0 0 0 1 0
0 1 1 0 0
1 0 0 1 0
0 1 0 0 1];
Затем повторите процедуру, а затем перед:
out = [A(maskRow,:);A(~maskRow,:)]; %// same code used
out = [out(:,maskCol),out(:,~maskCol)]; %// same code used
Вот результат:
>> out
out =
0 1 0 0 0
1 1 0 0 0
0 0 0 1 1
0 0 1 1 0
0 0 1 0 1
Примечание: Этот подход может работать в большинстве случаев, но все еще может потерпеть неудачу в некоторых редких случаях.
Здесь пример:
%// this works well.
A = [0 0 1 0 1 0
1 0 0 1 0 0
0 1 0 0 0 1
1 0 0 1 0 0
0 0 1 0 1 0
0 1 0 0 1 1];
%// This may not
%// Second col, last row changed to zero from one
A = [0 0 1 0 1 0
1 0 0 1 0 0
0 1 0 0 0 1
1 0 0 1 0 0
0 0 1 0 1 0
0 0 0 0 1 1];
Почему не получится?
Как Переберите каждую строку (чтобы найти маску столбца), в течение, например, когда мы переходим к 3-й ряду, ни один из перевалов не соответствует первой строке (текущего maskCol
). Таким образом, теряется единственная информация, переносимая третьей строкой (2-й элемент).
Это может быть редкий случай, поскольку некоторые другие строки могут содержать одну и ту же информацию. См. Первый пример. Также ни один из элементов третьей строки не совпадает с первой строкой, но поскольку последняя строка имеет одинаковую информацию (1 на 2-м элементе), она дала правильные результаты. Только в редких случаях подобное может произойти. Тем не менее, хорошо знать этот недостаток.
Метод 3
Это одна перебором альтернатива. Может применяться, если вы считаете, что предыдущий случай может завершиться неудачей. Здесь мы используем while loop
для запуска предыдущего кода (поиск строки и кол-маски) количество раз с обновленным maskCol
, чтобы он нашел правильную маску.
Процедура:
maskCol = A(1,:);
count = 1;
while(count<3)
for ii = 2:size(A,1)
if sum(A(ii,:) & maskCol)>0
maskCol = maskCol | A(ii,:);
end
end
count = count+1;
end
Предыдущий пример взят (где предыдущий метод не) и запускается с и без while-loop
без грубой силы:
>> out
out =
1 0 1 0 0 0
1 0 1 0 0 0
0 0 0 1 1 0
0 1 0 0 0 1
0 0 0 1 1 0
0 0 0 0 1 1
С Грубым незначащими во время цикла:
>> out
out =
1 1 0 0 0 0
1 1 0 0 0 0
0 0 0 1 1 0
0 0 1 0 0 1
0 0 0 1 1 0
0 0 0 0 1 1
Числа итераций, необходимых для получения правильных результатов могут отличаться. Но безопасно иметь хорошее число.
Удачи!
Это работает для конкретного примера, который я дал, но работает ли он для более общего примера? В вашем примере вы ищете строки и столбцы, которые имеют одни в первой строке или столбце. Как это будет работать, если я не знаю структуру искомой матрицы перед рукой? – Cecilia
@Cecilia, обновленная для общего случая .. должна работать практически во всех случаях для конкретного шаблона (строки и столбцы, занятые зелеными, не должны быть заняты синими). Если у вас есть какой-то конкретный пример, когда это не работает, обновите вопрос с помощью этого конкретного примера и дайте мне знать. :) –