2017-01-05 2 views
1

У меня есть способ найти все комбинации значений из списка списков. В настоящее время это может привести к следующей ошибке: OutOfMemoryError: GC overhead limit exceeded. Он отлично работает для небольших наборов данных, но ошибка возникает для больших наборов данных. Может кто-нибудь сказать, как исправить мой алгоритм?java - Генератор рекурсивных комбинаций заканчивается из памяти

Мой код выглядит следующим образом:

public static <T> List<List<T>> generate(List<List<T>> input, BiFunction<List<T>, T, Boolean> function) { 
    List<List<T>> output = new ArrayList<List<T>>(); 
    generate(input, 0, output, null, function); 
    return output; 
} 

private static <T> void generate(List<List<T>> input, int index, List<List<T>> output, List<T> current, BiFunction<List<T>, T, Boolean> function) { 

    int next = index + 1; 

    if (index == 0) { 
     current = new ArrayList<T>(); 
    } 

    for (T i : input.get(index)) { 
     List<T> temp = new ArrayList<T>(current); 

     if (function == null || !function.apply(temp, i)) { 
      temp.add(i); 

      if (next >= input.size()) { 
       output.add(temp); 
      } 
      else { 
       generate(input, next, output, temp, function); 
      } 
     } 
    } 
} 
+0

Кто сказал, что проблема с вашим алгоритмом? – shmosel

+0

Скорее всего, ваша проблема в этой строке 'List temp = new ArrayList (current);' поскольку он копирует элементы в новый список. Любая причина, по которой 'current' не используется напрямую, не упаковывая его в' temp'? Также, если вы обрабатываете большие наборы данных, лучше не использовать рекурсию, так как java не имеет оптимизации хвостового вызова, и вы столкнетесь с ошибками Stackoverflow. – kjsebastian

+0

Вы рассчитали, сколько комбинаций возможно? Он быстро растет. – Nayuki

ответ

0

Чтобы решить эту проблему, я воспользовался параметром BiFunction, чтобы исключить более недействительные комбинации наборов во время создания.

0

вы также можете попробовать память увеличения вашей виртуальной Java-машины, предоставляя параметров -Xms. если вы работаете с вашим eclipse, вы можете указать это в файле eclipse.ini, который присутствует в вашем домашнем каталоге Eclipse. вы можете изменить параметр, например, от -Xms128m до -Xmx512m. Другой альтернативой может быть попытка разбить вход на более мелкие куски для рекурсивного метода, тем самым следуя шаблону mapreduce.

+0

Я предпочел бы оптимизировать свое решение, а не увеличивать память, если это возможно. – user3499973

+0

как насчет разделения входа на более мелкие куски, так что рекурсивный метод не должен иметь дело со слишком большими данными в данный момент времени. Это будет компромисс между скоростью и памятью. вы можете решить проблему памяти, но время обработки может увеличиться – hhafeez

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