I am trying to write an optimized fibonacci as an assignment to be able to compute fib(300) and fib(8000). Here is what I have so far (map is a HashMap).
public static BigInteger fibMemo(int n) {
if (n <= 1){
return BigInteger.valueOf(n);
}
if (!map.containsKey(n)){
map.put(n, fibMemo(n-1).add(fibMemo(n-2)));
}
return map.get(n);
}
When I call
System.out.println("300: " + FibonacciMemo.fibMemo(300));
on its own, it works just fine. Also,
System.out.println("8000: " + FibonacciMemo.fibMemo(8000));
works fine if I comment out the previous call to fib(300). But if I keep both calls I get a stack overflow on the recursive fibMemo. This seems very strange to me. Could someone please clarify the situation? Thanks in advance.
Here is the code:
import java.util.HashMap; // Import Java's HashMap so we can use it
import java.math.BigInteger;
public class FibonacciMemo {
private static HashMap<Integer, BigInteger> map = new HashMap<Integer, BigInteger>();
/**
* The classic recursive implementation with no memoization. Don't care
* about graceful error catching, we're only interested in performance.
*
* @param n
* @return The nth fibonacci number
*/
public static int fibNoMemo(int n) {
if (n <= 1) {
return n;
}
return fibNoMemo(n - 2) + fibNoMemo(n - 1);
}
/**
* Your optimized recursive implementation with memoization.
* You may assume that n is non-negative.
*
* @param n
* @return The nth fibonacci number
*/
public static BigInteger fibMemo(int n) {
// YOUR CODE HERE
if (n <= 1){
return BigInteger.valueOf(n);
}
if (!map.containsKey(n)){
map.put(n, fibMemo(n-1).add(fibMemo(n-2)));
}
return map.get(n);
}
public static void main(String[] args) {
// Optional testing here
String m = "Fibonacci's real name was Leonardo Pisano Bigollo.";
m += "\n" + "He was the son of a wealthy merchant.\n";
System.out.println(m);
System.out.println("300: " + FibonacciMemo.fibMemo(300));
System.out.println("8000: " + FibonacciMemo.fibMemo(8000));
// 46th Fibonacci = 1,836,311,903
// 47th Fibonacci = 2,971,215,073
}
}
The issue is the size of thread stack which can get exhausted fir a large number of recursive calls. The solution is to provide enough stack size. You could try running the app using a vm arg
-Xss
. I tried with-Xss2m
and it worked fine.