2017-01-05 6 views
1

aus dem Speicher ausgeführt habe ich eine Methode, um alle Kombinationen von Werten aus einer Liste von Listen zu finden. Derzeit kann es den folgenden Fehler verursachen: OutOfMemoryError: GC overhead limit exceeded. Es funktioniert gut für kleine Sätze von Daten, aber der Fehler tritt bei größeren Datensätzen auf. Kann jemand sagen, wie ich meinen Algorithmus reparieren kann?java - rekursive Kombination Generator

Mein Code ist wie folgt:

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

sagte, dass es ein Problem mit Ihrem Algorithmus? – shmosel

+0

Wahrscheinlich ist Ihr Problem in dieser Zeile 'Liste temp = new Arraylist (Strom);' da sie kopiert die Elemente auf neue Liste. Gibt es irgendeinen Grund, warum 'current' nicht direkt verwendet wird, ohne es in' temp' zu verpacken? Auch wenn Sie große Datenmengen verarbeiten, ist es möglicherweise besser, keine Rekursion zu verwenden, da Java keine Tail-Call-Optimierung hat und Sie auf Stackoverflow-Fehler stoßen werden. – kjsebastian

+0

Haben Sie berechnet, wie viele Kombinationen möglich sind? Es wächst schnell groß – Nayuki

Antwort

0

Um dies zu lösen, nahm ich besser die Vorteile der BiFunction Parameter mehr ungültige Kombination zum Zeitpunkt der Schöpfung setzt auszuschließen. Wer

0

Sie können auch versuchen, die Steigerung Ihrer Java Virtual Speicher der Maschine durch den Parameter -Xms bereitstellt. Wenn Sie von Ihrer Eclipse aus arbeiten, können Sie dies in der Datei eclipse.ini angeben, die in Ihrem Eclipse-Ausgangsverzeichnis vorhanden ist. Sie können den Parameter beispielsweise -Xms128m in -Xmx512m ändern. Eine andere Alternative kann sein, zu versuchen, die Eingabe in kleinere Stücke für das rekursive Verfahren aufzuteilen, wodurch dem Mapreduce-Muster gefolgt wird.

+0

Ich würde lieber meine Lösung optimieren, anstatt den Speicher, wenn möglich, zu erhöhen. – user3499973

+0

wie Sie die Eingabe in kleinere Blöcke aufteilen, so dass die rekursive Methode nicht mit zu großen Daten zu einer bestimmten Zeit umgehen muss. Dies wird zwischen Geschwindigkeit und Speicher abgewogen werden. Sie könnten das Speicherproblem lösen, aber die Verarbeitungszeit kann sich erhöhen – hhafeez