동적 프로그래밍이란 무엇입니까?


33

이 질문이 바보처럼 들리면 미리 죄송합니다 ...

내가 아는 한 동적 프로그래밍을 사용하여 알고리즘을 작성하면 다음과 같이 작동합니다.

  1. 문제를 재발 관계로 표현하십시오.
  2. 메모 또는 상향식 접근을 통해 반복 관계를 구현합니다.

내가 아는 한, 나는 동적 프로그래밍에 관한 모든 것을 말했다. 동적 프로그래밍은 재귀 관계를 표현하거나 코드로 변환하기위한 도구 / 규칙 / 방법 / 이론을 제공하지 않습니다.

동적 프로그래밍의 특별한 점은 무엇입니까? 특정 종류의 문제에 접근하기위한 모호한 방법 이외의 다른 방법은 무엇입니까?


11
역사적 사실 (이 의견은 당신에게 도움이되지 않지만 Bellman은 동적 프로그래밍에 대한 이론을 많이 원한다면 실제로 좋은 리더입니다) "순전히 이론적 인 작업 은 그 당시 고용주와 함께 날지 않았기 때문에 , 그는 중대한 방식으로 사용될 수없는 더 화제가 필요했습니다 .
G. 바흐

3
내가 아는 한 정확하게 두 가지 사항을 언급했습니다. 하위 문제가 중복되어 지수 폭발을 피할 때 특별 해집니다. 그게 다야. 아, 그런데 교수님은 "모호한 방법"보다 "알고리즘 패러다임"을 선호합니다.
Hendrik Jan

"동적 프로그래밍"은 주로 유행어 인 것으로 보입니다 (그 이후로 유행을 잃은 것입니다). 그렇다고 그것이 유용하지 않다는 것을 의미하지는 않습니다.
user253751

3
답을 얻을 가치는 없지만 동적 프로그래밍은 분명히 "문제를 재귀 적으로 해결하려고 할 때 사용하는 것이지만, 동일한 하위 문제를 반복해서 다시 보는 데 시간을 낭비하게됩니다."
hobbs

@ hobbs : 맞습니다. 그러나 기술은 시간을 낭비하는 초기 방법을 찾는 것 입니다.)
j_random_hacker

답변:


27

동적 프로그래밍은 알고리즘 설계를 생각할 수있는 방법을 제공합니다. 이것은 종종 매우 도움이됩니다.

메모 및 상향식 방법은 반복 관계를 코드로 변환하는 규칙 / 방법을 제공합니다. 메모 화는 비교적 간단한 아이디어이지만 가장 좋은 아이디어는 종종 있습니다!

동적 프로그래밍은 알고리즘의 실행 시간을 생각할 수있는 체계적인 방법을 제공합니다. 실행 시간은 기본적으로 해결해야하는 하위 문제의 수와 각 하위 문제를 해결하는 데 걸리는 시간의 두 숫자로 결정됩니다. 이를 통해 알고리즘 설계 문제에 대해 쉽게 생각할 수 있습니다. 후보 재발 관계가 있으면 관계를보고 매우 빠르게 실행 시간을 파악할 수 있습니다. 실행 시간; 기하 급수적으로 많은 하위 문제가 해결되어야하는 경우 재발은 좋은 접근 방식이 아닐 것입니다). 또한 후보 하위 문제 분해를 배제하는 데 도움이됩니다. 예를 들어 문자열 , 접두사에 의해 하위 문제를 정의 S [ 1 .. I ] 또는 접미어 S [ J . . n ] 또는 부분 문자열 S [ i . . j ] 는 합리적 일 수 있지만 (하위 문제의 수는 다항식 n ), S 의 하위 시퀀스로 하 위 문제를 정의하는것은 좋은 접근 방법이 아닐 수 있습니다 (하위 문제의 수는 n의 지수). 이를 통해 가능한 재발의 "검색 공간"을 정리할 수 있습니다.에스[1..]에스[1..나는]에스[j..]에스[나는..j]에스

