Как сгенерировать все пары из двух векторов в MATLAB с использованием векторизованного кода?

42

Мне не раз приходилось генерировать все возможные пары двух векторов в MATLAB, которые я делаю для циклов, которые занимают несколько строк кода i.e.

vec1 = 1:4;
vec2 = 1:3;
i = 0;
pairs = zeros([4*3 2]);
for val1 = vec1
    for val2 = vec2
         i = i + 1;
         pairs(i,1) = val1;
         pairs(i,2) = val2;
    end
end

Создает...

1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1 
4 2
4 3

Должен быть лучший способ сделать это, что больше MATLAB'esque?

n.b. nchoosek не выполняет обратные пары, которые мне нужны (т.е. 2 1, а также 1 2), я не могу просто отменить и добавить вывод nchoosek, потому что симметричные пары будут включены дважды.

Теги:
combinations

7 ответов

80
Лучший ответ

Try

[p,q] = meshgrid(vec1, vec2);
pairs = [p(:) q(:)];

См. документацию MESHGRID. Хотя это не совсем то, для чего предназначена эта функция, но если вы прищурились, что то, о чем вы просите, это именно то, что она делает.

  • 1
    Это блестяще. Я знал как meshgrid и сериализацию 2d векторов, но никогда не думал об их использовании таким образом.
10

Вы можете использовать

a = 1:4;
b = 1:3;
result = combvec(a,b);
result = result'
  • 1
    Обратите внимание, что для этого требуется набор инструментов Neural Network. Для тех, у кого это есть, это кажется лучшим решением.
  • 0
    Как это лучше, чем принятое решение, поскольку оно обобщает на несколько векторов.
Показать ещё 1 комментарий
3

Другое решение для коллекции:

[idx2, idx1] = find(true(numel(vec2),numel(vec1)));
pairs = [reshape(vec1(idx1), [], 1), reshape(vec2(idx2), [], 1)];
  • 0
    +1: я удалил свое решение, мне больше нравится твое. Я vec1 vec2 исправить это, чтобы получить комбинации vec1 и vec2 .
  • 0
    @EitanT: Не нужно менять форму. Индексы из find всегда должны быть векторами столбцов, а также vec1(idx1) и т. Д.
Показать ещё 2 комментария
3

Вы можете сделать это, реплицируя матрицы с помощью repmat, а затем превратив результат в вектор-столбец с помощью reshape.

a = 1:4;
b = 1:3;
c = reshape( repmat(a, numel(b), 1), numel(a) * numel(b), 1 );
d = repmat(b(:), length(a), 1);
e = [c d]

e =

     1     1
     1     2
     1     3
     2     1
     2     2
     2     3
     3     1
     3     2
     3     3
     4     1
     4     2
     4     3

Конечно, вы можете избавиться от всех промежуточных переменных из приведенного выше примера.

1

Вы можете использовать простые старые матричные операции, например. в

x = [3,2,1];
y = [11,22,33,44,55];
v = [(ones(length(y),1) * x)(:), (ones(length(x), 1) * y)'(:)]

Изменить: это синтаксис Octave, MATLAB будет выглядеть следующим образом:

x = [3,2,1];
y = [11,22,33,44,55];
A = ones(length(y),1) * x;
B = (ones(length(x), 1) * y)';
v = [A(:) B(:)]

в обоих случаях результат будет

v =
 3    11
 3    22
 3    33
 3    44
 3    55
 2    11
 2    22
 2    33
 2    44
 2    55
 1    11
 1    22
 1    33
 1    44
 1    55
  • 0
    Это не правильный синтаксис MATLAB.
  • 0
    @gnovice спасибо, мой плохой. Я исправил синтаксис.
1

Здесь больше MATLAB'esque способ найти комбинации. Это также можно легко расширить до более чем 2 векторов (а также не численных комбинаций):

v1 =   1:  1:  3;
v2 =  11: 11: 44;
v3 = 111:111:555;

dimensions = cellfun(@numel, {v1,v2,v3});

[i1,i2,i3] = ind2sub(dimensions, 1:prod(dimensions));

combinations = [v1(i1); v2(i2); v3(i3)]'
0

Что вы ищете, это декартовой продукт

cartprod - это функция, которая его реализует. Вы можете найти его в пакете линейной алгебры, поэтому вам нужно будет сделать:

   >> pkg install -forge linear-algebra
   >> pkg load linear-algebra 
   >> sortrows(cartprod(1:4,1:3))                                            
    ans =                                                                                           
       1   1                                                                  
       1   2                                                                  
       1   3                                                                  
       2   1                                                                  
       2   2                                                                  
       2   3                                                                  
       3   1                                                                  
       3   2                                                                  
       3   3                                                                  
       4   1                                                                  
       4   2                                                                  
       4   3    
  • 0
    Для чего бы то ни было, функция обмена, утверждающая, что она делает то же самое, также доступна в обмене файлами MATLAB .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню