중복 가능성: 중복: 동적 프로그래밍과 메모화: 하향식 대 상향식 접근법](https://stackoverflow.com/questions/6164629/dynamic-programming-and-memoization-top-down-vs-bottom-up-approaches)
자동 삽입된 텍스트의 끝 -->!-- 자동 삽입된 텍스트의 끝입니다;
이에 대한 많은 기사를 살펴 보았지만 이해가 되지 않는 것 같습니다. 때로는 재귀와 동적 프로그래밍이 똑같아 보이고 다른 경우에는 메모화 및 동적 프로그래밍이 비슷해 보입니다. 차이점이 무엇인지 설명해 주실 수 있나요?
추신 : 같은 문제에 대해 세 가지 접근 방식을 사용하는 코드를 알려 주시면 도움이 될 것입니다. (예 : 피보나치 급수 문제, 내가 읽은 모든 기사에서 재귀를 사용했지만 동적 프로그래밍이라고 언급 한 것 같습니다.)
레오나르도 피보나치 계산하는 고려해보십시오 e0100042.log:
순결케 반복.
<! - 모든 언어: c - >.
int fib(int x)
{
if (x < 2)
return 1;
return fib(x-1) + fib(x-2);
}
지수 얻을 수 있다.
메모이제이션 함께 반복 / DP:
int fib(int x)
{
static vector<int> cache(N, -1);
int& result = cache[x];
if (result == -1)
{
if (x < 2)
result = 1;
else
result = fib(x-1) + fib(x-2);
}
return result;
}
이제 우리는 일괄이라는 통화 수 있으며, 그 후 처음으로 상수입니다.
위의 방법을 lazy" 호출됨 ";). 우리는 앞서 약관보다 계산하십시오 처음 이들은 주문하신거.
반복 없이 다음 고려해야 할 것이다.
int fibresult[N];
void setup_fib()
{
fibresult[0] = 1;
fibresult[1] = 1;
for (int i = 2; i < N; i++)
fibresult[i] = fibresult[i-1] + fibresult[i-2];
}
int fib(int x) { return fibresult[x]; }
이 길을 따라 eager" " precaching" " 설명 될 수 있다;;;; 또는 " iterative";). 하지만 해야 하는 등 전반적인 빠르게 계산할 수 있는 그림 아웃해야 수동으로로 오더할 하위 문제. 레오나르도 피보나치 있으나, 이 문제를 더 쉽게 더 복잡한 DP, 그래서 우리는 폴백하는 it gets the lazy 재귀 방법을 충분히 빨리 경우.
또한 다음 반복이 아닙니다 아니하고또 파켓:
int fib(int x)
{
int a = 1;
int b = 1;
for (int i = 2; i < x; i++)
{
a = a + b;
swap(a,b);
}
return b;
}
It 가 상수입니다 공간 및 일괄이라는 하게하면서요.
또한 내아기마저도 언급하십시오 생각해서라도 완성도 있는 레오나르도 피보나치 수 있게 하는 반복이 disk_b_s10database DP 에서 계산하십시오 황천의 단힌 양식을 사용하는 용어가 수학 공식을 사용하여 상수 시간에 따라 레오나르도 피보나치 황금 비율:
http://www.dreamincode.net/forums/topic/115550-fibonacci-closed-form/
글쎄요, 재귀+메모화는 탑다운 접근 방식에 따른 동적 프로그래밍인 동적 프로그래밍의 특정 <맛>이라고 할 수 있습니다.
더 정확하게는 재귀 를 특별히 사용할 필요가 없습니다. 메모화와 결합된 모든 분할 및 정복 솔루션은 하향식 동적 프로그래밍입니다. (재귀는 분할과 정복의 LIFO 방식이며, FIFO 분할과 정복 또는 다른 종류의 분할과 정복도 사용할 수 있습니다).
따라서 다음과 같이 말하는 것이 더 정확합니다.
divide & conquer + memoization == top-down dynamic programming
또한 매우 형식적인 관점에서 볼 때, 반복적인 부분 해를 생성하지 않는 문제(즉, 암기의 이점이 없는 문제)에 대해 분할 및 정복 해를 구현한다면, 이 분할 및 정복 해는 <동적 프로그래밍>의 퇴보한 예라고 주장할 수 있습니다.
그러나 동적 프로그래밍은 보다 일반적인 개념입니다. 동적 프로그래밍은 상향식 접근 방식을 사용할 수 있으며, 이는 분할 및 정복+메모화와는 다릅니다.
인터넷에서 자세한 정의를 찾을 수 있다고 확신합니다. 여기서는 간단하게 설명해 보겠습니다.
재귀가 다시 호출되고 있습니다.
동적 프로그래밍은 특정 구조 (최적 하위 구조)를 나타내는 문제를 해결하는 방법으로, 문제를 원래 문제와 유사한 하위 문제로 나눌 수 있습니다. 분명히 재귀를 호출하여 DP를 해결할 수 있습니다. 하지만 반드시 그럴 필요는 없습니다. 재귀를 사용하지 않고도 DP를 풀 수 있습니다.
메모화는 재귀에 의존하는 DP 알고리즘을 최적화하는 방법입니다. 요점은 이미 해결된 하위 문제를 다시 풀지 않는 것입니다. 하위 문제에 대한 솔루션의 캐시로 볼 수 있습니다.
이들은 다른 개념. 그러나 그들은 그들이 자주 중첩됩니다 꽤 다르다.
함수 호출을 반복이 때마다 직접 또는 간접적으로 발생하는 것이다. 이게 다.
예:
a -> call a
a -> call b, b -> call c, c -> call a
동적 프로그래밍 은 작은 하위 문제 해결을 위해 솔루션을 사용할 때 더 큰 문제다. 이는 일반적으로 가장 쉽게 생각할 수 있기 때문에 이러한 측면에서 솔루션을 구축하기 위해 재귀적으로 재귀 함수. 일반적으로 기본 표시되어도 반복적인 구축현 때문에 단시간에 및 메모리.
메모이제이션 방지하는 데 사용되는 재귀 DP 에서 구축현 며칠 동안 보다 더 많은 시간이 필요하다. 여러 문제를 해결하는 데 가장 큰 배, DP 알고리즘입니다 동일한 서브프로브렘 사용하게 됩니다. 즉, 여러 번 반복) 에 구축현 대화할거에요 재계산합니다 마찬가지입니다. 이 결과가 하위 문제 표로 절약합니다 메모이제이션 의미합니다. 재귀 호출을 입력할 때, 우리는 그 결과 table: 있는지 확인합니다. 우리는 우리가 예이면, 그렇지 않을 경우에는 다시 연산 후 다시 테이블에 저장하십시오.
재귀는 메모화 및 동적 프로그래밍과 전혀 관련이 없으며 완전히 별개의 개념입니다.
그렇지 않으면 다음 질문과 중복됩니다: https://stackoverflow.com/questions/6164629/dynamic-programming-and-memoization-top-down-vs-bottom-up-approaches