2017-01-05 20 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

おそらくあなたの問題はこの行にあります。リスト temp = new ArrayList (現在);これは要素を新しいリストにコピーするためです。 'current'が' temp'でラップせずに直接使われない理由は何ですか?大規模なデータセットを処理している場合は、Javaがテールコールの最適化を持たず、Stackoverflowエラーに遭遇するので、再帰を使用しない方が良いかもしれません – kjsebastian

+0

可能な組み合わせの数は計算しましたか?それはすぐに大規模に成長する – Nayuki

答えて

0

これを解決するために、BiFunctionパラメータを利用して、より無効な組み合わせセットを作成時に除外しました。

0

あなたは、パラメータ-Xmsを提供することにより、あなたのJava仮想マシンのメモリを増やしてみてくださいすることができます。 Eclipseから実行している場合は、Eclipseのホーム・ディレクトリーにあるeclipse.iniファイルでこれを指定できます。 -Xms128mのようなパラメータを-Xmx512mに変更することができます。もう1つの選択肢は、再帰的方法のために入力をより小さなチャンクに分割して、それによりマップ還元パターンに従うことである。

+0

可能であれば、メモリを増やすのではなく、ソリューションを最適化したいと思います。 – user3499973

+0

入力を小さなチャンクに分割すると、再帰的な方法では所定の時間に大きすぎるデータを処理する必要がなくなります。これは速度とメモリの間でトレードオフになります。メモリの問題は解決するかもしれませんが、処理時間は長くなるかもしれません – hhafeez

関連する問題