34

指定された数のベクトルの要素の可能な組み合わせをすべて生成したいと思います。

たとえば、 for [1 2][1 2]および[4 5]要素を生成したい:

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

問題は、組み合わせを計算する必要があるベクトルの数がわからないことです。この場合のように 3 つある場合もあれば、10 つある場合もあり、一般化が必要です。MATLABでこれを手伝ってもらえますか? このタスクを実行できる定義済みの関数は既にありますか?

4

4 に答える 4

52

NDGRID関数を使用してこのソリューションを検討してください。

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

または、(変数を手動で作成することなく)任意の数のセットの一般的なソリューションが必要な場合は、次の関数定義を使用します。

function result = cartesianProduct(sets)
    c = cell(1, numel(sets));
    [c{:}] = ndgrid( sets{:} );
    result = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
end

必要に応じて、結果を並べ替えることができます。

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

また、上記のコードは、セットに重複する値がないかどうかをチェックしません(例:) {[1 1] [1 2] [4 5]}。次の場合は、この1行を追加します。

sets = cellfun(@unique, sets, 'UniformOutput',false);
于 2010-11-12T22:06:27.037 に答える
17

FileExchange でALLCOMB機能を試してください。

ベクトルを cell 配列に格納する場合は、次のように実行できます。

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
于 2010-11-12T16:07:07.177 に答える
13

この最新の回答は 2 つの追加の解決策を提供します。2 番目は(私の意見では)解決ndgrid策であり、セル配列の代わりに MATLAB の強力なコンマ区切りリストを適用してパフォーマンスを向上させることで、Amro の回答解決策を改善します。

  1. Neural Network Toolbox がある場合:combvec
  2. 通常そうであるように、ツールボックスを持っていない場合: 以下は、任意の数のセットに対してデカルト積を一般化する別の方法です。

アムロが回答で行ったように、コンマ区切りリストの構文 ( v{:}) は の入力と出力の両方を提供しますndgrid。違い (4 行目) は、コンマ区切りのリストを回避cellfunし、ここでも入力として適用することです。cell2matcat

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

と を使用するとcatreshape実行時間がほぼ半分になります。このアプローチは、別の質問に対する私の回答で実証され、より正式には Luis Mendo によって実証されました。

于 2014-04-24T00:30:10.310 に答える