2010-11-12 14 views
31

Belirli bir sayıda vektörün elemanlarının olası tüm kombinasyonlarını üretmek istiyorum. I elemanları oluşturmak istediğiniz [1 2], [1 2] ve [4 5] için örneğin Bazı vektörlerin (Kartezyen ürün) elemanlarının olası tüm kombinasyonlarını üretin (Kartezyen ürün)

:

[1 1 4; 1 1 5; 1 2 4; 1 2 5; 2 1 4; 2 1 5; 2 2 4; 2 2 5]

Sorun kombinasyonları hesaplamak için gereken I vektörlerin sayısını bilmek kalmamasıdır . Bu durumda olduğu gibi 3 olabilir veya 10 olabilir ve genelleştirme'a ihtiyacım var. Lütfen bana MATLAB'da yardım edebilir misiniz? Bu görevi yerine getirebilen önceden tanımlanmış bir işlev var mı?

+10

aradığınız şey vektörlerin 'kartezyen ürünü' olarak adlandırılır. Bunun için biraz şansın olabilir. –

cevap

16

FileExchange'te ALLCOMB işlevini deneyin. Bir cep dizide size vektörleri saklıyorsanız

, böyle çalıştırabilirsiniz:

a = {[1 2], [1 2], [4 5]}; 
allcomb(a{:}) 
ans = 

    1  1  4 
    1  1  5 
    1  2  4 
    1  2  5 
    2  1  4 
    2  1  5 
    2  2  4 
    2  2  5 
+6

"ALLCOMB", Amro'nun yanıtındakiyle aynı şekilde "NDGRID" işlevini kullandığını ve hata düzeltmesini üstlendiğini unutmayın. – lodhb

+0

Evet, aradığım şey için teşekkürler .. :-) – tim

46

NDGRID işlevini kullanarak bu çözümü düşünün:

sets = {[1 2], [1 2], [4 5]}; 
[x y z] = ndgrid(sets{:}); 
cartProd = [x(:) y(:) z(:)]; 

cartProd = 
    1  1  4 
    2  1  4 
    1  2  4 
    2  2  4 
    1  1  5 
    2  1  5 
    1  2  5 
    2  2  5 

Yoksa genel bir çözüm istiyorsanız Herhangi bir sayı kümesi için (el ile değişkenleri oluşturmak zorunda kalmadan), bu işlev tanımını kullanın:

function result = cartesianProduct(sets) 
    c = cell(1, numel(sets)); 
    [c{:}] = ndgrid(sets{:}); 
    result = cell2mat(cellfun(@(v)v(:), c, 'UniformOutput',false)); 
end 
İsterseniz, sonuçları sıralayabilir o

Not: setleri hiçbir yinelenen değerleri (örn: {[1 1] [1 2] [4 5]}) varsa

cartProd = sortrows(cartProd, 1:numel(sets)); 

Ayrıca, yukarıdaki kod kontrol etmez. İsterseniz bu bir satır ekleme: İkinci (Bence) çözümü ve MATLAB güçlü uygulanarak ndgrid ile Amro cevabı çözümü bir gelişme olduğu

sets = cellfun(@unique, sets, 'UniformOutput',false); 
11

Bu geç cevaplar, iki ek çözümler sunar Eğeryoksa combvec

  • kullanın: Eğer Sinir Ağı Toolbox varsa

    1. yerine yüksek performans için hücre dizilerinin virgülle ayrılmış listeler, Araç kutusunun, genellikle olduğu gibi olması: Kartezyen ürünü herhangi bir sayı kümesi için genelleştirmenin başka bir yolu aşağıdadır. Amro onun cevabını olduğu gibi

  • Sadece virgülle ayrılmış listeler sözdizimi (v{:}) giriş ve ndgrid çıkışlarını hem tedarik etmektedir. fark, (dördüncü soyu) cat girişler olarak, şimdi daha virgülle ayrılmış listelerini uygulayarak cellfun ve cell2mat önlemesidir:

    N = numel(a); 
    v = cell(N,1); 
    [v{:}] = ndgrid(a{:}); 
    res = reshape(cat(N+1,v{:}),[],N); 
    

    cat ve reshape kullanımı yarısı hemen hemen uygulama süresini azaltır. Bu yaklaşım my answer to an different question ve more formally by Luis Mendo'da gösterilmiştir.

    0

    biz de

    no_inp=3 % number of inputs we want...in this case we have 3 inputs     
        a=[1 2 3] 
        b=[1 2 3] 
        c=[1 2 3] 
    
        pre_final=combvec(c,b,a)'; 
        final=zeros(size(pre_final)); 
    
        for i=1:no_inp 
        final(:,i)=pre_final(:,no_inp-i+1); 
        end 
        final 
    

    matlab

    yılında 'combvec' talimatı kullanabilirsiniz yardımcı olur Umut. İyi şanslar.