2

I have many fibonacci numbers, if I want to determine whether two fibonacci number are adjacent or not, one basic approach is as follows:

  1. Get the index of the first fibonacci number, say i1
  2. Get the index of the second fibonacci number, say i2
  3. Get the absolute value of i1-i2, that is |i1-i2| If the value is 1, then return true. else return false.

In the first step and the second step, it may need many comparisons to get the correct index by using accessing an array.

In the third step, it need one subtraction and one absolute operation.

I want to know whether there exists another approach to quickly to determine the adjacency of the fibonacci numbers.

I don't care whether this question could be solved mathematically or by any hacking techniques.

If anyone have some idea, please let me know. Thanks a lot!

  • 1
    how many fibonacci numbers you have? i'm curious because fibonacci is a really fast growing sequence – yvs Oct 02 '16 at 15:07
  • 2
    Check if the fraction is between 0.6 and 1.7, if you sure that the numbers are actually members of the Fibonacci sequence. – Lutz Lehmann Oct 02 '16 at 15:10
  • Use your method for the 10 first Fibonacci numbers. For larger ones calculate the distance (i.e. the absolute value of their difference) between the quotient `F/f` of the largest Fibonacci `F` and the smaller `f` and the number `phi = (1 + sqrt(5))/2`. If the distance `|F/f - phi|` is less than, say `0.01` they are consecutive, otherwise they are not (as @LuzL said, as long as they are both Fibonacci). – Leandro Caniglia Oct 02 '16 at 15:25
  • Adjacent fibonacci numbers differ by an amount equal to the previous fibonacci number. If they're not adjacent, they should differ by more than that, at a minimum (if they are separated by only one other Fibonacci number), by the Fibonacci number between them. So simply look at the difference in the two numbers. If the diff is smaller than both, then they are adjacent. If not, then they're not. – Charles Bretana Oct 02 '16 at 15:31
  • you can get the index of the number with this [formula](https://en.wikipedia.org/wiki/Fibonacci_number#Recognizing_Fibonacci_numbers) or you can keep the number in order such that the index in the array correspond to the index in the sequence and do a binary search there, or better use a dictionary where the key are the fibonacci number and the value are its index – Copperfield Oct 02 '16 at 15:34
  • @yvs I may have almost one hundred fibonacci numbers, and I would use the determination operation hundreds of thousand of times, so I want to know whether there exists quick methods. – user3148602 Oct 03 '16 at 02:51

3 Answers3

6

No need to find the index of both number.

Given that the two number belongs to Fibonacci series, if their difference is greater than the min. number among them then those two are not adjacent. Other wise they are.

Because Fibonacci series follows following rule:

F(n) = F(n-1) + F(n-2) where F(n)>F(n-1)>F(n-2). 
So F(n) - F(n-1) = F(n-2) ,
=>  Diff(n,n-1) < F(n-1) < F(n-k) for k >= 1

Difference between two adjacent fibonaci number will always be less than the min number among them.

NOTE : This will only hold if numbers belong to Fibonacci series.

pseudo_teetotaler
  • 1,485
  • 1
  • 15
  • 35
  • Thanks a lot, it would need one subtraction and one comparison. Determine the minimum of the two would need some other computation, but I think it is good enough. – user3148602 Oct 03 '16 at 03:09
1

Simply calculate the difference between them. If it is smaller than the smaller of the 2 numbers they are adjacent, If it is bigger, they are not.

Each triplet in the Fibonacci sequence a, b, c conforms to the rule

c = a + b

So for every pair of adjacent Fibonaccis (x, y), the difference between them (y-x) is equal to the value of the previous Fibonacci, which of course must be less than x.

If 2 Fibonaccis, say (x, z) are not adjacent, then their difference must be greater than the smaller of the two. At minimum, (if they are one Fibonacci apart) the difference would be equal to the Fibonacci between them, (which is of course greater than the smaller of the two numbers).

Since for (a, b, c, d)

 since c= a+b
 and d = b+c
 then d-b = (b+c) - b  = c
Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
0

By Binet's formula, the nth Fibonacci number is approximately sqrt(5)*phi**n, where phi is the golden ration. You can use base phi logarithms to recover the index easily:

from math import log, sqrt

def fibs(n):
    nums = [1,1]
    for i in range(n-2):
        nums.append(sum(nums[-2:]))
    return nums

phi = (1 + sqrt(5))/2

def fibIndex(f):
    return round((log(sqrt(5)*f,phi)))

To test this:

for f in fibs(20): print(fibIndex(f),f)

Output:

2 1
2 1
3 2
4 3
5 5
6 8
7 13
8 21
9 34
10 55
11 89
12 144
13 233
14 377
15 610
16 987
17 1597
18 2584
19 4181
20 6765

Of course,

def adjacentFibs(f,g):
    return abs(fibIndex(f) - fibIndex(g)) == 1

This fails with 1,1 -- but there is little point for explicit testing special logic for such an edge-case. Add it in if you want.

At some stage, floating-point round-off error will become an issue. For that, you would need to replace math.log by an integer log algorithm (e.g. one which involves binary search).

On Edit:

I concentrated on the question of how to recover the index (and I will keep the answer since that is an interesting problem in its own right), but as @LeandroCaniglia points out in their excellent comment, this is overkill if all you want to do is check if two Fibonacci numbers are adjacent, since another consequence of Binet's formula is that sufficiently large adjacent Fibonacci numbers have a ratio which differs from phi by a negligible amount. You could do something like:

def adjFibs(f,g):
    f,g = min(f,g), max(f,g)
    if g <= 34:
        return adjacentFibs(f,g)
    else:
        return abs(g/f - phi) < 0.01

This assumes that they are indeed Fibonacci numbers. The index-based approach can be used to verify that they are (calculate the index and then use the full-fledged Binet's formula with that index).

John Coleman
  • 51,337
  • 7
  • 54
  • 119