Fibonacci Sequence 분석

qzzloz·2023년 10월 26일
0

알고리즘

목록 보기
3/6

1. Fibonacci Sequence (피보나치 수열)

  • 피보나치 수열의 정의
  • 예: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...

2. 피보나치 수 구하기 알고리즘 (Recursive)

  • 피보나치 수열의 n번째 값을 찾는 알고리즘
  • 입력: n
  • 출력: 피보나치 수열의 n번째 값

pseudocode

int fibo(int n){
	if(n <= 1)
    	return n;
    else
    	return fibo(n-1) + fibo(n-2);
}
  • fibo(5)의 재귀 트리

    n=0, fibo(0) = 1
    n=1, fibo(1) = 1 이면
    n>=2에서 fibo는 2, 3, 5, 8 ...이 된다. 즉 n=5일 때 fibo=8이다. 이 값은 fibo(5)의 재귀 트리 그림에서 말단 노드의 개수와 같다.
    n=3일 때도 fibo(3) = 3이고, fibo(3)의 말단 노드도 fibo(1), fibo(0), fibo(1)으로 3개라는 것을 알 수 있다. 이 때 말단 노드의 개수는 fib(n)을 계산하기 위하여 fib 함수를 호출하는 횟수라고 할 수 있다.

T(n) = fib(n)을 계산하기 위하여 fib 함수를 호출하는 횟수 = 재귀 트리의 말단 노드 개수


3. 피보나치 수 구하기 알고리즘 (Iterative)

pseudocode

int fibo2(int n){
	index i;
    int f[0...n];
    
    f[0]=0;
    if(n > 0){
    	f[1] = 1;
        for(i = 2; i<=n; i++)
        	f[i] = f[i-1] + f[i-2];
    }
}
  • Dynamic Programming, Bottom-Up
  • 중복 계산이 없기 때문에 재귀보다 훨씬 빠르다.
  • 계산하는 항의 총 개수 T(n) = n + 1
  • f[0]부터 f[n]까지 한 번씩만 계산(계산한 값을 배열에 저장해두고 필요할 때마다 꺼내서 사용한다.)

4. 피보나치 문제를 해결할 때, Recursive와 Iterative 중 더 효율적인 것은?

  • 피보나치 수열 문제는 Divide&Conquer 방법으로 해결하면 중복 계산이 발생하기 때문에 Dynamic Programming 기법으로 푸는 것이 더 효율적이다.


위 그림은 피보나치의 재귀 트리이다.

Recursive 방법이 비효율적인 이유를 fib(2)의 중복 계산으로 알아보자.
(그림 참고) fib(4)를 구하기 위해서 fib(2)는 fib(2)를 구할 때 +1번, fib(3)을 구하기 위해 fib(2)를 호출할 때 +1번. 총 두 번의 중복 계산이 발생한다.

하지만 Iterative 방식으로 문제를 해결한다면 for문을 통해 fib(2) 값을 배열에 저장해두고 필요할 때마다 값을 가져와서 사용하기 때문에 중복 계산이 발생하지 않고 수행속도가 훨씬 빠르다. 따라서 Recursive보다 Iterative 방식이 더 효율적이라고 할 수 있다.

0개의 댓글