2014-02-24 85 views
1
所有可能的組合

嘿,我有一個數字數組:具有不同長度

[1,2,3,4,5,6,7,8] 

我需要找到然後是數字的每個組合具有不同長度:

[1,2] 
[1,3] 
[1,4] 
. 
. 
. 
[1,2,3,4,5,8] 
[1,2,3,4,5,6,7] 
[1,2,3,4,5,6,8] 
[1,2,3,4,5,6,7,8] 

注意:它無論數字在數組內的順序如何。

我想將數組傳遞給循環內的函數,因此不同大小的向量不應該擔心。

我已經嘗試perms()內循環,但它返回太多的結果。

任何幫助表示讚賞。

+0

你應該期待2^8個結果。 「燙髮」有多少人回到你身邊? – Shai

+0

燙髮([1,2,3,4,5,6,7,8]);導致一個長度爲40320個組合(長度= 8;) – user1845029

回答

1

您可以使用一個小技巧與nchoosek產生所有可變大小的組合:介紹0表示「無號」(假設你的數字是永遠0)。這將生成重複項,因此您需要將unique應用於結果矩陣的行。最後,請從每行的零和存儲結果到一個單元陣列:

v = [1,2,3,4,5,6,7,8]; %// data 

n = numel(v); 
vz = [zeros(1,n-1) v]; %// add n-1 zeros to represent the absence of a number 
r = nchoosek(vz,n); %// generate combinations, one in each row 
r = unique(r,'rows'); %// remove duplicate rows 
result = arrayfun(@(k) nonzeros(r(k,:)).', 1:size(r,1), 'uni',0); %'// delete 0's 
+0

這是一個避免循環的好方法!但我認爲OP想要排列而不是組合。 – hkf

+0

@hkf我不認爲它是OP想要的排列,是嗎?在例子 –

+0

中,它們都是遞增的,我想OP應該在問題中澄清一下。 – hkf

1

MATLAB有這個功能NCHOOSEK的組合,但這只是一個固定的大小。所以,我們需要通過一個不同大小的循環來運行它。

代碼:

v=1:8; 
for k = 1:numel(v)-1 
    in1 = nchoosek(v,k+1); 
    your_func(in1); 
end 
1

既然你想,你需要從nchoosek運行結果燙髮排列。 Martrix S的組合結果及以下矩陣P具有置換結果:

v = [1,2,3,4,5,6,7,8]; 
S ={}; 
for ii =1:length(v); 
    S{ii} = nchoosek(v,ii); 
end 
P={}; 
for kk = 1:length(S) 
    data = S{kk}; 
    for jj = 1:size(data,1) 
     P{jj} = perms(data(jj,:)); 
    end 
end 
0

什麼你要找的是你的陣列的power set。我不知道很多關於MATLAB,但Rosetta Code索賠的算法的implementation之後,它看起來還好我:

function pset = powerset(theSet) 

    pset = cell(size(theSet)); %Preallocate memory 

    %Generate all numbers from 0 to 2^(num elements of the set)-1 
    for i = (0:(2^numel(theSet))-1) 

     %Convert i into binary, convert each digit in binary to a boolean 
     %and store that array of booleans 
     indicies = logical(bitget(i,(1:numel(theSet)))); 

     %Use the array of booleans to extract the members of the original 
     %set, and store the set containing these members in the powerset 
     pset(i+1) = {theSet(indicies)}; 

    end 

end