我創建了一個 shape 元胞陣列m x 2
,其中的每個元素都是一個 shape 矩陣d x d
。
例如像這樣:
A = cell(8, 2);
for row = 1:8
for col = 1:2
A{row, col} = rand(3, 3);
end
end
更一般地說,我可以表示A
如下:
其中每個A_{ij}
都是一個矩陣。
現在,我需要從 的每一行中隨機挑選一個矩陣A
,因為總共A
有m
行,所以最終我會挑選出 m 個矩陣,我們稱之為組合。
顯然,由于每行只有兩個選擇,所以總共有2^m種可能的組合。
我的問題是,如何快速獲得這些2^m組合?
可以看出,上面的問題其實就是求以下集合的笛卡爾積:
uj5u.com熱心網友回復:
2^m
實際上是一個二進制數,因此我們可以使用它們來創建線性索引。您將得到一個包含 1 和 0 的陣列,類似于[1 1 0 0 1 0 1 0 1]
,我們可以將其視為列“索引”,使用 a0
表示第一列,使用 a 表示第二列1
。
m = size(A, 1);
% Build all binary numbers and create a logical matrix
bin_idx = dec2bin(0:(2^m -1)) == '1';
row = 3; % Loop here over size(bin_idx,1) for all possible permutations
linear_idx = [find(~bin_idx(row,:)) find(bin_idx(row,:)) m];
A{linear_idx} % the combination as specified by the permutation in out(row)
在我的 R2007b 版本上,它幾乎可以即時運行m = 20
.
注意:這將占用m * 2^m
記憶體位元組來存盤bin_idx
。那里只有 20 MB m = 20
,那已經是 30 GB m = 30
,也就是說,你很快就會耗盡記憶體,這只是將排列存盤為布林值!如果m
在您的情況下很大,則無論如何您都無法存盤所有可能性,因此我只選擇一個隨機的:
bin_idx = rand(m, 1); % Generate m random numbers
bin_idx(bin_idx > 0.5) = 1; % Set half to 1
bin_idx(bin_idx < 0.5) = 0; % and half to 0
舊的、緩慢的答案m
perms()
1為您提供給定集合的所有可能排列。但是,它不考慮重復條目,因此您需要呼叫unique()
以獲取唯一行。
unique(perms([1,1,2,2]), 'rows')
ans =
1 1 2 2
1 2 1 2
1 2 2 1
2 1 1 2
2 1 2 1
2 2 1 1
現在唯一剩下的就是以某種方式對所有可能數量的1
s 和2
s 執行此操作。我建議使用一個簡單的回圈:
m = 5;
out = [];
for ii = 1:m
my_tmp = ones(m,1);
my_tmp(ii:end) = 2;
out = [out; unique(perms(my_tmp),'rows')];
end
out = [out; ones(1,m)]; % Tack on the missing all-ones row
out =
2 2 2 2 2
1 2 2 2 2
2 1 2 2 2
2 2 1 2 2
2 2 2 1 2
2 2 2 2 1
1 1 2 2 2
1 2 1 2 2
1 2 2 1 2
1 2 2 2 1
2 1 1 2 2
2 1 2 1 2
2 1 2 2 1
2 2 1 1 2
2 2 1 2 1
2 2 2 1 1
1 1 1 2 2
1 1 2 1 2
1 1 2 2 1
1 2 1 1 2
1 2 1 2 1
1 2 2 1 1
2 1 1 1 2
2 1 1 2 1
2 1 2 1 1
2 2 1 1 1
1 1 1 1 2
1 1 1 2 1
1 1 2 1 1
1 2 1 1 1
2 1 1 1 1
1 1 1 1 1
NB: I've not initialised out
, which will be slow especially for large m
. Of course out = zeros(2^m, m)
will be its final size, but you'll need to juggle the indices within the for
loop to account for the changing sizes of the unique permutations.
You can create linear indices from out
using find()
linear_idx = [find(out(row,:)==1);find(out(row,:)==2) size(A,1)];
A{linear_idx} % the combination as specified by the permutation in out(row)
Linear indices are row-major in MATLAB, thus whenever you need the matrix in column 1, simply use its row number and whenever you need the second column, use the row number size(A,1)
, i.e. the total number of rows.
Combining everything together:
A = cell(8, 2);
for row = 1:8
for col = 1:2
A{row, col} = rand(3, 3);
end
end
m = size(A,1);
out = [];
for ii = 1:m
my_tmp = ones(m,1);
my_tmp(ii:end) = 2;
out = [out; unique(perms(my_tmp),'rows')];
end
out = [out; ones(1,m)];
row = 3; % Loop here over size(out,1) for all possible permutations
linear_idx = [find(out(row,:)==1).';find(out(row,:)==2).' m];
A{linear_idx} % the combination as specified by the permutation in out(row)
1 There's a note in the documentation:
perms(v)
is practical whenlength(v)
is less than about10
.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/449643.html
上一篇:簡單的mex檔案崩潰?