동적 프로그래밍은 후보 재발 관계를 찾기위한 구조화 된 접근 방식을 제공합니다. 경험적으로이 접근 방식은 종종 효과적입니다. 특히 입력 유형에 따라 하위 문제를 정의하는 일반적인 방법으로 인식 할 수있는 휴리스틱 / 공통 패턴이 있습니다. 예를 들어 :

  • 입력이 경우 양의 정수 하는 하위 문제를 정의하는 하나의 방법은 후보 바꾸어 인 N 보다 작은 정수로 N ' (세인트 0 N 'N ).'0'

  • 입력이 문자열 인 경우 하위 문제를 정의하는 몇 가지 후보 방법은 다음과 같습니다. S [ 1 .. n ] 을 접두사 S [ 1 .. i ]로 대체합니다 . S [ 1 .. n ] 을 접미사 S [ j로 바꾸십시오 . . n ] ; S [ 1 .. n ] 을 하위 문자열 S [ i로 교체하십시오 . . j ]에스[1..]에스[1..]에스[1..나는]에스[1..]에스[j..]에스[1..]에스[나는..j]. (여기서 하위 문제는 의 선택에 의해 결정됩니다 .)나는,j

  • 입력 값이 list 인 경우 문자열과 동일하게 수행하십시오.

  • 입력이 경우 트리 하는 하위 문제를 정의하는 하나의 후보 방법은 대체하는 것입니다 T를 의 하위 트리와 T (즉, 노드 선택 X를 하고 교체 T를 루트로하는 서브 트리와 X 하며 하위 문제가의 선택에 의해 결정된다 X ).엑스엑스엑스

  • 입력 값이 쌍 인 경우 x 유형과 y 유형을 반복적으로보고 각 하위 문제를 선택하는 방법을 식별하십시오. 즉, 하위 문제를 정의하기 위해 하나의 후보 방법 대체하는 ( X , Y가 )( X ' , Y ' ) X ' 대한 하위 문제이고 , XY ' 대한 하위 문제이다 Y . ( ( x , y 형식의 하위 문제도 고려할 수 있습니다.(엑스,와이)엑스와이(엑스,와이)(엑스',와이')엑스'엑스와이'와이 또는 ( x , y ) )(엑스,와이')(엑스',와이)

등등. 이 방법은 매우 유용한 휴리스틱을 제공합니다. 메서드 의 형식 서명 만 확인하면 하위 문제를 정의하는 후보 방법 목록을 얻을 수 있습니다. 다시 말해, 입력 유형 만보고 문제 설명을 살펴보면 하위 문제를 정의 할 수있는 몇 가지 후보 방법을 찾을 수 있습니다.

이것은 종종 매우 도움이됩니다. 재발 관계가 무엇인지 알려주지는 않지만 하위 문제를 정의하는 방법에 대한 특별한 선택이있을 때 종종 해당 재발 관계를 해결하는 것이 어렵지 않습니다. 따라서 종종 동적 프로그래밍 알고리즘의 설계를 구조화 된 경험으로 바꿉니다. 하위 문제를 정의하는 후보 방법 목록을 스크랩 용지에 기록합니다 (위의 휴리스틱 사용). 그런 다음 각 후보에 대해 반복 관계를 기록하고 하위 문제 수와 하위 문제당 소요 시간을 세어 실행 시간을 평가합니다. 각 후보를 시도한 후에는 찾은 최고의 후보를 유지하십시오. 알고리즘 설계 프로세스에 일부 구조를 제공하는 것은 알고리즘 설계가 위협적 일 수 있으므로 중요한 도움이됩니다.


따라서 동적 프로그래밍에는 구체적인 "절차"가 제공되지 않습니다. 당신이 말했듯이 그것은 단지 "생각하는 방법"입니다. 나는 DP가 쓸모 없다고 주장하는 것이 아니라 (반대로!), 내가 놓친 것이 있거나 더 연습 해야하는지 이해하려고합니다.
야 이봐

@heyhey, 그래 ... 아니, 아니 자세한 내용은 수정 된 답변을 참조하십시오. 그것은 총알이 아니지만 종종 도움이되는 반 콘크리트 절차를 제공합니다 (작동하지 않지만 도움이되는 경우가 종종 있습니다).
DW

많은 감사합니다! 연습함으로써 나는 당신이 설명하고있는 "반 구체적인 절차들"에 대해 점점 더 친숙해지고 있습니다.
안녕하세요 hey

"지속적으로 해결해야 할 하위 문제가 많은 경우 재발이 좋은 접근 방식이 아닐 수 있습니다." 많은 문제에 대해 알려진 다항식 시간 알고리즘이 없습니다. 이것이 DP 사용의 기준이되어야하는 이유는 무엇입니까?
Chiel ten Brinke

@Chiel, DP를 사용하는 기준은 아닙니다. 지수 시간 알고리즘에 만족할만한 문제가있는 경우 해당 특정 괄호를 무시할 수 있습니다. 너무 진지하게 받아들이거나 단단하고 빠른 규칙으로 해석해서는 안되는 것이 아니라 내가했던 일반적인 요점을 설명하려는 예일뿐입니다.
DW

9

동적 프로그래밍에 대한 이해가 정확하고 ( afaik ) 질문이 정당합니다.

우리가 "동적 프로그래밍"이라고 부르는 종류의 재귀에서 얻는 추가 디자인 공간은 재귀 적 접근 방식의 다른 스키마와 비교하여 가장 잘 볼 수 있다고 생각합니다.

개념을 강조하기 위해 입력 값이 배열 것처럼 가정합시다 .에이[1..]

  1. 유도 적 접근

    여기서 아이디어는 문제를 더 작게 만들고 더 작은 버전을 해결하며 원래 버전에 대한 솔루션을 도출하는 것입니다. 도식적으로,

    에프(에이)=(에프(에이[1..기음]),에이)

    함께 용액 변환 함수 / 알고리즘.

    예 : 선형 시간으로 슈퍼 스타 찾기

  2. 나누고 정복

    입력을 여러 개의 작은 부분으로 분할하고 각각의 문제를 해결하고 결합하십시오. 도식적으로 (두 부분으로)

    .에프(에이)=(에프(에이[1..기음]),에프(에이[기음+1..]),에이)

    예 : 병합 / 퀵소트, 평면에서 가장 짧은 쌍별 거리

  3. 다이나믹 프로그래밍

    문제를 더 작은 문제로 분할하고 최선의 방법을 선택하는 모든 방법을 고려하십시오 . 도식적으로 (두 부분으로)

    .f(A)=best{g(f(A[1..c]),f(A[c+1..n]))|1cn1}

    예 : 거리 편집, 변경 문제

    중요한 참고 사항 : 동적 프로그래밍은 무차별 강제력 이 아닙니다 ! 모든 단계에서 를 적용 하면 검색 공간이 상당히 줄어 듭니다.best

어떤 의미에서, 당신은 점점 더 정적으로 위에서 아래로가는 것을 알고 있으며, 점점 더 많은 결정을 동적으로 내려야합니다.

동적 프로그래밍에 대한 학습에서 교훈는 점이다 좋아 여전히 메모이 제이션을 사용하여 효율적으로 할 수 있기 때문에 (물론,이 정확성에 필요한 것) 가능한 모든 병풍을 시도.


"정리 된 동적 프로그래밍"(적용되는 경우)은 모든 가능성을 시험해볼 필요는 없습니다.
Ben Voigt

@BenVoigt 물론입니다. "분할하는 모든 방법"의 의미에 대해 의도적으로 모호한 상태를 유지했습니다. 물론 최대한 많은 것을 배제하고 싶다! (그러나 모든 분할 방법 을 시도하더라도 하위 문제에 대한 최적의 솔루션 조합 만 조사하기 때문에 무차별 공격을받지 않는 반면, 무차별 공격은 모든 솔루션 의 모든 조합을 조사합니다 .)
Raphael


5

동적 프로그래밍을 사용하면 계산 시간 동안 메모리를 교환 할 수 있습니다. 고전적인 예인 피보나치 (Fibonacci)를 고려하십시오.

피보나치는 재발 됩니다. 이 재귀를 사용하여 해결 하면 재귀 트리는 높이가 n 인 이진 트리이므로 F i b ( )에 O ( 2 n ) 호출을 수행하게 됩니다.Fib(n)=Fib(n1)+Fib(n2)O(2n)Fib()n

대신, 를 계산 한 다음이를 사용하여 F i b ( 3 ) 을 찾고,이를 사용하여 F i b ( 4 ) 등 을 찾으십시오 . 이것은 O ( n ) 시간 만 걸립니다 .Fib(2)Fib(3)Fib(4)O(n)

DP는 또한 재귀 관계를 상향식 솔루션으로 변환하는 기본 기술을 제공하지만 비교적 간단합니다 (일반적으로 차원 행렬 또는 이러한 행렬의 경계를 사용하는 경우). 여기서 m 은 매개 변수의 수입니다. 재발 관계). 이것들은 DP에 대한 모든 텍스트로 잘 설명되어 있습니다.mm


