算法分析与设计——第五章复习:贪心算法

贪心算法:


一、贪心算法的思想:

是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

二、贪心算法的应用:一般背包问题

问题描述:

已知:

  • 有 n 种物品、有一个承重量 M M M 的背包
  • n 种物品的重量分别为 ( w 1 , w 2 , … , w n ) (w_1, w_2, …, w_n) (w1,w2,,wn)
  • n 种物品放入背包所获得的效益分别是 ( p 1 , p 2 , … , p n ) ( p i > 0 ) (p_1, p_2, …, p_n)\quad (p_i>0) (p1,p2,,pn)(pi>0)
    若将物品i的一部分 x i x_i xi ( 0 ≦ x i ≦ 1 0\leqq x_i\leqq1 0xi1)放入背包,则获得效益 p i x i p_ix_i pixi

问题:
在背包可承重范围内,采用怎样的装包方法会使装入背包物品的总效益为最大?

问题分析:
求出一个( x 1 , x 2 , … , x n x_1, x_2, …, x_n x1,x2,,xn),要求在满足 ∑ i = 1 n w i x i ≦ M \sum_{i=1}^nw_ix_i\leqq M i=1nwixiM条件下,
使得总效益 ∑ i = 1 n p i x i \sum_{i=1}^np_ix_i i=1npixi 最大
满足约束条件的( x 1 , x 2 , … , x n x_1, x_2, …, x_n x1,x2,,xn),称为“可行解”。
使得总效益最大的可行解,称为“最优解”。

一般背包问题中度量标准的选择:

效益值 p i p_i pi重量 w i w_i wi等都可以作为度量标准。
我们采用效益值和重量之比做为量度标准

一般背包问题的实例:

有3个物品, 即 n = 3 n=3 n=3
背包能承载的最大重量为20, 即 M = 20 M=20 M=20
物品的价值和重量: ( p 1 , p 2 , p 3 ) = ( 25 , 24 , 15 ) , ( w 1 , w 2 , w 3 ) = ( 18 , 15 , 10 ) (p_1, p_2, p_3)=(25, 24, 15), \\ (w_1, w_2, w_3)=(18, 15, 10) (p1,p2,p3)=(25,24,15),(w1,w2,w3)=(18,15,10)

  • 步骤1. 将物品按单位重量效益的非增次序排序(递减), ( p 2 w 2 , p 3 w 3 , p 1 w 1 ) = ( 24 15 , 15 10 , 25 18 ) (\frac{p_2}{w_2},\frac{p_3}{w_3}, \frac{p_1}{w_1}) =(\frac{24}{15}, \frac{15}{10}, \frac{25}{18}) (w2p2,w3p3,w1p1)=(1524,1015,1825)
  • 步骤2. 按该次序逐一放物品
    首先放入物品2, x 2 = 1 x_2=1 x2=1
    然后放入物品3,因剩余容量为 20 − w 2 = 5 20-w_2=5 20w2=5,故只能放入物品3的 5 10 \frac{5}{10} 105,即 1 2 \frac{1}{2} 21
    总效益值为 ∑ i = 1 n p i x i = 24 + 15 × 1 2 = 31.5 \sum_{i=1}^np_ix_i = 24+15\times\frac{1}{2}=31.5 i=1npixi=24+15×21=31.5

一般背包问题的贪心算法:

在这里插入图片描述

首先给出定理:在物品排序后,通过Greedy-Knapsack算法得到的贪心解X是背包问题的一个最优解。

证明一般背包的贪心算法中贪心解是最优解:

证明的基本思想:

  • 把贪心解X与任一最优解Y相比较,如果这两个解不同,就去找第一个不同 x i x_i xi
  • 在最优解Y中,设法用贪心解的 x i x_i xi替换最优解的 y i y_i yi ,并证明最优解在分量代换前后的总效益值无任何变化
  • 反复进行这种代换, 直到新产生的最优解与贪心解完全一样, 从而证明了贪心解就是最优解。

证明:

在这里插入图片描述
在这里插入图片描述
附—— y k < x k y_k<x_k yk<xk 的证明:
在这里插入图片描述
我们继续证明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

贪心方法的核心:

