-
메모이제이션 Memoization(간단 정리)알고리즘/알고리즘 개념 및 정리 2020. 4. 16. 01:26
메모이제이션은 연산에 있어서 중복된 연산을 진행할 때 이러한 중복된 연산을 제거하기 위해 사용된다.
처음에 설명을 들을 때는 이미 계산한 값을 저장해놓고 다시 불러서 사용한다 어쩌구저쩌구~
이러한 설명보다는 직접 코드를 구현해서 보면 이해가 쉽다.
< 피보나치 수열 재귀함수 이용 >
#include <iostream> #include <string.h> using namespace std; int data[30]; int dp(int n){ if(n<=2) return 1; data[n]=dp(n-1)+dp(n-2); cout << "data[" << n << "] : " << data[n] << endl; return data[n]; } int main() { memset(data,0,sizeof(data)); cout << dp(10) <<'\n'; return 0; }
위의 코드를 보면 피보나치 수열에 대해서 구현해 놓은 코드이다.
10번째에 피보나치 수열 값이 무엇인지 계산해주는데 거기까지 가려면
dp(10) = dp(9) + dp(8)
dp(9) = dp(8) + dp(7)
dp(8) = dp(7) + dp(6)
이런식으로 재귀함수에 의해 쫘라락 연산이 진행될 것이다.
그래서 마지막에 n이 2보다 작은 경우인 dp(1)과 dp(2)가 1을 리턴하면서 계산이 다시 좌라락 진행될 것이다.
위의 내용이 자세한 것은 아니지만 저 수식들만봐도 중복되는 함수 호출이 벌써 여러개 있다.
-> dp(9) : 2개, dp(8) : 3개 dp(7) : 2개
물론 당연히 호출이 되야하지만 만약에 이렇게 사용한다면 어떨까?
< 피보나치 수열 재귀함수 + 메모이제이션 이용 >
#include <iostream> #include <string.h> using namespace std; int data[30]; int dp(int n){ if(n<=2) return 1; if(data[n]!=0){ return data[n]; } else{ data[n]=dp(n-1)+dp(n-2); cout << "data[" << n << "] : " << data[n] << endl; return data[n]; } } int main() { memset(data,0,sizeof(data)); cout << dp(10) <<'\n'; return 0; }
위의 코드와 다른 점은 if 문이 하나 더 등장했다는 것이다.
내용은 data[n]에 값이 존재하면 그 값을 그대로 리턴해라 이다.
즉, 값이 있으면 굳이 그 값을 구하기위한 연산을 하지않고 있는 값을 그대로 반환하겠다는 의미이다.
이와 같은 진행을 하게 되면 다수의 중복 연산을 제거할 수 있다.
눈으로 보고싶다면 위의 코드 두개를 직접 실행해보면된다.
누가봐도 연산의 차이가 난다는 것을 알 수 있다. 이는 굉장히 중요하다.
지금은 겨우 10개짜리를 진행했지만 크기가 클 수록 굉장히 많은 중복을 줄일 수 있게된다.
절대 잊지말자!! 포인트는 쉽게 말해 재활용이다!
반응형'알고리즘 > 알고리즘 개념 및 정리' 카테고리의 다른 글
Visual Studio 디버깅 시, 입력 붙여넣기 안 될때! (0) 2020.05.22 퀵 정렬 Quick Sort (0) 2019.03.09 삽입정렬 Insert Sort (0) 2019.03.07 버블 정렬 Bubble Sort (0) 2019.03.07 선택정렬 Selection Sort (0) 2019.03.07 댓글