Advertisements

Baba wrote:
> Level: beginner
>
> I would like to know how to approach the following Fibonacci problem:
> How may rabbits do i have after n months?
>
> I'm not looking for the code as i could Google that very easily. I'm
> looking for a hint to put me on the right track to solve this myself
> without looking it up.
>
> my brainstorming so far brought me to a stand still as i can't seem to
> imagine a recursive way to code this:
>
> my attempted rough code:
>
> def fibonacci(n):
> # base case:
> result = fibonacci (n-1) + fibonacci (n-2)
>>> this will end up in a mess as it will create overlapping recursions

I don't think this is the base case. The base case would be one or more
values of `n` that you already know the fibonacci number for. Your
recursive function can just test for those and return the right answer right
away. The the expression you've coded contains a good way to handle the
non-base cases. There's no such problem as "overlapping recursions".

Advertisements

I suggest you to memoize results in order to prevent overlapping recursion.

Regards,
Matteo

On Sun, Aug 29, 2010 at 2:23 AM, Ben Finney <> wrote:
> Baba <> writes:
>
>> my brainstorming so far brought me to a stand still as i can't seem to
>> imagine a recursive way to code this:
>>
>> my attempted rough code:
>>
>> def fibonacci(n):
>> # base case:
>> result = fibonacci (n-1) + fibonacci (n-2)
>> >> this will end up in a mess as it will create overlapping recursions
>
> It also never returns anything (which, in Python, means it returns the
> None object).
>
> Worse, it will endlessly recurse; every time it's called it will call
> itself (twice).
>
> Perhaps a way to approach the problem is: How will your function know
> when *not* to call itself? What will it do instead? Try writing that
> case first, and then write the rest of it on that basis.
>
> --
> \ “Science is a way of trying not to fool yourself. The first |
> `\ principle is that you must not fool yourself, and you are the |
> _o__) easiest person to fool.” —Richard P.. Feynman, 1964 |
> Ben Finney
> --
> http://mail.python.org/mailman/listinfo/python-list
>

On Sat, 28 Aug 2010 16:12:36 -0700, Baba wrote:
> Level: beginner
>
> I would like to know how to approach the following Fibonacci problem:
> How may rabbits do i have after n months?
>
> I'm not looking for the code as i could Google that very easily. I'm
> looking for a hint to put me on the right track to solve this myself
> without looking it up.
>
> my brainstorming so far brought me to a stand still as i can't seem to
> imagine a recursive way to code this:

Perhaps you need to start with a simpler case to get your head around the
ideas. Let's look at factorial first.

is the most basic form you can have. Notice that you must *return*
something. That's basic Python syntax -- if you don't call return, the
function will return the special None object, which is not what you want.

More generally, you could have multiple base cases and multiple recursive
cases, not necessarily one of each. But there must be at least one non-
recursive expression that gets returned, or the recursion can never
terminate.

Mathematically, there is nothing wrong with overlapping recursion. It
will work, and Python can handle it easily.

But in practical terms, it can lead to great inefficiency. In this
example, it should be avoided because it is slow. Very slow. To calculate
the nth Fibonacci number using naive recursion requires *many* calls:

As you can see, the number of calls is also calculable by a recursive
expression R:

R(0) = R(1) = 1
R(n) = R(n-1) + R(n-2) + 1

This is very similar to the Fibonacci recursion, only it grows more
quickly. But I digress...

You can make the recursive version more efficient if you give it a
memory. In the call to fib(5), for example, it ends up calling fib(4)
once, fib(3) twice, fib(2) three times, fib(1) four times, and fib(0)
twice. If it could remember each value once it saw it, it could
potentially save nine calls (out of fifteen). That's a less inefficient
use of recursion. Think about ways to give it a short-term memory.

You can make it even more efficient by giving fib() a long-term cache, so
that each call to fib(5) requires one cache lookup rather than six (or
fifteen) recursive calls. Other than the first time, obviously. This is
called memoisation, but again I digress.

On 08/29/2010 01:12 AM, Baba wrote:
> Level: beginner
>
> I would like to know how to approach the following Fibonacci problem:
> How may rabbits do i have after n months?
>
> I'm not looking for the code as i could Google that very easily. I'm
> looking for a hint to put me on the right track to solve this myself
> without looking it up.
>
> my brainstorming so far brought me to a stand still as i can't seem to
> imagine a recursive way to code this:
>
> my attempted rough code:
>
> def fibonacci(n):
> # base case:
> result = fibonacci (n-1) + fibonacci (n-2)
>>> this will end up in a mess as it will create overlapping recursions
>
> OR
>
> def fibonacci(n):
> # base case:
> fibonacci(n+2) - fibonacci(n+1) - n = 0
>>> this too would create overlapping recursions
>
Hi Baba,

Let's take another example: factorials:
Trivial, but you 'just have to apply the same techniques FIbonacci

n! = 1 * 2 * 3 . . . * n

Very first thing is to always find a trivial case, or the terminal
condition.
Tjis is, when you reduced the problem to the most trivial case(s), for
which you don't need anymore recursion

for factorials this would be
0! = 1
for Fibonacci you might have multiple trivial cases

On Aug 29, 3:25 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> Mathematically, there is nothing wrong with overlapping recursion. It
> will work, and Python can handle it easily.

Based on the advice by Steven and Mel i tried my initial 'guess' and
it does seem to work fine. When looking at it using pencil and paper i
thought "well, each recursive call will call 2 new ones and if n is
large i will have a huge overlap, so it probably is the wrong
approach". However it turns out to be fine in principle. It can be
handled, as Steven pointed out.

> But in practical terms, it can lead to great inefficiency. In this
> example, it should be avoided because it is slow. Very slow. To calculate
> the nth Fibonacci number using naive recursion requires *many* calls:
>
> You can make it even more efficient by giving fib() a long-term cache, so
> that each call to fib(5) requires one cache lookup rather than six (or
> fifteen) recursive calls. Other than the first time, obviously. This is
> called memoisation, but again I digress.
>

I looked memoisation up and decided that for now i will not go near
it. First i will try to build up some bacic skills but thank you very
much for the hint. Memoisation will certainly be on the list of future
exercises.

However, the idea that memoisation is needed to make the computation
more efficient confirms my initial feeling that a 'simple' recursive
approach is somewhat not ideal.

So here's my code. It does still cause me one headache. If i use
f(0)=0
and f(1)=1 as base cases the result will be 144. I was expecting the
result to be the next value in the series (233)...
If i use f(1)=1 and f(2)=2 as base cases them i get my expected
result. I assume this has to do with our understanding/defining the
start of the Fibonacci series?

Baba <> writes:
> Level: beginner
>
> I would like to know how to approach the following Fibonacci problem:
> How may rabbits do i have after n months?
>
> I'm not looking for the code as i could Google that very easily. I'm
> looking for a hint to put me on the right track to solve this myself
> without looking it up.

fib(n) = fib(n-1) + fib(n-2), so you need the two previous values to
compute the next one (that's the main difference between fibonacci and
factorial). So here is a hint: instead of computing only fib(n), compute
a pair (fib(n),fib(n-1)). It now becomes a problem very similar to
factorial: for instance, what's (fib(7),fib(6)) if you have the values
of (fib(6),fib(5))? Now write a recursive function fib2(n) that returns
the last two values. And a simple wrapper fib(n) that calls fib2(n) and
returns the first element of the pair.

Hi Baba,
> So here's my code. It does still cause me one headache. If i use
> f(0)=0
> and f(1)=1 as base cases the result will be 144. I was expecting the
> result to be the next value in the series (233)...
> If i use f(1)=1 and f(2)=2 as base cases them i get my expected
> result. I assume this has to do with our understanding/defining the
> start of the Fibonacci series?
>
>
> def r_fib(n):
> if n == 1: return 1
> elif n == 2: return 2
> else: return r_fib(n-2) + r_fib(n-1)
>
> print r_fib(12)
>

On Sun, 29 Aug 2010 06:43:40 -0700, Baba wrote:
> So here's my code. It does still cause me one headache. If i use f(0)=0
> and f(1)=1 as base cases the result will be 144. I was expecting the
> result to be the next value in the series (233)...

That's because you're not generating the Fibonacci series, but a similar
unnamed(?) series with the same recurrence but different starting
conditions. The Fibinacci series starts with f(0)=1, f(1)=1.

> If i use f(1)=1 and
> f(2)=2 as base cases them i get my expected result.

In article <i5c7ke$207$>, Mel <> wrote:
>Baba wrote:
>
>> Level: beginner
>>
>> I would like to know how to approach the following Fibonacci problem:
>> How may rabbits do i have after n months?
>>
>> I'm not looking for the code as i could Google that very easily. I'm
>> looking for a hint to put me on the right track to solve this myself
>> without looking it up.
>>
>> my brainstorming so far brought me to a stand still as i can't seem to
>> imagine a recursive way to code this:
>>
>> my attempted rough code:
>>
>> def fibonacci(n):
>> # base case:
>> result = fibonacci (n-1) + fibonacci (n-2)
>>>> this will end up in a mess as it will create overlapping recursions
>
>I don't think this is the base case. The base case would be one or more
>values of `n` that you already know the fibonacci number for. Your
>recursive function can just test for those and return the right answer right
>away. The the expression you've coded contains a good way to handle the
>non-base cases. There's no such problem as "overlapping recursions".

[Didn't you mean: I don't understand what you mean by overlapping
recursions? You're right about the base case, so clearly the OP
uses some confusing terminology.]

I see a problem with overlapping recursions. Unless automatic memoizing
is one, they are unduely inefficient, as each call splits into two
calls.

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!