贪心算法-背包、有期限作业排序、单源最短路径、二元归并

贪心算法的实验—学习过程


注:这是本人写的第四次实验,由于很懒,只是把报告内容搬运了过来,如有不足,请理解。没有认真设置文章格式,而且也没为文章做专门的修改请理解。

前言

实验前言:本次实验学习贪心策略,为此其实我们可以学到很多,大部分文档都在着重讲解贪心为什么正确,它是如何做的。但是还要知道:“完美是优秀的敌人”有时候只需要找到一个能大致解决问题的方法,贪心策略很多时候显然不能够获得最优解,但是可以获得一个非常接近最优解的解。尤其在考虑复杂的NP完全问题时,近似也是不错的方法。(学习感悟:步步完美,虽然可能不是最优解,但是也近似最优解。有时候不追求完美退而求其次反而能得到完美的结果。人生就像连绵不断的曲线,起起落落是人生常态……这说的不就是贪心算法!)

数学:在学习本次实验的过程中,我联想到了很多数学知识,从数学的证明到数学中的多元函数极值问题再到离散数学中的集合知识,我认为这部分的学习是很需要逻辑的,如果用数学的严谨、数学的方法、来考虑可能会很简单。

顺序:本次实验从背包问题入手,由简单到复杂,逐渐深入。在数据结构方面,我考虑了向量结构、struct结构、优先队列结构(priority_queue)。


一、(部分)(分数)背包问题(调制饮品问题)

问题:本问题的描述完全相似于01背包,增加的条件是可以装一部分物品进入背包。贪心策略的思想符合人的本性,且易于理解。找零钱、拿物品等等人自然想到的就是贪心策略,在该问题中很自然的考虑性价比,先选性价比高的物品,依次装入直到装满。但是为什么这个贪心策略可以在该问题中得到最优解,如何证明是关键的一步,一般使用替换法证明,当然还可以联想很多其它数学证明法,如反证法、归纳法等等。

证明:假设另外存在最优解s*,贪心解为s’,并且按照性价比排好顺序。一开始假设放入一样多的性价比最高的物品。然后往上依次看,直到某一性价比的物品,贪心解装满了,最优解没装满,那么我们可以把最优解中没装满的物品的下一个低性价比的物品换成这个高性价比的物品,这样的交换肯定不亏。这样以此类推,最优解的价钱不会减少,而且换完之后最优解会变成贪心解。(为此我画了一张图,帮助理解)

在这里插入图片描述

做为引入的问题,比较简单,故深入的理解在后面的问题讨论,下面是背包问题的代码:(完全自主编写,貌似写的有点复杂)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码的运行结果:测试了一些01背包中的数据,可以验证是正确的。

在这里插入图片描述

二、 用贪心法实现带有期限作业排序的快速算法

我打算通过这一部分的实验,探索如何掌握并自己设计贪心算法,而不是只是弄懂个别案例。首先我通过很多资料,学习设计贪心算法的过程。

对于该问题,一个好的入手点是首先考虑动态规划,然后设计一个递归,证明我们可以通过一个贪心选择使只剩下一个子问题,再证明贪心选择的安全性,最后设计一个递归的贪心策略,再把贪心策略转换为递归策略(《算法导论》)。我阅读了很多的资料,直到看到这个繁琐的过程,我认为这是一个好的入手点,可以帮助我独自想出该问题的贪心算法的解。我们应该知道,在每个贪心算法之下,几乎总有一个更繁琐的动态规划算法。

在开始之前,还要注意贪心选择性质,该性质代表我们在当前问题不用考虑子问题的解(不依赖于任何将来的选择),而动态规划则通常依赖于子问题的解。如果我们在贪心中考虑了众多选择,则说明我们的算法还可以改进。最优子结构性质在贪心中真正要做的工作就是论证:将子问题与贪心选择组合在一起就能生成原问题的最优解。

开始(前面其实都是废话):动态规划,表格,行表示考虑的作业范围,列表示期限(找到期限最久的作业,作为列数)。每次考虑完成该作业与不完成该作业两个情况的收益,选择最大的收益填入表格,如果不选该作业,则就是上一行的值,如果选该作业,则为上一行在该作业截至日期-1列处的值。当然每次也必须考虑有没有入场券,即能不能选择该作业。可以思考“带权重的活动选择问题”。

贪心选择:结合递归考虑,我发现本问题的贪心选择为作业的收益(当然可能有其它的贪心选择,比如按照最短期限等等,但是可以举反例证明一些贪心选择并不适用)。简单证明,有个贪心解,和一个最优解,对于第一个作业,如果没有把计算机的资源分给收益最高的作业,那么我就可以把分给的资源换成贪心的分配,这样总收益不会降低。然后使用数学归纳法,每次贪心求完之后,递归的求剩下的相容的部分。总的来说,思路还是一样的。
该问题的约束:所有作业均应该在期限之前完成。该问题的目标:使收益之和最大。

伪代码:

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

“54”->闫子;

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

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

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

打赏作者

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

抵扣说明:

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

余额充值