算法基础--贪心策略

image
本文主要作为自己的学习笔记,并不具备过多的指导意义。

概述

贪心算法通常用来求解最优问题

  1. 由局部最优解到整体最优解

    通过不断对局部最优进行操作,最终达到整体最优

  2. 无后效性

    后序操作,不会出现数据状态的回滚

  3. 和DP(动态规划)之间的联系

    很多贪心问题可以通过DP进行求解


最优装载问题

  1. 给出N个物体,第一个物体重量为Mi
  2. 尽量选择最多的物品,总重不超过C

先将物品按照质量排序,然后依次放入每个物品,直到总重量将超过C位置。

这里依次将剩余物品中质量最小的物品放入的过程,就是贪心的过程。


合并果子

一类总过程代价,取决于子过程代价的问题

  1. 有N堆果子,没堆果子的数量为Ai,每次可以将两堆果子合并,每次合并将消耗两堆果子总数的体力。
  2. 求最小消耗的体力
  3. 1<N<10000

首先,如果我们什么都不管直接两两合并:总计消耗48点体力

image

然后,我们尝试排序后两两合并:总计消耗44点体力

image

最后,我们尝试只将当前所有数据中最小的两个进行合并:总计消耗38点体力

image

解法

构建一个小根堆,每次从堆顶推出两个元素合并。并且将合并都的元素追加进小根堆中即可。

具体证明的过程有一定难度,可以参考哈夫曼编码证明的过程。

以上的操作过程,也就是贪心的过程。他只保证单次合并所消耗的体力最优,而不在意其他的数据该如何合并。

堆结构往往用来解决贪心的问题。因为贪心问题往往需要一个明确的指标,最大值或者最小值。


项目利润

输入:

cost[]:每个项目的花费

profits[]:每个项目的利润(纯利润)

k:最多能做k个项目

w:表示初始资金

输出:

最后可以获得的最大钱数

说明:一次只能做一个项目,且做完一个之后马上就能获得收益,可以支持做下一个项目

  1. costprofits中的元素依次合并成一个新的节点node:
public class Node {
    public var c :Int //项目花费
    public var p :Int //项目利润
    
    public init(cost:Int,profit:Int) {
        self.c = cost
        self.p = profit
    }
}
  1. 准备一个以项目花费构建的小根堆

将所有node依次放入

  1. 准备一个以项目利润构建的大根堆

贪心过程:

  1. 从小根堆中依次弹出堆顶元素,直到node.c>w(项目所需资金大于当前资金)

    具体代码上,将小根堆数组removeFirst,然后将arr[0]与arr[arr.count-1]位置交换。让小根堆对arr[0]位置元素向下调整即可。

  2. 将小根堆中弹出的元素放入大根堆中(大根堆中即为当前可执行的项目)

    具体代码上,将元素追加进大根堆数组末尾,并进行调整即可。

  3. 从大根堆中弹出堆顶元素,并将w += node.p(执行收益最大的项目,并且更新当前资金)

    具体代码上与第一步类似

该贪心过程总计执行k次,每一次执行都只需要关心小根堆中最小值,与大根堆中最大值即可。最后的w即为最大总资产。


会议安排

在优先的时间内安排数量最多的会议

做一张图可以直观表示过程:

我们将蓝色表示为待安排红色表示为已安排黑色表示为不可安排

我们可以尝试几种不同的贪心策略

  1. 每次选择持续时间最短的安排
image

显然不可行

  1. 每次选择开始时间最早的
image

显然也不可行

  1. 每次选择开始时间最早的并且持续时间最短的来安排
image
image

由此可见该方案是可以行的

代码也很简单,只需要关心当前有效数据内开始时间晚于当前会议结束时间结束时间最早的一个数据即可。

func bestArrange(programs:[Program]) -> Int {
    program.sort("end")//根据program.end进行排序
    
    var res = 0
    var current = 0
    
    for p in programs {
        if p.current > current {  //开始时间晚于当前时间,否则作废
            res += 1
            current = p.end //开会,当前时间变成会议结束时间
        }
    }
    return res
}

贪心策略的证明

贪心策略的数学证明通常很复杂,有能力可以去翻阅

这里推荐一种很方便的方式,对数器。

通过小样本大样本量的测试,证明贪心策略的正确性。

以排序算法的证明举例

var checkOK = true
for i in 0..<10000 {
    var arr1 = generateRandomArray(size: 5, value: 20) //获取一个长度为10,最大值为20的随机数数组
    var arr2 = arr1 //数组在swift里属于值类型,赋值动作会自动copy
    let originalArr = arr1
    arr1.sort()//一定正确的算法
    radixSort(arr: &arr2, maxDigit: 2)
    if arr1 != arr2 {
        checkOK = false
        print(originalArr)
        print(arr2)
        break
    }
}

print(checkOK ? "比对成功":"比对失败")

对于贪心问题,可能不一定存在一个一定正确的算法。那么我们完全可以不去比对结果是否一致,只要贪心策略的结果永远优于默认顺序得出的结果即可。

关于对数器的介绍可以参阅另一篇


贪心算法

贪心算法3: 会议安排

左神牛课网算法课

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,473评论 1 45
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,769评论 0 13
  • Java继承关系初始化顺序 父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父...
    第六象限阅读 2,152评论 0 9
  • 第六章(一)“喜欢看书吗?光是坐在这里发呆,不如找点什么丰富一下你的大脑。” 从FLLFFL进入花园修剪花花草草到...
    汀雨S26阅读 563评论 0 2
  • 早啊 早什么早,天还没亮 哦,可我已经开始想你了 ——空言
    一写空言阅读 284评论 2 3