ガンサーはすでに正しい軌道に乗っていた。要素を選択する場合は、
- 非ゼロの行の累積は1AND
- 非ゼロの列の累積は1AND
- 要素自体はゼロ以外です。
次のコードは問題を解決します。
A = [0, 0, 3, 4;
4, 3, 2, 0;
2, 0, 2, 0];
batches = cell(0);
while any(A(:)~=0)
selector = cumsum(A~=0, 1) .* cumsum(A~=0, 2) .* (A~=0) == 1;
batches{end+1} = A .* selector;
A(selector) = 0;
end
ただし、2番目のバッチは次のようになっているため、返されるソリューションは最適ではないことに注意してください。
0 0 0 4
0 3 0 0
2 0 0 0
これは、残りの行列要素が同じ列からのものであることを意味します。
0 0 0 0
0 0 2 0
0 0 2 0
残念ながら、同じバッチでそれらを描画することはできません。したがって、3つではなく4つのバッチになります。
編集:おそらく、ゼロ以外の多くの行/列に表示される要素を最初に選択することをお勧めします。たとえば、これらの重みを使用できます
weight = repmat(sum(A~=0, 1), size(A, 1), 1) ...
.* repmat(sum(A~=0, 2), 1, size(A, 2)) .* (A~=0)
weight =
0 0 6 2
6 3 9 0
4 0 6 0
次のアルゴリズム
batches = cell(0);
while any(A(:)~=0)
batch = zeros(size(A));
weight = repmat(sum(A~=0, 1), size(A, 1), 1) ...
.* repmat(sum(A~=0, 2), 1, size(A, 2)) .* (A~=0);
while any(weight(:)~=0)
[r,c] = find(weight == max(weight(:)), 1);
batch(r,c) = A(r,c);
A(r,c) = 0;
weight(r,:) = 0;
weight(:,c) = 0;
end
batches{end+1} = batch;
end
それらのバッチを返します。
batches{:}
ans =
0 0 0 4
0 0 2 0
2 0 0 0
ans =
0 0 3 0
4 0 0 0
0 0 0 0
ans =
0 0 0 0
0 3 0 0
0 0 2 0
したがって、少なくともこの小さなテストケースでは機能しました。