贪婪算法的应用:

相关算法练习题:
LeetCode股票买卖的最佳时机
LeetCode判断子序列
LeetCode 分发饼干
LeetCode跳跃游戏
LeetCode加油站

一、简单调度问题:

给出作业和作业的运行时间,现在只有一个处理器,我们假设使用非预占调度(一旦开始一个作业,必须完成),现在我们要把作业平均完成的时间最小化。

举例:

作业 时间
j1 15
j2 8
j3 3
j4 10

其中一种调度方式:

15 8 3 10
j1 j2 j3 j4

完成作业花费的时间:

j1=15
j2=15+8=23
j3=15+8+3=26
j4=15+8+3+10=36

一共花费的时间:

     15+23+26+36=10015×4+8×3+3×2+10×1

所以,平均完成一项作业需要:
100/4=25;

如何使平均完成时间最少?

j1是第一个完成的作业, 则它所花的时间一共要累加 4次
j2 是第二个完成的作业,则它所花的时间一共要累加 3次
出现 第 i 次,累加 (n-i+1)次
该调度花的总时间:


要使总花的时间最少,C的前面一个求和公式是固定的,后面一个求和要最大。显然,当 K大的时候,tk是大的,则这样累加起来最大。
举个例子:

k=0,1,t1=23,t2=7
0×7+23×1=23 > 1×7+23×0=7

所以,时间花费少的要在前面完成,时间花费多的要在后面完成。这个结果也指出了为什么操作系统要将优先级给短的程序。

根据上述描述的方法我们做出另一种调度方式:

3 8 10 15
j3 j2 j4 j1

平均完成一项是17.5,明显该种调度方式就是最优调度。

扩展:
当多处理器时,按顺序开始作业,多处理器交叉处理。
如果要求的是这些作业的最早结束时间,则这个问题便是NP-完全的。实际上,所有的调度问题要么NP-完全的,要么是贪婪可解的。

二、应用处理文件压缩

假设我们有7个字符,每个字符出现的频率不等。

a c e g w t i
45 3 21 8 10 30 80

如果我们按照一般的方法来存储这些数据,那么我们应该用3位二进制码来表示这7个字符。

因此我们一共要存储数据总量:

               Σ(3×出现的频率)

这样出现频率低的编码和出现频率高的编码都是一样的长度,如果我们要使它的数据总量尽可能地少,那么我们想出了另外一种方法来表示编码,使得出现频率越高则编码越短,这种编码就叫做Huffman编码

如何构造一个Huffman编码呢,我们在二叉树的帮助下。
我们令这些字符作为一个树的叶子结点,

从根结点开始,左边分支上的权0,右边上为1。那么每个字符都有一个编码。

现在我们对树进行修改,使它成为一颗Huffman树,Huffman树是满足下列三个条件的树:

  • 字符只能够在叶子结点上,这样规定是为了防止一个字符是另一个字符的前缀编码,防止造成二义性。
    比如在 t 的父节点是字符 b ,那么 t:101;b:10,当我们有个编码串为 101001001 则首个字符可以解释为t 也可以为 b。
  • 我们可以把 i 向上移动一层,这是没有影响的。
  • 出现频率最大的字符所在的叶子结点要尽量在上层,这样它的编码长度才会尽可能短。

如何构造Huffman 树?
1.为所有字符创建叶子结点,并且把这些结点全部放在最小堆里
2.从最小堆里找出两个出现频率最小的叶子
3.创建一个新的内部结点,新的内部节点的频率是第二步里找出来的两个结点的和,两个结点一个作为内部结点的左结点,一个作为内部结点的右结点,然后将新的内部结点添加到最小堆里,而两个结点去除
4.重复上述2,3,直到最小堆里直剩下一个结点,剩下的结点是树的根节点,到此为止,Huffman tree 形成!

这个算法是贪婪算法的原因是我们每次只选取两个最小的叶子 结点,而没有进行全局的考虑。

三、近似装箱问题

当我们解决问题时,为了找到全局最优解,我们通过在每个步骤寻找局部最优,但是有时我们不能够获得全局最优。

举例:

如果我们要从第一个结点开始寻找最大的路径:

       greedy:1+3+7=11actual:1+2+4+8+12=27

因此,局部最优解不一定会得到全局最优解。

那什么时候可以使用贪婪算法呢?
满足两个条件:
1.全局最优可以由局部最优得到,但是这个只有在我们得出结果后才能知道是不是最优的。
2.最优子结构:
an optimal solution to the problem contains an optimal solution to subproblems
这里和动态规划的区别,贪心算法从来不会再重新考虑他的选择

我们将使用一些方法使得所得的解离最优解不是很远。

装箱问题一般分为两种:

  • 联机装箱(on-line):
    必须将一个物品放到一个箱子里,才能处理下一个物品。来一个我装一个
  • 脱机装箱(off-line)
    只有当输入数据全部输入才能进行工作。所有物品都来了,我再一起装

联机装箱

1.下项合适(next fit)算法
当处理一个物品时我们看它可以不可以装进刚刚装进物品的箱子里,如果可以,则装入;如果不可以,则新开辟一个箱子。

算法改进:0.3其实不用新开辟箱子,而可以放在B2中,因此我们引入第二种算法。
2.首次合适(first fit)算法
当处理一个物品时,我们同时遍历所以的箱子,将物品放在第一个可以容纳物品的箱子中。

算法改进:0.3也许我们可以将它放在B3,这样虽然没有使箱子的个数减少,但是,如果还有新的物品进来,更能容纳更多的物品,于是我们引入最优合适算法。

