Matlab, альтернатива вложенному циклу - PullRequest
0 голосов
/ 01 апреля 2012

В настоящее время мой файл .m выглядит следующим образом

 for a = 1 : 47
  for b = a+1 : 48
   for c = b+1 : 49
    for d = c+1 : 50
     fprintf('%d %d %d %d \n',a,b,c,d);
    end
   end
  end

Я пытаюсь создать наборы из 4 элементов из 1,2,3, ... 50, т. Е. {1,2,3,4}, {1,2,3,5}, ... {1,2,3,50}, {1,2,4,5}, .. {47, 48, 49, 50}.Следовательно, всего существует C (50,4) множеств.Я хотел бы знать, есть ли более быстрые альтернативы, чем эти 4 вложенных цикла?Порядок в одном наборе не обязательно в порядке возрастания.т.е. это нормально, если код генерирует {4,1,2,3}, а не {1,2,3,4}.

Ответы [ 2 ]

1 голос
/ 01 апреля 2012

Забавная проблема!

Перечисление всех возможных комбинаций хорошо изучено, и существует множество решений.См. Например этот вопрос .Вот простое, эффективное решение для разумного выбора N, k с использованием двух удобных функций Matlab, nchoosek и arrayfun:

% test function for benchmarking
foo = @(a, b, c, d) ( a + b + c + d );

% see detailed timings at https://gist.github.com/2295957
tic;
C = nchoosek([1:50], 4);     % all 230,300 4-tuple combinations
result = arrayfun(@(k) foo(C(k,1),C(k,2),C(k,3),C(k,4)), 1:length(C));
toc;
0 голосов
/ 01 апреля 2012

Похоже, что назначение кода можно определить как вызов SomeFunction со всеми возможными входами, которые удовлетворяют следующим условиям:

  1. A D <= 50 </li> (подразумевается, что A, B, C, D являются целыми числами)

Если это так, вы можете сделать этот код намного быстрее, исключиввнешняя петля.То есть замените for N = 1:50 на N = 50.На самом деле, вы вызываете одни и те же комбинации много раз.Например, замена первой строки на N = 4:6 возвращает следующий результат ("*" строки ed дублированы):

 A     B     C     D
 N=4
 1     2     3     4

 N=5
 1     2     3     4 *
 1     2     3     5
 1     2     4     5
 1     3     4     5
 2     3     4     5

 N=6
 1     2     3     4 *
 1     2     3     5 *
 1     2     3     6
 1     2     4     5 *
 1     2     4     6 
 1     2     5     6
 1     3     4     5 *
 1     3     4     6 
 1     3     5     6
 1     4     5     6
 2     3     4     5 *
 2     3     4     6
 2     3     5     6
 2     4     5     6
 3     4     5     6
...