Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Fibonacci Algorithms and their different manifestations. Which is the best?  RSS feed

 
Rooks Forgenal
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
GOALS:
The function will accept only one parameter (that of 'n').
The function uses nothing but temporary variables (function variables)
The function returns the correct Fibonacci number at the passed index (i.e. x_fibonacci(0) = 1)
The function must accept a parameter from 0 to 30 and produce the correct answer.

The first is a recursive function. I would love some constructive criticism on this code. My recursive abilities are pretty rusty.

The second version is as simple as I could think to make it. It just steps forward and was reminiscent of a bubble sort algorithm. I wonder if it can be made better? I did it kind of fast.

This one is my favorite. It is a fine example of why direct translation of mathematics to code can get VERY bulky. However, it adds some usefulness by allowing a user access to combinatorial mathematics. If you were to look at this for the purpose of making it better, what would you change?


Why would I make these and post them to the forum? Well the last Fibonacci post was in 2003 and I was bored.
 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey,

the recursive method could be a bit shorter ;-) ...



The problem with this recursive method is the following.

Imagine you pass 5. Then in the first cycle, fibonacci is again called for the value 4 (a -1) and 3 (a-2). Again in the next cycle you would call with a value of 3 (a-1) and 2 (a-2). You see that there are redundant method calls, which easily add up. Even though a recursive approach might seem as the more elegant one, in practice it mostly is the one you would not opt for compared to an iterative approach. You add up stack over stack, causing the process to slow down and risking to run into a StackOverflowError ...
 
Rooks Forgenal
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh snap. Talk about an improvement!
 
Paul Clapham
Sheriff
Posts: 22823
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want to try something completely different, you could try writing a program which uses this:

Fibonacci_number#Closed_form_expression
 
Rooks Forgenal
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have to think that due to round off error, I could never truly get a reliable answer. I think I could do it if I used Scheme because it keeps things like root 5 as fractional instead of decimal. Even so, I think the round off would bite me in the end (unless I just Math.round(n);)

Also, I ran the more succinct solution given by Sebastian Janisch and it is noticeably slower at indexes > 40 than my recursive algorithm. Does anyone know how to calculate Big(O) of each to see why that is? I had to fix it to fit the requirements and it might be my change that caused the problem.


Times in nano seconds were:
a_fibonacci = 36,000
b_fibonacci = 6,100
c_fibonacci = 17,515
d_fibonacci = 11,606,422,821

If anyone can explain the difference I would be very happy. Thanks in advance.
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As you will see from Sebastian Janisch's reply, you have a subtle error in your assignment; fib(0) is not 1 but 0. you should have fib(1) = 1 and fib(2) = 1 in the commonest Fibonacci series, and fib(10) = 55. work out why he has marked the method static, which I believe is correct.
Note you can shorten SJ's solution to one statement and avoid two returns in the same method:
return a == 1 || a == 2 ? 1 : fib(a - 1) + fib(a - 2);

It is possible to pass two parameters to a Fibonacci method and have it run in linear time, and it is possible to pass 4 parameters and run in logarithmic time (reference on this thread), but I can't remember how to do it at the moment.
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would change your method:

 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The recursive method runs in 1.618^n time. I shall let you work out where the 1.618 comes from.

You almost certainly won't suffer stack overflow or memory lack, however; values are taken off the stack almost as fast as they are put on it.
The way to get a method taking a single parameter and run in linear time is to pass that parameter on to a private helper method which takes two parameters and does the actual recursion.
 
fred rosenberger
lowercase baba
Bartender
Posts: 12563
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would say the first implementation is the worst, because it doesn't meet the specifications:

The function will accept only one parameter (that of 'n').

public int a_fibonacci(int n, int... values)
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!