`

动态规划算法

阅读更多

动态规划主要指的现阶段的所做决策最优决策加上将来所做的最优决策组合起来肯定是最优决策,它需要满足三个条件:

1.最优化原理(最优子结构性质):一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质

2.无后向性:将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态

3.子问题的重叠性:。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其它的算法

详细介绍参见http://www.ahhf45.com/info/Data_Structures_and_Algorithms/algorithm/technique/dynamic_programming/chapter3.htm

接下来会列举几个经典题目,及解法:

1.0/1背包问题

题目:给定一个载重量为m,n个物品,其重量为wi,价值为vi,1<=i<=n,要求:把物品装入背包,并使包内物品价值最大

解题思路:每一个对象都只有两种状态,一种是在箱子里面,另一种是不在箱子里面,那么当重量相同的时候,我们可以去当前对象在箱子里面和当前对象不再箱子里面两种情况中的最佳值作为最优解,并记录下来。

是否满足3个特征:1.它满足最优化原理,既当对于前面判断好的对象,在某个具体的重量上的价值都是最优化的。

                          2.以前的对象是不是放到箱子里面,对后面的对象没有影响。

                          3.存储了以前的最优状态

算法的具体实现:

package com.fnk.acm;

public class Package {
	private static int PackageWeight = 15;
	private static int[] objectWeights = new int[] { 2, 6, 4, 7, 9 };
	private static int[] objectValues = new int[] { 1, 6, 5, 9, 4 };

	private static int[][] value = new int[objectWeights.length + 1][];

	//初始化对象
	private static void init() {
		for (int i = 0; i < value.length; i++) {
			value[i] = new int[PackageWeight + 1];
		}
		
		for (int i = 0; i < value.length; i++) {
			for (int j = 0; j <= PackageWeight; j++) {
				value[i][j] = -1;
			}
		}
	}

	public static int getMaxValue() {
		init();
		for (int i = 1; i < value.length; i++) {
			for (int j = 1; j <= PackageWeight; j++) {
				//首先将 重量为j的ID为i-1的value值 赋值给重量为j的ID为i的对象。这个 我们可以想象成第i的对象不放到箱子里面去。那样重量不变,价值额不变
				value[i][j] = value[i - 1][j];
				//当第 i个对象的重量小于J并且, value[i][j] < value[i - 1][j - objectWeights[i - 1]]+ objectValues[i - 1].
				//此处我们假设 i为2,j为10. objectWeights[1]为5,那么value[i - 1][j - objectWeights[i - 1]] = value[1][5],objectValues[i - 1]
				//指第2个对象的重量。那么整句的意思是,需要去判断一下,不妨第二个对象的价值大,还是第二个对象进去的价值大,取大的那个。
				if (objectWeights[i - 1] <= j
						&& value[i][j] < value[i - 1][j - objectWeights[i - 1]]
								+ objectValues[i - 1]) {
					//当第i个对象的重量等于j或者当value[i - 1][j - objectWeights[i - 1]]不为-1的时候才能将第I个对象放进箱子里
					//当value[i - 1][j - objectWeights[i - 1]] = -1的时候,其实里面是没有放对象的,那么其实重量为0,那么把它当成重量为j - objectWeights[i - 1]就没有意义了
					if (j == objectWeights[i - 1]){
						value[i][j]= objectValues[i - 1];
					}else if(value[i - 1][j - objectWeights[i - 1]] != -1){
						value[i][j] = value[i - 1][j - objectWeights[i - 1]]
													+ objectValues[i - 1];
					}
				}
			}
		}
		int maxValue = 0;
		int weight = 0;
		for (int i = 1; i <= PackageWeight; i++) {
			if (value[objectWeights.length][i] > maxValue) {
				maxValue = value[objectWeights.length][i];
				weight = i;
			}
		}
		System.out.print("Max Value:" + maxValue + ",Weigth:" + weight);
		return 0;
	}

	public static void main(String[] args) {
		Package.getMaxValue();
	}
}

 2.求两地最短路径算法

解题思路,从目的地开始往后遍历。如果某一点有到目的地更近的方案,就记录下来。

是否满足3个特征:1.它满足最优化原理,如果当前节点到目的地的路径有n条,那么前n个点的最优解加上前个节点到当前节点的距离之和的最优解也就是当前节点到目的在的最优解        

                          2.是否经过当前节点和以前的状态没有关系

                         3.存储了以前的最优状态

package com.fnk.acm;
public class MinPath {
   private static char node[] = {'A','B','C','D','E','F','G'};  
   private static int array[][]=  
     {        /*  A  B  C  D  E  F  G*/  
           /*A*/ {0, 5, 2, 0, 0, 0, 0},  //      B -3- D   
           /*B*/ {0, 0, 0, 3, 2, 0, 0},  //     /  /     /4   
           /*C*/ {0, 0, 0, 0, 7, 4, 0},  //   /5    2/     /_   
           /*D*/ {0, 0, 0, 0, 0, 0, 4},  //  A         E -3- G   
           /*E*/ {0 ,0, 0, 0, 0, 0, 3},  //    /2    /     /   
           /*F*/ {0, 0, 0, 0, 0, 0, 5},  //      / /7    /5     
           /*G*/ {0, 0, 0, 0, 0, 0, 0}   //       C -4- F   
     };  
   
  
   
   public static int getMinRoutineVal( )  
   {  
    int len = array[0].length;
       int ret=0;  
       int sr[] = new int[len];  
       int way[] = new int[len];  
       int i,j,temp;  
       sr[len-1] = 0;  
       way[len-1] = len-1;  
       for(i=len-2; i>=0; i--)  //计算每点的最小routine value.从根向顶层遍历   
       {  
           sr[i] = 0;  
           way[i] = 0;  
           for(j=i+1; j<len; j++)  
           {  
               if(array[i][j] != 0)  
               {  
                   temp = sr[j]+array[i][j];  
                   if(sr[i] == 0 || temp < sr[i])  
                   {  
                       sr[i] = temp;  
                       way[i] = j;  
                   }  
               }             
           }  
       }  
       PrintWay(way);
       ret = sr[0];  
       return ret;  
   }
   
   public static void PrintWay(int way[])    //打印路径   
   {  
       int i=0;
       int len = way.length;
       while(i != len-1)  
       {  
        System.out.println(node[i]);  
           i = way[i];  
       }  
       System.out.println(node[i]);  
   }  
   
   
   public static void main(String[] args){
    //MinPath.getMinPath();
    MinPath.getMinRoutineVal();
   }
}

 

 

 

分享到:
评论

相关推荐

    动态规划算法的应用

    "动态规划算法的应用" 动态规划算法是一种非常强大且广泛应用的算法思想,它可以解决许多复杂的问题。动态规划算法的核心思想是将问题分解成小问题,然后使用Memoization技术将中间结果存储起来,以便后续问题的...

    动态规划算法经典题目

    动态规划算法经典题目分析 动态规划是一种非常经典的算法思想,解决的问题领域非常广泛。动态规划的基本思想是将一个复杂的问题分解成多个小问题,通过解决这些小问题来解决整个问题。今天,我们将要探讨动态规划的...

    动态规划算法课件PPT

    动态规划算法课件PPT 动态规划算法是解决问题的有效方法,它将问题分解成多个子问题,然后通过解决这些子问题来解决原问题。动态规划算法与分治法类似,但不同的是,动态规划算法中子问题之间存在相互依赖关系,...

    多阶段决策过程问题的动态规划算法

    动态规划算法是一种强大的工具,主要用于解决多阶段决策过程中的最优化问题。在计算机科学和算法设计中,动态规划提供了一种系统化的方法来处理复杂问题,尤其在那些问题的最优解可以通过组合子问题的最优解来得出的...

    北京工业大学--算法作业2--动态规划算法实现0-1背包问题---Java

    北京工业大学--算法作业2--动态规划算法实现0-1背包问题---Java代码 利用动态规划算法实现0-1背包问题或装配线调度问题。(二选一) 要求测试数据以文本文件的形式存储, 即所有的数据由文本文件读入。 利用动态...

    动态规划算法实现投资问题

    "动态规划算法实现投资问题" 资源分配问题是指在给定的总资源下,如何将其分配给多个工程项目,以获得最大利润的问题。这种问题可以使用动态规划算法来解决。 在动态规划算法中,我们首先需要定义状态变量,例如...

    背包问题动态规划算法模拟设计与实现

    【背包问题动态规划算法模拟设计与实现】 背包问题是一类经典的优化问题,在计算机科学和运筹学中广泛应用。它的核心是通过有限的资源(背包的容量)来最大化收益(子物品的价值)。0-1背包问题是最基础的形式,...

    动态规划算法原理与应用

    "动态规划算法原理与应用" 动态规划是一种解决最优化问题的基本方法,它可以分解为多个互相联系的阶段,每个阶段都需要进行决策,以达到目标函数的极大或极小。动态规划的主要思想是将问题实例分解为更小的、相似的...

    《动态规划算法实验》实验报告.docx

    《动态规划算法实验》实验报告主要探讨了两个经典动态规划问题——0-1背包问题和合唱队形安排问题。这两个问题都是在优化决策过程中寻找最优解的经典实例。 **一、0-1背包问题** 0-1背包问题是一个经典的约束优化...

    动态规划算法简介 很详细

    子问题重叠是动态规划算法效率的关键,即在解决问题的过程中,某些子问题会被多次求解。通过存储子问题的解,我们可以避免重复计算,提高效率。这也是动态规划与分治法的主要区别,后者通常处理独立的子问题。 设计...

    动态规划算法比对蛋白质序列

    动态规划算法是一种在计算机科学和生物学领域广泛应用的解决复杂问题的方法。在本场景中,它被用来比对蛋白质序列,这是生物信息学中的一个核心任务。蛋白质序列比对旨在寻找两个或多个蛋白质序列之间的相似性,这...

    水库调度程序包含12个动态规划算法的程序代码

    这12个动态规划算法的程序代码是解决此类问题的实例,使用了C++编程语言,适用于后端开发。 动态规划的基本思想是将一个复杂问题分解为若干个子问题,通过求解子问题的最优解来得到原问题的最优解。在水库调度问题...

    matlab实现动态规划算法 程序源码.zip

    【达摩老生出品,必属...资源名:matlab实现动态规划算法 程序源码.zip 资源类型:程序源代码 源码说明: 基于matlab实现动态规划的程序,包含完整源码和注释,非常适合借鉴学习 适合人群:新手及有一定经验的开发人员

    数据结构动态规划算法总结

    数据结构动态规划算法总结 动态规划是一种重要的算法思想,广泛应用于经济管理、生产调度、工程技术和最优控制等方面。动态规划是解决多阶段决策过程的优化问题的数学方法,由美国数学家R.E.Bellman等人在20世纪50...

    动态规划算法的应用实验报告.doc

    动态规划算法是一种强大的工具,常用于解决复杂的问题,如寻找最优化解。在这个实验报告中,我们关注的是如何运用动态规划解决数塔问题。数塔问题是一个典型的动态规划实例,它要求从一个下三角矩阵的顶部出发,找到...

    第三讲:动态规划算法详解.pptx

    动态规划算法详解 动态规划算法是解决多阶段决策问题的一种方法,它可以将问题分解成多个阶段,每个阶段都需要做出决策,整个过程的决策序列是一个最优的解决方案。动态规划算法的基本思想是对整个过程的最优策略...

    动态规划算法与贪心算法

    ### 动态规划算法与贪心算法 #### 最优化原理 最优化原理是解决多阶段决策问题的关键。这一原理最早由美国数学家R. Bellman等人于1951年提出,他们指出:一个最优策略的子策略对于它的初态和终态而言也必须是最优...

    图像压缩动态规划算法Java代码

    利用动态规划算法解决图形图像处理问题,用Java编写,代码经过调试健壮性良好

    动态规划算法的优化技巧

    动态规划算法作为一种强大的编程策略,尤其在解决具有重叠子问题和最优子结构特性的问题时,展现出了其独特的魅力。然而,在实际应用中,尤其是在ACM等编程竞赛中,动态规划算法的时间效率优化成为了参赛选手关注的...

    C++ 动态规划算法实现0-1背包问题

    总的来说,这个C++实现的0-1背包问题动态规划算法不仅展示了如何利用动态规划解决问题,还提供了代码调试和测试的方法,是学习和理解动态规划算法的一个优秀实例。通过深入研究和实践,我们可以掌握这一重要的算法...

Global site tag (gtag.js) - Google Analytics