选择能产生问题最优解最优量度标准是使用贪婪算法的核心。

三、贪心算法的应用:带有限期的作业排序问题

问题描述:

假定只能在一台机器上处理 n n n个作业:

  • 每个作业均可在单位时间内完成;
  • 每个作业i都有一个截止期限 d i > 0 d_i>0 di>0(di是整数), 当且仅当作业 i i i 在它的期限截止之前被完成时,方可获得 p i > 0 p_i>0 pi>0 的效益。

问题的可行解:

  • 可行解是这 n n n 个作业的一个子集合 J J J J J J 中的每个作业都能在各自的截止期限之前完成
  • 可行解的效益值是 J J J 中这些作业的效益之和 ∑ p j ∑p_j pj

问题的最优解:
具有最大效益值的可行解就是最优解

作业排序问题的标准度量的选择:

选择目标函数 ∑ p j ∑p_j pj 作为量度标准,则下一个要计入的作业将是使 ∑ p j ∑p_j pj 得到最大增加的作业,只需将各作业按效益 p j p_j pj降序来排列,即: p 1 ≦ p 2 ≦ … ≦ p n p_1\leqq p_2 \leqq…\leqq p_n p1p2pn

作业排序问题的贪心算法:

在这里插入图片描述

给出定理:

对于作业排序问题,算法 GREEDY_JOB 所描述的贪心方法总是得到一个最优解

证明GREEDY——JOB算法中贪心解是最优解:

》

考虑最优解不等于贪心解的情况
在这里插入图片描述

  • 情况一:
    若 𝐼⊂𝐽,则 𝐼 的效益 < 𝐽 的效益,这与 I I I 是最优解矛盾,故 𝐼⊂𝐽 不可能。
  • 情况二:
    在这里插入图片描述
  • 情况三:
    先考虑 I I I J J J交集中的作业。
    在这里插入图片描述
    再考虑 J ∩ I J∩I JI以外的作业.
    在这里插入图片描述
    在这里插入图片描述

如何判断一个子集合是否是一个可行解?

定理:

J J J k k k 个作业的集合, δ = i 1 , i 2 , … , i k \delta=i_1, i_2,…,i_k δ=i1,i2,,ik J J J 中作业的一种排列, 它使得 d i 1 ≦ d i 2 ≦ … ≦ d i k d_{i_1}\leqq d_{i_2}\leqq …\leqq d_{i_k} di1di2dik。则:
J J J 是一个可行解 当且仅当 J J J 中的作业可以按照 δ \delta δ 的次序排列是一个可行调度表

定理证明:

在这里插入图片描述
在这里插入图片描述
证明完毕。

如何判断(保证) J ∪ { i } J∪ \left\{ i \right\} J{i}是否为可行解?

方法一:向 J J J 中插入 i i i

在这里插入图片描述

  • while循环中红字 D ( J ( r ) ) ≠ r D(J(r))\ne r D(J(r))=r 为了保证 J J J 中向后移动一位的作业不会超时
方法二:对作业 i i i 分配时间时, 尽可能推迟对作业 i i i 的处理。 (在其截止期前最靠后的空时间片)

为了更好的理解这一方法,我们给出方法二的实例:

在这里插入图片描述

并查集的引用:

  • 加权规则:并查集合并时,集合中元素数少的合并到元素数多的集合中。
  • 合并操作 U N I O N UNION UNION( i i i j j j):使用加权规则,合并根为 i i i 和根为 j j j 的两个集合
  • 查找算法 F I N D ( i ) FIND( i ) FIND(i):查找并返回含有元素 i i i 的树根 j j j,并使用压缩规则压缩 i i i 到根 j j j 的所有节点,使其父节点均为 j j j

利用并查集实现方法二:

时间片区间为 [ 0 , b ] [0,b] [0,b]
在这里插入图片描述
并查集的操作是红字和粉框中的语句。其中粉框中有对并查集的更新操作,这是重点,将在实例中进一步展现出来。

方法二的实例:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最优解 J = { 1 , 2 , 3 , 4 , 6 } J= \left\{1,2,3,4,6\right\} J{1,2,3,4,6},处理次序 4,2,3,1,6,效益值120

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Desperado1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值