动态规划和贪心算法分析(装配线调度、最小生成树)
来源:互联网 发布:网络国际电话 编辑:程序博客网 时间:2024/06/06 13:11
本文主要从问题分析的角度介绍动态规划和贪心算法,文中不涉及代码。通过装配线调度问题和最小生成树问题,说明怎样运用动态规划和贪心算法解决问题。
1 装配线调度问题
1.1 问题描述
如下图所示,某个工厂有两条装配线,每条装配线上有n个装配站,装配站S_{i,j}表示第i条装配线上的第j个装配站,其中i=1,2,j=1,2,…,n。装配站S_{1,j}与装配站S_{2,j}具有相同的作用,其中a_{i,j}表示装配站S_{i,j}完成装配所需要的时间,在同一条装配线上,商品从上一个装配站转移到下一个装配站不需要时间,但是如果商品从一条装配线换到另一条装配线上则需要时间t,如图所示。一件商品从开始端进入装配线的时间分别是e_1,e_2。然后必须依次经过没个装配站进行装配,然后在结束端离开装配线的时间分别是x_1,x_2。带求解问题是应该确定在装配线1内选择哪些站,在装配线2内选择哪些站,才能使商品通过工厂的时间最小。
1.2 问题分析
首先,这是一个做选择类的问题,而对于做选择的所有问题我们都可以从穷举的角度去分析问题。我们最终要选择一个装配路线,使得商品的装配时间最少,而在每一个装配站都有两个选择(装配线1,还是装配线2)。所以要穷举所有的装配路线,一共有2^n种选择,那么算法的运行时间复杂度是O(2^n),当n很大时显然是不可取的。
现在,从动态规划的角度去分析这个问题。关于动态规划,要记住一点,就是动态规划是以空间换时间的。接下来我们就需要好好理解这个话。首先要明确该问题中的目标值是什么。从问题中知道,该问题是选择装配路线,使得商品的装配时间最少。所以,很明显目标位装配的时间T。T(1,i)表示经过装配线1上第i个装配站后的装配时间,T(2,i)表示经过装配线2上第i个装配站的装配时间。所以可以得到如下的递归公式。
可见,在求第i时刻的最优解T(1,i)和T(2,i)时,需要i-1时刻的最优解T(1,i-1)和T(2,i-1)。这里出现了重叠子问题,所以可以将子问题的解以表的形式保存起来,那么以后要用的时候不用重新计算,只要查表就行了,这就是所谓的以空间换时间。
1.3 具体实例
在求解问题最优解的过程中,首先求解子问题的最优解,并将结果保存起来。在求解过程中,需要两张表来保存结果。T表保存目标值,P表保存路径。
第一步,初始化两张表。
第二步,根据递归公式计算。i=1时。
i=2时,
i=6时,
第三步,根据T表和P表得到最优解。
2 最小生成树问题
2.1 问题描述
对于一个无向连通图G=(V,E),其中V为图的顶点集合,E为图的边集合。对图中每一条边(u,v),都有一个权值w(u,v)表示连接u和v的代价,找出一个E的子集T,连接所有的顶点,并且保证权值和w(T)最小。
2.1 问题分析
首先,这个问题也是关于选择的问题。问题的解为一系列边的集合,并且满足两个条件:保证图的连通性;权值和最小。所以最原始最简单的方法就是穷举,然后判断是否满足着两个条件。假设图的有e条表,那么E的子集个数为2^e种情况,因此算法的运行时间复杂度为O(2^e),当e很大时,这显然是不行的。
现在从动态规划的角度来分析这个问题,找出最优子结构。这个问题要优化的目标值为树的权值和W。可以从顶点和边两方面来找递归公式。
从顶点出发,将图中的顶点排序{V1,V2,…,Vi,…Vn}。W(i)表示连接{V1,V2,…,Vi}的最小生成树的权值。其中如果边(i,j)不存在,则w(i,j)为无穷大。
可以采用“剪切-粘贴”法,证明该递归公式的重要性。证明比较简单,这里就不在证明了。这个算法的实现也就是经典的Prim算法了。
从边出发,将图中的边按照权值由小到大排序,排序结果为{E1,E2,…,Ei,…,Ee}。每条边Ei在最优解中只有两种选择:被选与不被选。W(i)表示判断表Ei是否被选后,树的权值。则递归公式可表示为:
所谓的连通性是否改变就是有没有新的顶点加进去。同样采用“剪切-粘贴”法可证明该递归公式的重要性,这个递归公式的实现也就是Kruskal算法了。
众所周知,Prim算法和Kruskal算法都是贪心算法,而上面都分析都是从动态规划的角度去分析问题的。下面就看看动态规划与贪心算法,分析问题时的不同。
认真观察上面的递归公式可以看出,装配线调度问题的递归解中出现了重叠子问题T(1,i-1)和T(2,i-1),而最小生成树时,要计算W(i),只要知道W(i-1)即可,没有重现重叠子问题。换言之,也就是最小生成树问题的求解,只需要一个子问题,再进行相关处理就行了。所以当动态规划的递归解满足这个特性的时候,就可以采用贪心算法来解决。贪心算法是动态规划的一个特例,能用动态规划解决的问题,当满足一定条件的时候就可以用贪心算法解决。
3 动态规划与贪心算法分析总结
动态规划是一种用空间换时间,从而降低算法的时间复杂度的算法。适合采用动态规划的最优问题需要两个要素:最优子结构和重叠子问题。
最优子结构
如果一个最优解中包含子问题的最优解,则该问题具有最优子结构。现在问题的关键是如何判断一个最优问题是否有最优子结构,以及给出一个最优子结构,怎么判断是最优解的子结构。这两个问题其实是一个问题。要解决这两个问题,一般我们从问题本身出发,采用自顶向下的方法进行分析。首先,根据推理或经验等给出一个递推解的结构,再证明该结构为该最优问题的最优子结构,常用的证明方法有“剪贴”技术。
在寻找最优子结构时,可以遵循一种共同的模式:
1)、问题的一个解,可以是做一个选择。例如,选择一个前一个装配线转配站;或者选择一个下标以在该位置分裂矩阵链。做这种选择会得到一个或多个有待解决的子问题。
2)、假设对一个给定的问题,已知的是一个可以导致最优解的选择。不必关系如何确定这个选择,尽管假定它是已知的。然后要确定哪些子问题随之变化,以及如何最好地描述所得到的的子问题空间。
为了描述子问题空间,可以遵循这样一条有效的经验规则,就是尽量保持这个空间简单,然后在有需要的时候再扩充它。
最优子结构在问题域中以两种方式变化:
1)、有多个子问题被使用在原问题的一个最优解中
2)、在决定一个最优解中使用哪些子问题时有多个选择
动态规划以自底向上的方式利用最优子结构。也就是说,首先找到子问题的最优解,解决子问题,然后找到问题的一个最优解。寻找问题的一个最优解需要在子问题中做出选择,即选择将用哪一个来求解问题。问题的代价通常是子问题的代价加上选择本来带来的开销。贪心算法与动态规划有很多相似之处。特别地,贪心算法适用的问题也具有最优子结构。贪心算法与动态规划有一个显著的区别,就是在贪心算法中,是以自顶向下的方式使用最优子结构。贪心算法会先做选择,在当时看起来是最优的选择,然后再求解一个结果子问题,而不是先寻找子问题的最优解,然后在做选择。
解决这类问题的一步步骤:
1、判断问题是否为选择类问题。
2、找出目标值。
3、找最优子结构,写出递归公式。
根据递归公式判断是否有重叠子问题,有重叠子问题,采用动态规划解决,无重叠子问题采用贪心算法解决。
- 动态规划和贪心算法分析(装配线调度、最小生成树)
- 算法导论--动态规划(装配线调度)
- 算法导论--动态规划(装配线调度)
- 【算法】【动态规划】装配线调度
- 装配线调度(动态规划)
- 装配线调度问题(算法导论+动态规划)
- 【算法导论】动态规划--装配线调度问题
- 动态规划算法之装配线调度
- 算法练习 动态规划 装配线调度
- 动态规划-装配线调度
- 动态规划----装配线调度
- 动态规划(DP)-装配线调度问题
- 算法导论 15章 动态规划 装配线调度算法
- 【算法导论】动态规划算法之装配线调度
- 动态规划--装配线调度问题
- 动态规划--装配线调度问题
- 动态规划 - 装配线调度问题
- 【动态规划】装配线调度代码
- 在u-boot中制作升级菜单
- 求连续子数组的最大和,并记录其起始结束位置
- 【问题】Cannot find any information on property 'userPhone' in a bean of type 'Bean'.
- win7,win8安装pl2303驱动失败的解决方法-关闭驱动自动安装功能
- 帮助你优化前端性能的工具类网站 - browserdiet
- 动态规划和贪心算法分析(装配线调度、最小生成树)
- C#关闭一个窗口的同时打开另一个窗口
- ULARGE_INTEGER
- NYOJ 359 Delete it 字符串处理
- 一步步教你粗暴破解宫爆老奶奶-APK反编译教程
- 我的设计模式学习之路1(单例模式)
- varnish 503的一种分析 nginx tomcat gzip
- 使用位运算实现乘法和乘方运算
- 用一个宏定义FIND求一个结构体struct里某个变量相对struct的编移量