2017-11-02 1 views
0

Wenn die Funktion wie folgtmemoization mit Vavr scheint incosistent

static Function1<BigInteger, BigInteger> fibonacci = Function((BigInteger value) -> 
      value.equals(BigInteger.ZERO) ? BigInteger.ZERO 
        : value.equals(BigInteger.ONE) ? BigInteger.ONE 
        : value.equals(BigInteger.valueOf(2)) ? BigInteger.ONE 
        : Program.fibonacci.apply(value.subtract(BigInteger.ONE)).add(Program.fibonacci.apply(value.subtract(BigInteger.valueOf(2)))) 
    ).memoized(); 

definiert und aufgerufen

System.out.println(fibonacci.apply(BigInteger.valueOf(1000))); 

Es ist sehr schnell berechnet. Allerdings, wenn ich die memoized() bewegen Variable, um als

static Function1<BigInteger, BigInteger> fibonacci = Function((BigInteger value) -> 
      value.equals(BigInteger.ZERO) ? BigInteger.ZERO 
        : value.equals(BigInteger.ONE) ? BigInteger.ONE 
        : value.equals(BigInteger.valueOf(2)) ? BigInteger.ONE 
        : Program.fibonacci.apply(value.subtract(BigInteger.ONE)).add(Program.fibonacci.apply(value.subtract(BigInteger.valueOf(2)))) 
    ); // Removed memoized() from here 

folgt und rief

fibonacci.memoized().apply(BigInteger.valueOf(1000)); 

Es dauert sehr lange, als ob memoized() nicht angewandt wurde.

Was könnte der Grund dafür sein?

+1

Weil a) die Rekursion nicht auf dem memoisierten Formular aufgerufen wird, b) der ganze Punkt des Memoisierens ist, dass Sie das Memo speichern und nicht jedes Mal ein neues Memo erstellen müssen. –

+0

Ich denke, ich habe es. Mein zweites Beispiel ist nur für 1000 angemeldet. Die anderen Werte werden auf rohen ** fibonacci() ** aufgerufen. Können Sie die Frage beantworten, damit ich sie akzeptiere? – ozgur

+0

Warum verwenden Sie nicht die Formel von Binet zur Berechnung von Fibonacci? http://mathworld.wolfram.com/BinetsFibonacciNumberFormula.html –

Antwort

2

Weil a) die Rekursion nicht auf dem memoisierten Formular aufgerufen wird, b) der ganze Punkt des Memoisierens ist, dass Sie das Memo speichern und nicht jedes Mal ein neues Memo erstellen müssen.

Program.fibonacci ist in sich selbst definiert, so ruft die Rekursion diese Version, nicht die Memo-Version.