3.最优合适(best fit)算法
当处理一个新的物品时,同时遍历箱子,使得物品放在使得箱子最满的情况下。
综上,我们发现了,联机算法最大的弊端就是大项物品装箱困难,尤其是当大项物品是后面处理的,这样我们要不停的开辟新的箱子,因此,如果我们先将大项物品放入箱子中,这样是不是更好呢?于是我们引入脱机算法。

脱机装箱
当所有物品都已经给出,我们先对它们进行排序,将大的物品先进行装箱。此时我们可以运用联机算法的首次适合算法和最优适合算法,此时称为首次适合非增算法和最优适合非增算法。

应用

1.Activity Selection Problem
给了一些活动的开始时间和结束时间,对于一个人来说,他最多可以完成多少活动
方法:
1.我们先通过结束时间对活动进行排序
2.选择第一个活动。
3.然后遍历剩下的活动,如果剩下的活动开始时间晚于或等于他的前一个活动的结束时间,则可以选择这个活动,否则不行

2.Huffman coding

3.Job Sequencing Problem

4.Fractional Knapsack Problem
5.Prim’s Minimum Spanning Tree

未完待续。

贪婪算法(greedy Algorithm)相关推荐

  1. 贪婪算法-Greedy algorithm

    贪婪算法(greedy algorithm) WIKI A greedy algorithm is an algorithmic paradigm that follows the problem s ...

  2. 贪心(Greedy Algorithm)

    贪心(Greedy Algorithm) 贪心 44.通配符匹配 45.跳跃游戏 II 55.跳跃游戏 122.买卖股票的最佳时机II 134.加油站 135.分发糖果 179.最大数 277.搜寻名 ...

  3. 数据结构与算法(C++)– 贪婪算法(Greedy algorithm)

    贪婪算法(Greedy algorithm) 1.基础 定义:贪婪算法分阶段地工作,在每一阶段,选择在当前最好的决策,不考虑将来的后果.所以一般只能得到局部最优而不是全局最优. 贪婪算法: Dijks ...

  4. 动态规划(Dynamic Programming)与贪心算法(Greedy Algorithm)

    文章目录 动态规划算法(Dynamic Programming) 动态规划问题的属性 应用实例:最长公共子序列问题(Longest Common Subsequence, LCS) 贪心算法(Gree ...

  5. 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal#39;s algorithm)

    克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...

  6. Arithmetic_Thinking -- greedy algorithm

    贪心算法--就是一种寻找局部最优解的情况,然后整合成整体最优解的情况 简单的例子:买菜的找钱,现在有1元,5角,1角的硬币,要找给别人2元7角,现在是怎么才能以最少的硬币量找给别人,肯定是先来两个1元 ...

  7. 贪心算法(Greedy Algorithm)之霍夫曼编码

    文章目录 1. 贪心算法 2. 应用 2.1 找零钱 2.2 区间覆盖 2.3 霍夫曼编码 霍夫曼编码完整代码 1. 贪心算法 我们希望在一定的限制条件下,获得一个最优解 每次都在当前的标准下做出当下 ...

  8. 实验12 Greedy Algorithm练习题 答案与解析

    1-1 只有当局部最优跟全局最优解一致的时候,贪心法才能给出正确的解.(1分) T 1-2 Let S be the set of activities in Activity Selection P ...

  9. 【控制】贪心算法(GA,Greedy Algorithm)及 Matlab 实现

    文章目录 算法思路 应用实例 仿真 Ref. 算法思路 贪心算法一般按如下步骤进行: 建立数学模型来描述问题. 把求解的问题分成若干个子问题. 对每个子问题求解,得到子问题的局部最优解. 把子问题的解 ...

最新文章

  1. java数组出现次数最多的数_找出数组中出现次数最多的那个数——主元素问题...
  2. java 两个数交换问题
  3. 自定义 Layer 属性的动画
  4. application context not configured for this file?
  5. abap--REUSE_ALV_GRID_DISPLAY事件子过程和cl_gui_grid类的事件对应关系
  6. 不确定mysql是否安装成功了怎么办
  7. Ubuntu14.04下Mongodb数据库可视化工具安装部署步骤(图文详解)(博主推荐)
  8. UI-UIButton、UILable、UITextField总结
  9. [html] 使用div+css进行布局有什么好处?
  10. 哈工大计算机学院成立,哈工大计算机科学与技术学院简介
  11. cef 前进后台 实现_CefSpider: 一个基于Webkit,Cef框架构建爬虫,项目代号:“车风”,具备浏览器所有特性,欢迎你给我一个Star,你的Star是该项目前进的动力!...
  12. css图片上漂浮着文字效果
  13. Redis数据结构——简单动态字符串-SDS
  14. python获取html文本框内容_Python3处理HTML获取所需内容
  15. 【sklearn第六讲】特征提取(下)
  16. jQuery源码06-jQuery = function(){};给JQ对象,添加一些方法和属性,extend : JQ的继承方法,jQuery.extend()...
  17. 2020年互联网大厂中秋礼盒PK!看看你的礼盒怎么样
  18. 【对话系统】Knowledge-Grounded Dialogue Generation with a Unified Knowledge Representation
  19. 如何下载历史版本和最新版本的iar
  20. 微信公众号开发python库_轻松实现python搭建微信公众平台

热门文章

  1. 房地产行业软件ApartmentSales开源版发布
  2. ARM7与Cortex-M的区别
  3. ARM7以及ARMv7的区别?
  4. 如何几行代码看到网恋对象的原型
  5. 二、预训练模型预测(Datawhale组队学习)
  6. PHP面向对象的程序设计封装--php高级最详细教程
  7. (原创)Oracle10g客户端下载/安装
  8. 你管这破玩意儿叫高可用
  9. Python计算机视觉编程——第7章 图像搜索
  10. 关键字过滤 java_java 关键字过滤