데이터 구조 및 알고리즘 단축 - 동적 프로그래밍 이론을

동적 프로그래밍 이론


모델 세 가지 기능

  • 다단계 의사 결정 최적의 솔루션
  • 최적의 하부 구조
    • 최적 하부 수단은 최적의 해결책은 문제의 서브 - 최적 솔루션을 포함하고있다. 반대로 말하자면, 우리는이 문제의 서브 - 최적의 솔루션은 최적의 솔루션의 문제점을 도출 할 수 있다는 것이다.
    • 우리는 최적의 하부 구조를 취할 경우, 우리는 이전에 정의 된 동적 프로그래밍 모델의 문제에 대응이, 우리가 알 수있는 스테이지 뒤에 상태가 이전 단계의 상태에 의해 유도 될 수있다 .
  • 더 후 없습니다 효과
    • 더 후 효과 상태가 나중 단계를 유도 할 때, 우리는, 이전 단계의 값의 상태에 관심이 상태 단계 추론 단계가 얼마나 걱정하지 않는다, 두 가지 의미, 의미의 첫 번째 레이어가 없습니다.
    • 두 번째 의미는 국가가 설립 어떤 단계에서,이 단계 이후에 영향을 미치는 의사 결정의 대상이되지 않는 것입니다. 아니오 후 효과는 매우 "느슨한"요구 사항입니다. 동적 프로그래밍 모델의 문제는 앞서 언급 한 긴만큼, 사실, 그것은 기본적으로 더 후 효과를 충족하지 않습니다.
  • 반복 하위 문제
    • 이 개념은 더 잘 이해된다. 이전 하나, 나는 반복적으로 언급했다. 만약 한 문장으로, 인 의사 결정의 다른 시퀀스를 요약하고, 같은 도달 특정 단계가 중복 상태가 발생할 수 있습니다 때 .

예제와 함께 이론을 이해

  • 우리는 행렬 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)는 부합 두 상태를 유도 " 최적 하부 ."

두 동적 프로그래밍 문제 해결 아이디어 요약

  1. 상태 전이 테이블 방법은 대략, 문제 해결 방안으로 요약 할 수있다 국가의 정의 - - 재귀 트리 그림 - 알고리즘을 역 추적 중복 하위 문제를 발견 - 상태 전이 테이블을 그립니다 - 채우기 형태로 재귀 적 관계를 기반으로 - 프로세스를 작성하는 코드로 변환합니다 .
  2. 상태 전환 방정식 방법의 일반적인 아이디어로 요약 할 수 있습니다 상태 전이 방정식을 쓰기 - - 코드가 상태 전이 방정식으로 변환됩니다 최적의 하부를 찾을 .

 

  • 상태 전이 테이블 방법
    • 해결에 우선 역 추적 알고리즘 검색 폭력 여부를 사용할 수있는 동적 계획 솔루션을 볼 수있는 법을 찾아, 중복 하위 문제가 있는지 여부를 확인하기 위해 재귀 트리를 그립니다.
    • 경우 두 가지 해결책이 있습니다 :
      • 사용 + 메모 되돌아 해결 중복 노드를
      • 상태 전이 테이블 방법 :
        • 상태 표를 작성합니다. 당신이 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;
        }

         

 

四种算法思想比较分析

  • 分类
    • 贪心、回溯、动态规划:解决多阶段决策最优解模型。
    • 分治:解决的问题尽管大部分也是最优解问题,但是,大部分都不能抽象成多阶段决策模型
  • 回溯算法:
    • 相当于穷举搜索,“万金油”,基本上能用的动态规划、贪心解决的问题,我们都可以用回溯算法解决。
    • 时间复杂度高:指数级
  • 动态规划:
    • 动态规划比回溯算法高效。
    • 需要满足一个模型三个特征
    • 动态规划和分治算法在重复子问题上区分非常明显。分治算法要求分割成的子问题,不能有重复子问题,而动态规划正好相反,动态规划之所以高效,就是因为回溯算法实现中存在大量的重复子问题。
  • 贪心算法
    • 动态规划算法的一种特殊情况。
    • 更加高效,代码实现也更加简洁。
    • 可以解决的问题也更加有限。它能解决的问题需要满足三个条件,最优子结构、无后效性和贪心选择性(这里我们不怎么强调重复子问题)。
    • 贪心选择性”的意思是,通过局部最优的选择,能产生全局的最优选择。

 

 

 

추천

출처www.cnblogs.com/wod-Y/p/12146673.html