动态规划 既Dynamic Programming
1)动态规划是运筹学中用于求解决策过程中的最优化数学方法。 当然,我们在这里关注的是作为一种算法设计技术,作为一种使用多阶段决策过程最优的通用方法。
它是应用数学中用于解决某类最优化问题的重要工具。
2)如果问题是由交叠的子问题所构成,我们就可以用动态规划技术来解决它,一般来说,这样的子问题出现在对给定问题求解的递推关系中,这个递推关系包含了相
同问题的更小子问题的解。动态规划法建议,与其对交叠子问题一次又一次的求解,不如把每个较小子问题只求解一次并把结果记录在表中(动态规划也是空间换时间
的),这样就可以从表中得到原始问题的解。
直接看例子
国际象棋中的车可以水平的或竖直的移动,一个车要从一个棋盘的一角移到对角线的另一角,有多少种最短路径?
用动态规划算法求解(假设棋盘为n*n,最短路即不能回退)
我们设定 F[i , j]表示从坐标(0,0)到(i ,j)的方法数(定义F[i , j]的含义,动态规划的一个关键点):
很明显,要走到坐标(i ,j),它的上一步的坐标必定是(i-1 ,j)或者(i ,j-1) (分析动态规划问题的逆向思考)
这样就将问题描述为了交叠子问题:
F[i , j] = F[i -1, j] + F[i , j-1] ( F[i , j] 拆解成更小的交叠的子问题 )
我们要求的是F[n , n]
列出初始边界条件:
F[0 , j] = 1
F[i , 0] = 1
填矩阵的形式:可以按行也可以按列。
典型的动态规划的算法,由最小的边界条件处依次递归.
把矩阵填出来以后也很简单
1 8 36 120 330 792 1716 3432
1 7 28 84 210 462 924 1716
1 6 21 56 126 252 462 792
1 5 15 35 70 126 210 330
1 4 10 20 35 56 84 120
1 3 6 10 15 21 28 36
1 2 3 4 5 6 7 8
车 1 1 1 1 1 1 1
这个图似曾相识吧,没错,这就是帕斯卡三角形(Pascal's Triangle)
1
11
121
1331
14641
...........
的变形.即二项式的展开系数.因此其实F[n , n]即为C(2n , n)
(c(n,m)=p(n,m)/m!=n!/((n-m)!*m!))
二项式系数的性质图里也已经很明显了 C(n,k)=C(n-1,k-1)+C(n-1,k) n>k>0
代码:
/**
* Copyright 2012, NEWTOUCH Co., Ltd. All right reserved.
*/
package calculation.dynamicprogramming;
/**
* @author aijnec
*/
public class ChessTest {
//棋盘维度
private static int n = 8;
//棋盘模型
private long[][] chessBoard = new long[n][n];
/**
* 构造棋盘矩阵 往格子里填方法数
*
*/
private void buildChessBoard(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==0 || j==0){
//边界条件
chessBoard[i][j]=1;
//System.out.println("chessBoard["+i+"]"+"["+j+"]="+chessBoard[i][j]);
}else{
//子方法递推
chessBoard[i][j]=chessBoard[i-1][j]+chessBoard[i][j-1];
//System.out.println("chessBoard["+i+"]"+"["+j+"]="+chessBoard[i][j]);
}
}
}
}
/**
* 取得从(0,0)走到对角端点(n,n)的最短方法数
* @return
*/
public void getPointNum(){
buildChessBoard();
System.out.println("pointNum="+chessBoard[n-1][n-1]);
}
public static void main(String[] args){
ChessTest test = new ChessTest();
long startTick,endTick;
startTick = System.nanoTime();
test.getPointNum();
endTick = System.nanoTime();
System.out.println("process costs "+(endTick-startTick)+" ns");
}
}
分享到:
相关推荐
动态规划算法的步骤包括:找出最优解的性质,递归地定义最优值,以自底向上的方式计算出最优值,并根据计算最优值时得到的信息构造一个最优解。 动态规划算法的特征是具有最优子结构性质和子问题重叠性质。最优子...
根据给定文件的信息,我们可以提炼出以下几个与...以上就是通过对给定文件的分析提取出来的三个动态规划经典例子及其相应的解决方案。这些例子不仅展示了动态规划的基本思想,还提供了实际的应用场景和具体的实现方法。
动态规划通过构建一个二维数组,其中每个元素表示在特定容量下能获得的最大价值。 2. **最长公共子序列**:给定两个字符串,动态规划寻找它们的最长子序列,子序列不必连续。通过构造一个二维矩阵,记录两个字符串在...
此外,动态规划还可以用于解决字符串操作问题,如“最小编辑距离”,该问题描述了将一个字符串转换为另一个字符串所需的最少单字符操作次数(插入、删除或替换)。状态可以是两个字符串的起始位置,转移方程根据字符...
在这个命令行实现的例子中,我们可以考虑一个经典的动态规划问题,如斐波那契数列或者背包问题。例如,我们可以用动态规划解决0-1背包问题,目标是在给定的容量限制下,使装入背包的物品总价值最大。这个问题可以...
动态规划的核心在于构造一个状态转移方程,它描述了从一个子问题的状态转移到另一个子问题的状态的过程。这个方程通常涉及递推关系,即当前状态的最优解可以通过已知的子问题最优解来获得。在实现动态规划时,我们...
虽然没有提供具体的细节,但我们可以推测这是一个演示如何应用动态规划的实例。可能的例子包括背包问题、最长公共子序列、最小编辑距离等经典问题。这些问题都有一个共同点:它们都可以通过分解为子问题,然后使用...
动态规划的核心思想在于将一个复杂的问题分解为一系列较小的子问题,并通过对这些子问题的递归求解来找到整体的最优解。下面是动态规划模型中几个重要的概念: ##### 1. 阶段 (Step) 阶段是对整个过程的自然划分。...
这两个例子展示了动态规划算法的基本思想:将大问题分解为小问题,通过解决这些小问题来构建大问题的解。这种思想与递归不同,尽管递归也可以解决同样的问题,但递归方法往往伴随着大量的重复计算,特别是在问题规模...
在这个例子中,"ex1_1add"可能是一个简单的动态规划问题的代码实现,可能涉及到矩阵操作和循环结构,这些都是MATLAB的优势所在。 程序可能包含以下几个关键部分: 1. **状态定义**:首先,需要定义问题的状态,这...
这些例子可以帮助我们更好地理解和应用动态规划。 例如,斐波那契数列的动态规划解决方案可以通过维护两个数组元素f[n-1]和f[n-2]来实现,其中f[n]表示第n个斐波那契数。状态转移方程可以表示为f[n] = f[n-1] + f[n...
旅行商问题 一个使用动态规划的精确解方法的 Python 代码示例, 旅行商问题 (Traveling Salesman ...在这个例子中,我们使用一个简单的距离矩阵来表示城市之间的距离,你可以根据实际情况替换为你自己的距离数据。
给定的问题是一个实际应用树形动态规划的例子,寻找最快找到Chris的路径。这个问题符合上述的状态定义和状态转移规则。父母需要从家出发,根据A、B、C之间的相对距离选择最有利的路线。这个问题可以通过"根->叶"的...
具体来说,当动态规划的状态转移方程具有某种单调性时,可以通过维护一个单调队列来减少不必要的计算,从而降低算法的时间复杂度。 **4. 时间效率分析** 在利用单调队列进行动态规划优化时,每个元素至多入队一次和...
数字三角形问题只是动态规划众多应用场景中的一个典型例子,动态规划还可以应用于诸如最短路径问题、背包问题等多种优化问题。随着对动态规划理解的加深,我们能够更加灵活地将其应用于更多实际问题中。
3. **问题求解模式**:动态规划处理的问题往往可以被视为一个多阶段决策过程。从初始状态出发,经过一系列决策到达最终状态,这些决策构成了完成整个过程的活动路线。动态规划的设计步骤通常包括划分阶段、确定状态...
在本压缩包中,"基于MATLAB动态规划中最短路线的实现程序.pdf" 文件提供了一个实际的MATLAB代码示例,用于演示如何利用动态规划来解决最短路径问题。 动态规划的核心思想是将一个复杂问题分解为多个子问题,通过...
首先,动态规划的基本思想是将一个复杂的问题分解为一系列相互关联的子问题,通过对子问题的求解来得到原问题的解答。与分治法不同,动态规划不简单地将问题一分为二,而是考虑所有可能的子问题,并避免重复计算,...
在一维动态规划问题中,每个阶段的状态可以通过一个状态变量\( s_k \)来描述,同时每个阶段也只需要选择一个决策变量\( x_k \)。这类问题的求解通常有两种方法:解析法和数值法。 **解析法**是一种利用数学公式表示...