익명 사용자
로그인하지 않음
계정 만들기
로그인
youngwiki
검색
Dynamic Programming 문서 원본 보기
youngwiki
이름공간
문서
토론
더 보기
더 보기
문서 행위
읽기
원본 보기
역사
←
Dynamic Programming
문서 편집 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 명령은 다음 권한을 가진 사용자에게 제한됩니다:
사용자
.
문서의 원본을 보거나 복사할 수 있습니다.
[[분류:알고리즘 설계와 분석]] [[분류:컴퓨터 공학]] 상위 문서: [[알고리즘 설계와 분석#문제|알고리즘 설계와 분석]] ==개요== 동적 프로그래밍(Dynamic Programming)은 좌우 순서로 배열된 문제들<ref>문자열, 수열 등에 관한 문제이다.</ref>에 대한 최적화 문제를 효율적으로 푸는 방법이다. 동적 프로그래밍의 핵심적인 아이디어는 복잡한 문제를 작은 하위 문제(subproblem) 로 나누고, 중복 계산을 피하기 위해 이전 결과를 저장(memoization)하는 것이다. 이때 동적 프로그래밍은 재귀적으로 구현한다는 것을 의미하지 않는다. 동적 프로그램의 본질은 어디까지나: # 중복되는 하위 문제(Overlapping Subproblems): 예를 들면, 피보나치에서 fib(3)을 여러 번 계산하지 않는 것이 있다. # 최적 부분 구조(Optimal Substructure): 큰 문제의 최적해가 작은 문제의 최적해들로 구성되는 것이다. 따라서 DP를 구현하는 방식은 아래와 같이 두 가지로 나뉜다: # Top-Down(Memoization): 큰 문제에서 출발해 재귀를 통해 하위 문제를 호출하며, 이미 계산된 값은 저장하여 활용한다. # Bottom-Up(Tabulation): 가장 작은 하위 문제부터 순서대로 반복문으로 해결하며, 결과를 테이블에 저장한다. 동적 프로그래밍은 완전탐색(Exhaustive Search) 방식에 같이 사용된다. 완전 탐색 기법은 모든 가능한 해를 탐색하므로 항상 정답은 구하지만 비효율적이지만 동적프로그램과 같이 응용하여, 중복 계산을 제거하여 효율을 높일 수 있다. 이를 이용한 대표적인 알고리즘으로는 [[Shortest Paths#Floyd’s Algorithm|Floyd’s Algorithm]]이 있다. ==Recurrence Relations== 점화식(Recurrence Relation)은 어떤 수열을 “이전 항들로 정의하는 식”이다. 즉, "자기 자신을 기반으로 정의된 함수"이다. 예를 들면, 아래와 같은 식이 있다: <math>a_n=a_{n-1}+1,a_1=1 \Rightarrow a_n = n</math> <math>a_n=2a_{n-1},a_1=2\,\,\,\,\,\,\, \Rightarrow a_n = 2^n</math> <math>a_n=na_{n-1}, a_1=1\,\,\,\,\,\,\, \Rightarrow a_n=n!</math> 이와 같이 점화식을 통해 문제의 구조를 반복되는 관계로 표현함으로서 프로그램이 재귀적으로 계산할 수 있다. 즉, 동적 프로그래밍은 이러한 점화식을 효율적으로 계산하기 위해 부분 결과를 저장하는 기법이다. ===Master Theorem=== 이때 점화식은 문제를 작은 하위 문제로 나누었을 때 이를 표현하는 수식이므로, 주어진 점화식을 이용해 알고리즘의 시간복잡도를 추론할 수 있다. 이를 마스터 정리(master theorem)이라고 하며, 이는 [[Sorting Problem#Mergesort#Divide and Conquer|분할 정복 알고리즘]]에도 적용될 수 있다. 마스터 정리는 점화식이 아래와 같은 형태임을 가정한다: <math>T(n) = a\cdot T(n/b)+f(n)</math> 위에서 a는 분할할 때 문제의 개수, n/b는 분할된 각 문제의 크기, f(n)은 부분 문제의 해를 합치는데 걸리는 비용을 의미한다. 일반화한 이 식을 통해 T(n)의 점근적인 시간복잡도를 구하면 아래와 같다: *Case 1: <math>f(n) = O(n^{log_b{a-\epsilon}}),</math> for some <math>\epsilon > 0</math> ** 즉, 합치는 비용이 부분 문제 비용보다 작다. 이 경우, <math>T(n) = \Theta(n^{log_ba})</math> * Case 2: <math>f(n) = \Theta(n^{log_ba}),</math> ** 즉, 합치는 비용이 부분 문제 비용과 비슷하다. 이 경우, <math>T(n) = \Theta(n^{log_ba}\cdot log(n))</math> * Case 3: <math>f(n) = \Omega(n^{log_b{a+\epsilon}}),</math> for some <math>\epsilon > 0</math> ** 즉, 합치는 비용이 부분 문제 비용보다 크다. 이 경우, <math>T(n) = \Theta(f(n))</math> ** 단, 정규성 조건이 필요하다: <math>a\cdot f(n/b) \le c\cdot f(n)</math> for some <math>c < 1</math> ===Three Steps to Dynamic Programming=== 마스터 정리를 바탕으로, 동적 프로그래밍을 하기 위한 3단계를 요약하면 아래와 같다: # 점화식 세우기: 문제를 작은 하위 문제로 나누고, 이들 결과를 결합하는 수식을 만든다. # 서브문제 개수의 다항성 보장: 가능한 하위 문제 수가 너무 많지 않아야 한다.<ref>마스터 정리를 통해 계산했을 때 전체 알고리즘의 시간 복잡도가 <math>O(n^2), O(n^3)</math> 정도이면 적당하다.</ref> # 계산 순서 결정: 하위 문제의 결과를 이미 계산된 값으로부터 효율적으로 구할 수 있도록 순서를 정한다. ==[[Fibonacci Numbers]]== 피보나치 수열(Fibonacci Numbers)은 동적 프로그래밍의 대표적인 구현 예시 중 하나이다. [[Fibonacci Numbers|피보나치 수열]]에 대한 자세한 설명은 해당 문서를 참조해주십시오. ==[[Binomial Coefficients]]== 이항 계수(Binomial Coefficients)는 동적 프로그래밍의 고전적인 응용 중 하나이다. [[Binomial Coefficients|이항 계수(Binomial Coefficients)]]에 대한 자세한 설명은 해당 문서를 참조해 주십시오. ==[[The Gas Station Problem]]== [[The Gas Station Problem]]에 대한 자세한 설명은 해당 문서를 참조해 주십시오. ==[[Edit Distance]]== [[Edit Distance]]에 대한 자세한 설명은 해당 문서를 참조해 주십시오. ==각주==
Dynamic Programming
문서로 돌아갑니다.
둘러보기
둘러보기
대문
최근 바뀜
임의의 문서로
미디어위키 도움말
위키 도구
위키 도구
특수 문서 목록
문서 도구
문서 도구
사용자 문서 도구
더 보기
여기를 가리키는 문서
가리키는 글의 최근 바뀜
문서 정보
문서 기록