算法篇:贪心算法

上回说动态规划算法的时候,有提及贪心算法,说他也是属于分治思想下面的一类解决问题的算法,而分治思想指的就是将一个大的问题,分解成几个小的问题,通过解决小问题,最后解决大问题的解决思路,因此,贪心算法也继承了这样的思想,将一个大的问题,分解成众多小问题来解决。而他和动态规划算法的区别在于,一个是子问题的最优解不一定会是总问题的最优解,就好比如,我们探讨如下的A,B,C,D节点,其中每条边上代表是边长。


图一

现在我们要计算从A到D的最短边长和,明眼上一看,A-C-D是最短的路径,但如果要计算机能够通过计算达到最短轮径,我们就不得不列举出所有可能从A到达D的路径,依次算出所有的路径长度和并比较出最小的一条最为最短的路径。这样的做实际上也是一种方案,通过穷举法,但如果是一个比较复杂的图形,其中包含有n个节点,m条边,通过穷举法,我们最多可能有n的阶乘这么多种情况,当输入比较大的时候,这个值会很大,计算机可能会花费大量时间来计算所有的情况,而为了提高效率,通过动态规划的算法,将从A到D的问题,分解成它的子问题,很明显,我们会分解成,从A-B或者从A到C,而如果用动态规划算法,我们会保存从A-B的最短路径short(a,b),同时也会计算出A-B的最短路径short(a,c),然后,比较short(b,d)+short(b,d)<short(a,c)+short(c,d),比较的时候,我们还不确定那个是真正的从A到D的最短路径,也就是当我们解决了A-D的子问题A-B或A-C的最短路径时,我们依然无法确定那个时最短路径,而直到我们比较了子问题的解加上另外一个子问题的解的时候,才算是等到了A-C-D是最短路径。这个举例业主要是说明,动态规划算法,其之所以是动态规划,指的就是总问题的解是根据子问题的解动态调整的,子问题的解并不一定是最优解的情况,只有遍历到最后才能够得到整个问题的答案。

而贪心算法又是另外的一种情况,贪心算法是所有子问题的解一定构成了总问题的解,而解决问题的关键就是,求得每个子问题的最优解,最后得到总问题的最优解。

可以看出,贪心算法是一种比较简单的思维模式,法如其名,贪心,针对每个问题,我们都要最好的,那么总问题的结果一定就是最好的,而如果用这种想法解决上面最短路径问题,我们就发现不对了,首先从A出发,最好的是short(a,b)=1,然后再从B出发,最好的是short(b,d)=8,那short(a,d)=1+8=9,显然是不对的,所以贪心算法,是不是和用来解决这种眼前最好的不一定是后来最好的算法,有些问题的解决也不能太贪心。

什么样的情况适合用贪心算法,主要还是要考虑问题本身的特性,当发现问题具有一种单纯的累积效应的时候。例如,我今天早上列出了我今天要做的事情[a,b,c,d,e]以及他们所需要的时间[1,2,5,4,3],以及每件事情的重要程度[2,1,3,3,1],这些事情是我上班要做的事,我不想下班再做,所以我只用8个小时来做,且最后一件事情要嘛完成,要嘛就算没做,也就是一旦超过了8个小时,还在做一件事情,那么就算没做这件事,同时允许上班偷懒。现在,我有两种想法,我今天要完成尽量多的事情,另外一种是我今天要做最大的重要程度。第一种情况,尽量多的事情,那么我就要考虑,如何才能保证我做的事情足够的多,首先该做哪一个事,然后再做哪一个,这样我们就得到了一个子问题,如何选择下一件该做的事情,而使得8小时中做得事情足够多,换种思维方式就是,假设我们选择了一个事情x,使得最多事情成立,那么这个最多的情况就是1+剩下的做的事情件数,而解决问题的关键就是如何使得剩下的事情件数最多,那就是当我们出现足够多的剩下的时间的时候,可以被选择的事情件数就更多,因此我们得出了一个结论,只要我们每次选择用时最少的情况,我们就能够得到8个小时中最多的事件集合。

第二个问题,如何选择最多重要性的事情,很显然,我们不能光靠完成事情的多少就证明我们完成了多少重要度,而是依靠整个重要度的结合,这里我们很明显要考虑两个维度,一是我们选择要做的事情的用时总和不超过8小时,同时它的重要度是最大的。而针对这个问题,我们很清楚的发现,当我们选择某个事情x时,那么剩下的事情一定满足再剩下的时间中的最大的重要程度,而能否找到一个确定的x的值,满足这样的条件,答案时否定的,我们不能唯一确定一个事件[a,b,c,d,e]中的任意一个满足这样的条件,而只有当我们把这个问题逐渐推到低成问题的时候,那就是如果时间为0的时候,或者事件为0的时候,再从这个基本问题出发解决总问题,实际上我们用到的是动态规划算法。

思路:

设一个二维数组[time,important],时间重要性数组,其中包括了我们输入的所有情况,同时在设一个满足最高重要度和的事件集合things

设事件x为重要性数组的一个事件

那么就有,如果事件x属于things,important(things)=important(things-x)+important(x);time(things)=time(things-x)+time(x)

如果事件x不属于things,那么important(things)=important(things-x);time(things)=time(things-x)

同时有,important(o)=0,time(o)=0,也就是[0,importants]=0,[time,0]=0,[0,0]=0

而如何判断事件x是否在things里面,我们只需要判断,important(things-x)<important(things-x)+important(x),且times(things-x)+times(x)<8

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 专业考题类型管理运行工作负责人一般作业考题内容选项A选项B选项C选项D选项E选项F正确答案 变电单选GYSZ本规程...
    小白兔去钓鱼阅读 10,489评论 0 13
  • 1. 关于诊断X线机准直器的作用,错误的是()。 (6.0 分) A. 显示照射野 B. 显示中心线 C. 屏蔽多...
    我们村我最帅阅读 11,391评论 0 5
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,841评论 0 10
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 11,038评论 0 23
  • 贪心算法 贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上...
    fredal阅读 9,421评论 3 52

友情链接更多精彩内容