Beginning of small algorithm column: Fibonaci sequence of DFS

Preface

  Starting today, I will introduce you some topics or summary notes during the period when I was learning software algorithms . I am not a software class or ACM , so don’t expect me to explain Leetcode or Linkcode to you . , It is really helpless to encounter Hard questions.


Insert picture description here

  I will seldom use some words about computer technical terms, and use some intuitive data to reflect~

  Young people don’t speak code morality , various pruning optimizations, various memory methods, various exit conditions , cough, cough, cough... ( hematemesis)

CSDN (゜-゜) Cheers つロ

Brief Introduction to DFS

  Today I started with **DFS (Depth First Search)**. When I first started learning, the teacher gave me a test question. I was just ashamed, DFS? Maybe it was mentioned in the basics or when learning C language, simple structure is still possible. I will start to do some questions later, huh?

  But for now it is actually DFS to routine first, decision logic based, pruning optimization ideas, supplemented by an algorithm .

  Ok, let’s briefly introduce, depth-first search DFS and breadth-first search BFS are two very important software algorithms. There are many applications in graph theory, such as shortest path, global search and other optimization problems.

  Depth first, that is, under the current established search strategy, continue to proceed, one way to the dark. It can be said that if it doesn't work, exit the current loop, change the search strategy, and continue to loop until you find the exit. Isn't it like a mouse walking through a maze?

Insert picture description here
  The meaning is easy to understand, I think there are three key points:

  1. The first is the search strategy, which is the core algorithm, needless to say

  2. The second is the transfer of parameters before and after the loop, that is, I will not take the road I have traveled, or pass through a failed road and pass other n similar roads without going directly, saving time and space, and passing some of the variables.

  3. The third is the exit condition, there is no exit condition, it is an infinite loop, Happy Ending!

  The above Key Point will be gradually reflected in the future content~ You don't have to worry too much, just be a small encyclopedia.


Implementation of Fibonaci using DFS

  Today I will start with Fibonaci (Fibonacci Sequence) and introduce DFS to everyone.

  The environment used is Windows10+Python3.7.

  The grammar is very simple, it is an explanatory language in itself, easy to understand.
  The Fibonacci sequence is very common: 1, 1, 2, 3, 5,...

  Starting from the third item, each item is the sum of the first two items. Suppose I ask for the nth item, do I need to know the n-1 and n-2th items, ask for the n-1th item, and also need to know the n-2th and n-3th items, and so on, It's a continuous looping process. When is it a head?

  We know that the first and second items are both 1, so when recursing to these two items, just return 1 directly . It's like being in a maze. There is a room on each floor. The rooms on each floor have the keys needed to open the upper floor. The rooms on the top floor have Oreos. How can you get Oreos?

Insert picture description here
  Intuitive thinking: You only need to go to the lowest floor and get the keys of the lowest two floors, then you can go straight up, keep the door open during this period, collect the keys until you open the room on the top floor.

  Take a look at the code:

def fibonaci():
    """
    Function: get n_th value in Fibonacci_array using DFS
    Returns: None
    """
    import time
    # input the index
    n=int(input())
    # core function
    def dfs(x):
        if x == 1 or x == 2:
            return 1
        else:
            # recursion step
            return dfs(x - 1) + dfs(x - 2)
    # record processing time
    start=time.time()
    # print answer
    print(dfs(n))
    print("Using {:.5f} s".format(time.time() - start))
    return

>>> fibonaci()
20
6765
Using 0.01405 s
>>> fibonaci()
35
9227465
Using 2.22722 s

  The above is the function of DFS to solve the n-th Fibonacci sequence written according to our thoughts. The time library is to calculate the execution time of the program. The core function is to recurse to the first or second term. Return 1 directly, otherwise the value corresponding to the first two items is solved through the function recursively.

  But when n is too large, you will find the results are slow. It took 2.22 seconds to solve the 35th term, which is simply unbearable.

  The reason is that every time we find the nth term, we must find the 0~n-1 term, and this process is the same in the sub-process, that is, when the n-1th term is obtained, the time complexity of the algorithm increases with N The increase of is exponentially increasing, and the time complexity is O(2^n), which is 2 to the nth power. The process of the algorithm can be visually seen as traversing a binary tree.

Insert picture description here

Memory Search in DFS

  There are many ways to improve, such as transforming to matrix multiplication and applying fast exponentiation, as well as memory search.

  Memory search is an optimized pruning strategy commonly used by DFS . The meaning of pruning is very vivid here, which is to remove unnecessary nodes and not recurse there.

  We can easily know that the process of solving the nth term and the n-1th term in the above function is basically the same. That is to say, the program has done a lot of useless work. If we record the intermediate process in the solution process, If you need to call the value directly again, you can improve efficiency, that is, use space for time.

  Just do it!

def fibonaci():
    """
    Function: get n_th value in Fibonacci Array using DFS with memory search
    Returns: None
    """
    import time
    # input the index
    n=int(input())
    # store intermediate results
    ans=[False for i in range(n + 1)]
    # core function
    def dfs(x):
        nonlocal ans
        if ans[x]:
            return ans[x]
        if x == 1 or x == 2:
            ans[x] = 1
            return 1
        else:
            ans[x] = dfs(x - 1) + dfs(x - 2)
            return ans[x]
    # record processing time
    start=time.time()
    # print answer
    print(dfs(n))
    print("Using {:.5f} s".format(time.time() - start))
    return

>>> fibonaci()
35
9227465
Using 0.00751 s
>>> fibonaci()
50
12586269025
Using 0.00795 s
>>> fibonaci()
100
354224848179261915075
Using 0.01003 s

  It can be seen that the memoized search method only used 0.01153 when solving the 35th term. The actual time complexity is basically maintained at the linear O(N) level , nice!

Insert picture description here

Little Trick

  In fact, the recursive method is limited by the number of function recursive stacks. The default is 1000. It can be solved in a non-recursive form, but it is not in the scope of today, so I won’t introduce it. You can check the relevant information by yourself~

  In addition, there is a little trick. Sometimes it is necessary to solve the nth term of the Fibonacci sequence, but n is not too large (less than 50). Then you can use the following faster lambda anonymous function method, which is concise~

# Lambda function definition
Fibo = lambda x: 1 if x == 1 or x == 2 else Fibo(x-1) + Fibo(x-2)
# test
>>> Fibo(20)
6765
>>> Fibo(35)
9227465

  In fact, it is to simplify the DFS core function of non-memoized search to an anonymous function . This will be used frequently in some future topics, and I think it is more convenient.

  I’m here for today. Those who have questions or comments can ask questions on the blog or public account, and will reply in time!


WeChat

CSDN BLog

Come and be bald with the knife~

Reference

[1] The beginning of the small column of algorithms: Fibonaci series of DFS

Guess you like

Origin blog.csdn.net/weixin_40519529/article/details/113081416