1
당신은 질문 부분을 놓치는 메모 부분에 대해서만 이야기합니다.
Raphael

1
"동적 프로그래밍을 사용하면 계산 시간에 메모리를 교환 할 수 있습니다"는 저학년 때들은 것이 아니며이 주제를 살펴볼 수있는 좋은 방법입니다. 이것은 간결한 예를 가진 직관적 인 답변입니다.
trueshot

@trueshot : 때때로 동적 프로그래밍 (특히, "동적 동적 프로그래밍")이 시간 및 공간 요구 사항을 모두 줄일 수 있다는 점을 제외하고.
Ben Voigt

@Ben은 일대일 거래라고 말하지 않았습니다. 반복 트리도 제거 할 수 있습니다. 나는 "DP가 우리를 어떻게 얻습니까?"라는 질문에 대답했다고 주장했다. 그것은 시간을 위해 공간을 거래함으로써 더 빠른 알고리즘을 얻습니다. 수락 된 답변이 더 철저하다는 데 동의하지만 이것은 유효합니다.
Kittsil

2

다음은 동적 프로그래밍이 제공하는 다른 표현 방식입니다. 다이나믹 프로그래밍은 기하 급수의 후보 솔루션을 다항식 수의 등가 클래스로 축소하여 각 클래스의 후보 솔루션을 구분할 수 없도록합니다.

길이 n 의 배열 A 에서 길이 의 증가하는 서브 시퀀스 수를 찾는 문제를 예로 들어 보겠습니다 . 모든 서브 시퀀스 세트를 동등 클래스로 분할하여 두 개의 서브 시퀀스가 ​​길이가 동일하고 동일한 색인으로 끝나는 경우에만 동일한 클래스에 속하도록하는 것이 유용합니다. 의 모든 2 개 n 개의 가능한 서브 정확히 하나에 속하는 O ( N 2 ) 등가 클래스. 이 분할은 클래스의 크기에 대한 반복 관계를 정의 할 수 있도록 충분한 정보를 유지합니다. 만약 f ( i , )kAn2nO(n2)f(i,)인덱스 끝나고 길이가 인 하위 시퀀스 수를 제공하면 다음 과 같습니다.i

(F)는 ( , 1 ) = 1  모두가  나는 = 1 ... N을

f(i,)=j<i such thatA[j]<A[i]f(j,1)
f(i,1)=1 for all i=1n

이 반복은 시간 의 문제를 해결합니다 .O(n2k)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.