2013-11-20 2 views
3

Я пытаюсь создать все возможные 1xM векторы (слова) из вектора 1xN (алфавит) в MATLAB. N -> M. Например, я хочу создать все возможные 2x1 «слова» из 4x1 «алфавита» alphabet = [1 2 3 4];Создайте все возможные векторы Mx1 из вектора Nx1 в MATLAB

Я ожидаю, что результат, как:

[1 1] 
[1 2] 
[1 3] 
[1 4] 
[2 1] 
[2 2] 
... 

Я хочу сделать M вход для моей рутины, и я не знаю заранее. В противном случае я мог бы легко сделать это с помощью вложенных for-loops. В любом случае, чтобы это сделать?

+0

Вот вопрос, который дал мне ключ к компактному ответ: http://stackoverflow.com/questions/9834254/cartesian-product-in-matlab (Я буду признателен за то, что я знаю, что вы ищете «продукт для работы с матрицей») –

+0

@BenVoigt I [должен был это знать] (http://stackoverflow.com/questions/19991279/permutations-of-parameters-ie-cartesian- продукт в-а-многомерный-обр)! – chappjc

+0

Это было задано _ много раз. Вот возможные дубликаты: [Как сгенерировать все пары из двух векторов в MATLAB с помощью векторизованного кода?] (Http: // stackoverflow.com/questions/7446946/how-to-generate-all-pairs-from-two-vectors-in-matlab-using-vectorized-code) и [Создать все возможные комбинации элементов некоторых векторов] (http: // stackoverflow.com/questions/4165859/matlab-generate-all-possible-combinations-of-the-elements-of-some-vectors) –

ответ

1

Для того, чтобы получить все k -Письмо комбинации из произвольной alphabet, использовать

n = length(alphabet); 
aux = dec2base(0:n^k-1,n) 
aux2 = aux-'A'; 
ind = aux2<0; 
aux2(ind) = aux(ind)-'0' 
aux2(~ind) = aux2(~ind)+10; 
words = alphabet(aux2+1) 

alphabet может состоять из до 36 элементов (в соответствии с dec2base). Этими элементами могут быть номера или знаков.

Как это работает:

число 0, 1, ..., п^к-1, когда выражаются в базе п дают все группы к числам, взятым из 0, ..., n- 1. dec2base делает преобразование в базу n, но дает результат в виде строк, поэтому необходимо преобразовать в соответствующее число (это часть с aux и aux2). Затем добавим 1, чтобы сделать числа 1, ..., n. Наконец, мы индексируем alphabet с тем, чтобы использовать реальные буквы чисел алфавита.

Пример с буквами:

>> alphabet = 'abc'; 
>> k = 2; 

>> words 

words = 

aa 
ab 
ac 
ba 
bb 
bc 
ca 
cb 
cc 

Пример с номерами:

>> alphabet = [1 3 5 7]; 
>> k = 2; 

>> words 

words = 

    1  1 
    1  3 
    1  5 
    1  7 
    3  1 
    3  3 
    3  5 
    3  7 
    5  1 
    5  3 
    5  5 
    5  7 
    7  1 
    7  3 
    7  5 
    7  7 
+2

, когда 'base' больше 10, я не думаю, что вычитание-' 0'' трюк будет работать правильно. –

+0

Почему вычитание '0' превращает строку в число? @BenVoigt К сожалению, я фактически использую базу> 10, и она не работает, как вы сказали. – iab

+0

@BenVoigt Ты прав! Спасибо –

5

Попробуйте

[d1 d2] = ndgrid(alphabet); 
[d2(:) d1(:)] 

спараметрировать на M:

d = cell(M, 1); 
[d{:}] = ndgrid(alphabet); 
for i = 1:M 
    d{i} = d{i}(:); 
end 
[d{end:-1:1}] 

В общем, и на языках, которые не имеют ndgrid в своей библиотеке, путь к параметрирования для цикла гнездования использует рекурсию.

[result] = function cartesian(alphabet, M) 
    if M <= 1 
     result = alphabet; 
    else 
     recursed = cartesian(alphabet, M-1) 
     N = size(recursed,1); 
     result = zeros(M, N * numel(alphabet)); 
     for i=1:numel(alphabet) 
      result(1,1+(i-1)*N:i*N) = alphabet(i); 
      result(2:M,1+(i-1)*N:i*N) = recursed; % in MATLAB, this line can be vectorized with repmat... but in MATLAB you'd use ndgrid anyway 
     end 
    end 
end 
+0

Ха-ха, очень краткий! +1 – chappjc

+0

Ну, я не проверял его. Но он должен * работать, возможно, с некоторой настройкой. –

+0

Там, как заказанные, так и параметризованные! И протестирован, хотя на Matlab Mobile, поэтому я не могу легко вырезать + вставить здесь. –

0

использование функции ndgrid в Matlab

[a,b] = ndgrid(alphabet) 
+0

Вы случайно встретили ответ Бена Войгта? – chappjc

Смежные вопросы