MATLAB: комбинации произвольного числа массивов ячеек - PullRequest
5 голосов
/ 13 декабря 2011

Есть ли в MATLAB командная или однострочная стратегия, которая будет возвращать все комбинации компонентов n массивов ячеек, взятых n за раз?

Пример того, чего я хочу достичь:

A = {'a1','a2'};
B = {'b1','b2','b3'};
C = combinations(A,B)
C = {'a1','b1' ;
     'a1','b2' ;
     'a1','b3' ;
     'a2','b1' ;
     'a2','b2' ;
     ... }

Команда сможет принять произвольное количество аргументов, и результат в примере будет иметь столько столбцов, сколько аргументов для функции. (Конечно, приведенный выше синтаксис предназначен только для иллюстрации и для любого метода, который будет генерировать результаты независимо от формата, который будет соответствовать требованиям)

РЕДАКТИРОВАТЬ: аналогичные вопросы были заданы для матриц вместо ячеек, например, ссылка . Многие решения указывают на представление FEX allcomb , но все такие решения являются просто обертками вокруг ndgrid, которые работают только с двойными числами. Любые предложения для нечисловых наборов?

Ответы [ 2 ]

6 голосов
/ 13 декабря 2011

Несмотря на то, что я адресую это в моем ответе на связанный / почти повторяющийся вопрос , я публикую здесь другую версию моего решения, так как кажется, что вы хотите обобщенное решение, и мой другой ответ является специфическим для случая трех входных наборов.Вот функция, которая должна делать то, что вы хотите для любого числа входов массива ячеек:

function combMat = allcombs(varargin)
  sizeVec = cellfun('prodofsize', varargin);
  indices = fliplr(arrayfun(@(n) {1:n}, sizeVec));
  [indices{:}] = ndgrid(indices{:});
  combMat = cellfun(@(c,i) {reshape(c(i(:)), [], 1)}, ...
                    varargin, fliplr(indices));
  combMat = [combMat{:}];
end

А вот как вы бы ее назвали:

>> combMat = allcombs(A, B)

combMat = 

    'a1'    'b1'
    'a1'    'b2'
    'a1'    'b3'
    'a2'    'b1'
    'a2'    'b2'
    'a2'    'b3'
5 голосов
/ 13 декабря 2011

2-строчная стратегия:

 A = {'a1','a2'};
 B = {'b1','b2','b3'};

[a b]=ndgrid(1:numel(A),1:numel(B));
C= [A(a(:))' B(b(:))']

C = 
    'a1'    'b1'
    'a2'    'b1'
    'a1'    'b2'
    'a2'    'b2'
    'a1'    'b3'
    'a2'    'b3'
...