동적 프로그래밍 이론
모델 세 가지 기능
- 다단계 의사 결정 최적의 솔루션
- 최적의 하부 구조
- 최적 하부 수단은 최적의 해결책은 문제의 서브 - 최적 솔루션을 포함하고있다. 반대로 말하자면, 우리는이 문제의 서브 - 최적의 솔루션은 최적의 솔루션의 문제점을 도출 할 수 있다는 것이다.
- 우리는 최적의 하부 구조를 취할 경우, 우리는 이전에 정의 된 동적 프로그래밍 모델의 문제에 대응이, 우리가 알 수있는 스테이지 뒤에 상태가 이전 단계의 상태에 의해 유도 될 수있다 .
- 더 후 없습니다 효과
- 더 후 효과 상태가 나중 단계를 유도 할 때, 우리는, 이전 단계의 값의 상태에 관심이 상태 단계 추론 단계가 얼마나 걱정하지 않는다, 두 가지 의미, 의미의 첫 번째 레이어가 없습니다.
- 두 번째 의미는 국가가 설립 어떤 단계에서,이 단계 이후에 영향을 미치는 의사 결정의 대상이되지 않는 것입니다. 아니오 후 효과는 매우 "느슨한"요구 사항입니다. 동적 프로그래밍 모델의 문제는 앞서 언급 한 긴만큼, 사실, 그것은 기본적으로 더 후 효과를 충족하지 않습니다.
- 반복 하위 문제
- 이 개념은 더 잘 이해된다. 이전 하나, 나는 반복적으로 언급했다. 만약 한 문장으로, 인 의사 결정의 다른 시퀀스를 요약하고, 같은 도달 특정 단계가 중복 상태가 발생할 수 있습니다 때 .
예제와 함께 이론을 이해
- 우리는 행렬 W가 N [N] [n]을 N의 곱 있다고 가정하자. 이것은 양의 정수 행렬 저장된다. 오른쪽 하단의 좌측 상단 위치에 폰의 시작 위치. 우리는 오른쪽 아래 왼쪽 상단에서 잇됩니다. 당신은 오른쪽이나 아래에 하나를 이동할 수 있습니다. 오른쪽 아래 왼쪽 상단에서 취할 수있는 여러 가지 경로가있다. 우리는 숫자를 통해 각각의 경로는 경로의 길이로 간주 추가 할 수 있습니다. 그건 오른쪽 아래 왼쪽 상단에서 최단 경로의 길이는 얼마입니까?
- 모델 :
- (0, 0)으로부터 (N-1, N-1)로 이동하여, 2 * (N-1) 단계의 총두고 2 * (N-1) 번째 스테이지에 해당한다.
- 각 단계는 바로 이동하거나 의사 결정의 두 종류 내려가 있고, 각 단계는 상태의 집합에 해당됩니다.
- 우리는 i가 행을 나타내는 min_dist (I, J)의 상태를 정의하는, j는 열을 나타낸다. Min_dist 식 최단 경로 길이의 (i, j) (0, 0)의 값을 나타낸다. 따라서,이 문제는 동적 프로그래밍의 모델에 부합하는 다단 의사 최적 솔루션이다.
- 세 가지 특성 :
- 는 해당 노드의 위치를 표시하기 위해 왼쪽 상단에서 중복 된 노드를 찾을 그림 재귀 트리,이 문제의 존재를 나타내는 다양한 경로,가 반복 문제 .
- 계산 (I, J) 상태의 위치에 대응하는 작업은 결정 관련되는 (I-1, J) (I는, J-1)의 상태가 이전의 스테이지를 판정 한 후, 상태의 두 위치에 대응하는, 후속 단계는 없습니다 "와 라인의 변화, 더 후 효과" .
- 시작에 위치 (0, 0) (I, J)로 표시 min_dist (I, J)에서 min_dist 최소 경로 (I, J) min_dist 그래피 (I, J-1) min_dist (I- 1, j)는 부합 두 상태를 유도 " 최적 하부 ."
두 동적 프로그래밍 문제 해결 아이디어 요약
- 상태 전이 테이블 방법은 대략, 문제 해결 방안으로 요약 할 수있다 국가의 정의 - - 재귀 트리 그림 - 알고리즘을 역 추적 중복 하위 문제를 발견 - 상태 전이 테이블을 그립니다 - 채우기 형태로 재귀 적 관계를 기반으로 - 프로세스를 작성하는 코드로 변환합니다 .
- 상태 전환 방정식 방법의 일반적인 아이디어로 요약 할 수 있습니다 상태 전이 방정식을 쓰기 - - 코드가 상태 전이 방정식으로 변환됩니다 최적의 하부를 찾을 .
- 상태 전이 테이블 방법
- 해결에 우선 역 추적 알고리즘 검색 폭력 여부를 사용할 수있는 동적 계획 솔루션을 볼 수있는 법을 찾아, 중복 하위 문제가 있는지 여부를 확인하기 위해 재귀 트리를 그립니다.
- 경우 두 가지 해결책이 있습니다 :
- 사용 + 메모 되돌아 해결 중복 노드를
- 상태 전이 테이블 방법 :
- 상태 표를 작성합니다. 당신이 2 차원 배열로 상상할 수 있도록 상태 표는 일반적으로 두 가지 차원이다.
- 상기 각각의 상기 세 개의 상태 변수, 행, 열 배열 값. 재발 관계에 따라, 우리는 앞에서 뒤로,이 의사 결정 과정에 따르면, 단계에서 각 상태는 상태 테이블을 가득 채웠다. 마지막으로, 우리는 동적 프로그래밍 코드 코드로 변환이 순환 과정에서 채울 것입니다.
- 응용 프로그램 : 위의 최단 경로 문제를 해결
- 우선 철저한 되돌아 알고리즘
-
개인 INT minDist는 Integer.MAX_VALUE =; // 글로벌 변수 또는 필드 // 요청 : minDistBacktracing (0, 0, 0, W, N-) 공공 공극 minDistBT ( INT I, INT J, INT DIST, INT [] ] W, INT N-) { // 도달 N-1, N-1이 위치는 여기 이상한 하를 찾고, 당신은 예를 보면 IF (J == I == & & N- {N-) IF를 (DIST <minDist) minDist = DIST; 창 ; } IF (I <N-) { // 내려가 ,. 1 + I = 갱신 I, J = J minDistBT (1 + I, J, DIST +. W [I] [J ), W, N-] } IF (J <N-) { //는 I는 I를 = 업데이트 오른쪽으로 이동 J + = J. 1 minDistBT (I, J + 1, DIST +. W [I] [J], W, N-); } }
- (난, j)의 노드를 반복, 우리는 재귀 솔루션을 계속, 가장 작은 노드 DIST를 선택해야 중복 하위 문제를 발견하는 방법으로 재귀 트리 그리기, 다른 노드가 폐기 될 수있다
-
이차원 상태 테이블을 그립니다
-
public int minDistDP(int[][] matrix, int n) { int[][] states = new int[n][n]; int sum = 0; for (int j = 0; j < n; ++j) { // 初始化states的第一行数据 sum += matrix[0][j]; states[0][j] = sum; } sum = 0; for (int i = 0; i < n; ++i) { // 初始化states的第一列数据 sum += matrix[i][0]; states[i][0] = sum; } for (int i = 1; i < n; ++i) { for (int j = 1; j < n; ++j) { states[i][j] = matrix[i][j] + Math.min(states[i][j-1], states[i-1][j]); } } return states[n-1][n-1]; }
-
状态转移方程法
-
类似递归的解题思路。我们需要分析,某个问题如何通过子问题来递归求解,也就是所谓的最优子结构。
-
根据最优子结构,写出递归公式,也就是所谓的状态转移方程。有了状态转移方程,代码实现就非常简单了。
-
一般情况下,我们有两种代码实现方法,一种是递归加“备忘录”,另一种是迭代递推。
-
强调:状态转移方程是解决动态规划的关键,写出状态转移方程,问题就解决了一半!!
-
应用:解决上面的最短路径问题
-
状态转移方程:
min_dist(i, j) = w[i][j] + min(min_dist(i, j-1), min_dist(i-1, j))
-
实现代码
-
private int[][] matrix = {{1,3,5,9}, {2,1,3,4},{5,2,6,7},{6,8,4,3}}; private int n = 4; private int[][] mem = new int[4][4]; public int minDist(int i, int j) { // 调用minDist(n-1, n-1); if (i == 0 && j == 0) return matrix[0][0]; if (mem[i][j] > 0) return mem[i][j]; int minLeft = Integer.MAX_VALUE; if (j-1 >= 0) { minLeft = minDist(i, j-1); } int minUp = Integer.MAX_VALUE; if (i-1 >= 0) { minUp = minDist(i-1, j); } int currMinDist = matrix[i][j] + Math.min(minLeft, minUp); mem[i][j] = currMinDist; return currMinDist; }
-
-
四种算法思想比较分析
- 分类
- 贪心、回溯、动态规划:解决多阶段决策最优解模型。
- 分治:解决的问题尽管大部分也是最优解问题,但是,大部分都不能抽象成多阶段决策模型
- 回溯算法:
- 相当于穷举搜索,“万金油”,基本上能用的动态规划、贪心解决的问题,我们都可以用回溯算法解决。
- 时间复杂度高:指数级
- 动态规划:
- 动态规划比回溯算法高效。
- 需要满足一个模型三个特征。
- 动态规划和分治算法在重复子问题上区分非常明显。分治算法要求分割成的子问题,不能有重复子问题,而动态规划正好相反,动态规划之所以高效,就是因为回溯算法实现中存在大量的重复子问题。
- 贪心算法
- 动态规划算法的一种特殊情况。
- 更加高效,代码实现也更加简洁。
- 可以解决的问题也更加有限。它能解决的问题需要满足三个条件,最优子结构、无后效性和贪心选择性(这里我们不怎么强调重复子问题)。
- 贪心选择性”的意思是,通过局部最优的选择,能产生全局的最优选择。