Fibonacci Search Algorithm in Python

.This post deals with the Fibonacci search algorithm. It is quite similar to the binary search algorithm. It operates on sorted arrays. However, it partitions the array into unequal sizes in contrast to the binary search technique.

Prerequisites: Basics of python lists

Fibonacci Search Algorithm

The basic idea behind the algorithm is to find the smallest Fibonacci number greater than or equal to the length of the array. Let’s say that is the i-th Fibonacci number stored as ‘fn’.

We then take up (i-2)the Fibonacci number and check whether the required element is at that index, if not we proceed as in binary search. That is, we check if it is greater or smaller than the required number. If smaller, we decrement the Fibonacci numbers to (i-3)th and (i-1)th i.e. by 1. This indicates that we have eliminated approximately the first 1/3rd of the array. Moreover, we also keep an ‘elim’ factor (initialized as -1) which keeps track of the elements eliminated (all elements from 0 to elim are eliminated). Hence we will also set elim to this checked index value. If the checked index was greater than the element we are looking for, that’s even better as we have eliminated approximately the last 2/3rd of the array and we decrement the Fibonacci numbers by 2 in this case and the elim value remains unchanged.

This process is repeated as long as fn remains greater than¬† 1. That’s because, when fn is 1, fn_2 becomes 0 or doesn’t exist (becomes -ve). If the element is not found at the termination of the loop, the element is not present in the array.

Implementation using Python

Consider the following program for the implementation,

def fibonacci_search(arr,x):
    l = len(arr)
    elim = -1
    fn_2 = 0    #Two finbonacci numbers before fn
    fn_1 = 1    #One finonacci numbers before fn
    fn = fn_1+fn_2

    while fn<l:
        fn_1, fn_2 = fn, fn_1
        fn = fn_1+fn_2

    while fn>1:
        #Note: Searching after the 'elim' factor
        curr = min(elim+fn_2,l-1)  #To ensure index is within range

        if arr[curr] == x:
            return curr     #Returning the found index
        elif arr[curr] > x:   #Then element is first 1/3rd
            fn = fn_2
            fn_1 = fn_1 - fn_2
            fn_2 = fn_2 - fn_1   #Moving two down
        else:   #arr[curr] < x
            fn = fn_1
            fn_1 = fn_2
            fn_2 = fn - fn_1   #Moving 1 down
            elim = curr   #eliminating upto curr from 0 index
    return -1

In the output below, the search takes about 1.7 seconds to find the last element in an array having 10^7 elements

Fibonacci Search Algorithm in Python

Why Fibonacci Search?

This search method proves to be useful, particularly in cases where the element is in the first 1/3rd of the division, in any of the early iterations. If it is always in the last 2/3rd, then it is a little slower than binary search. Hence, this has a case-specific advantage. Note, however, that the element doesn’t need to be in the first 1/3rd in the first iteration itself. That would mean the element is at the beginning of the array and even linear search can narrow it down in a short time! If the element is in the first 1/3rd at least in the first few iterations, the algorithm is faster than binary search.

Moreover, we are using the Fibonacci series since as the series progresses, the ration of consecutive numbers approaches the golden ratio 1.618…,¬† hence it divides the array also in the same ratio.

And just to add a fact, the Fibonacci search does all the index calculations by using just addition or subtraction. Whereas, binary search uses division and multiplication. That used to be a harder process in the early years of the computing world. Hence, it was a more preferred method when it was introduced. Now, the difference may not be that pronounced.

Feel free to leave behind any sort of feedback, suggestions, doubts, below.

Leave a Reply

Your email address will not be published.