贪心策略取得最优解的条件_python程序员必备技能之贪心算法初解

本文介绍了贪心算法的基本思想和应用,通过解决会议安排和背包问题两个实例,展示了如何利用贪心策略寻找局部最优解进而构建全局最优解。在会议安排问题中,选择最早结束的会议以最大化参与数量;在背包问题中,选择性价比最高的物品以最大化价值。贪心算法在无法找到快速解的问题中提供了解决方案,但其局限性在于仅关注当前最优,不考虑全局最优。
摘要由CSDN通过智能技术生成
ffc49b0fd2993952d87206ffe9f8cc9e.png

1、贪心算法介绍

贪心算法,又称贪婪法,是寻找最优解算法的常用算法。当面对没有快速算法的问题(NP完全问题)时,贪心算法则可以化解危机,这种方法的模式一般是将问题求解分割成若干步骤,每个步骤都去应用贪心原则,即选取当前状态下最优的选择,每一步都是当前最佳选择,并逐步堆出问题的最优解。贪心算法的每次决策都是以当前状态为基础并依照局部最有利的原则进行选择,不从整体上考虑其他各种可能的情况。生活中我们常听到“人要活在当下”、“看清眼前”,其实这跟贪心算法就是同一个道理,贪心算法在解决问题的策略上目光短浅,只看眼前,不去计较长远与整体。

2、贪心算法的基本思想

(1)贪心策略

首先要确定贪心策略,选择一个方案,定义问题最优解的模型。比如去菜市场买苹果,个大的肯定好吃些,所以每次都从苹果堆里挑选一个最大的作为局部最优解,这时贪心算法的策略就是每次选择当前最大的苹果。有人觉得最红的苹果最好吃,那他的贪心策略就是每次都挑选最红的苹果。

(2)局部最优解

将问题分解为一系列子问题,一步一步的得到局部问题最优解。例如在上述假设中,第一次从苹果堆里选择一个最大的,第二次再从剩下的苹果堆里选一个最大的,以此类推。

(3)全局最优解

根据贪心策略,用所有子问题的局部最优解堆叠出全局最优解。

3、解决会议安排问题

(1)问题描述

假如你是一家公司的老总,公司每天都有很多会议要举行,每个会议都有起始时间和结束时间,每个会议进行的时间也不一样,同一时间不会有两个会议同时举行。而你作为一位敬业的老板,你需要争取在有限的时间内参与更多的会议。下图为会议安排表:

3ce1699c03b8e55e575d1a85a930b873.png

(2)问题分析

从问题描述中可以看出,需要考虑几个点,一是会议的起始时间和结束时间,二是每个会议所占时间,三是要在参与更多的会议,即寻找最优解。这个问题我们可以采用贪心算法来解决。我们应该每次从剩下的会议中选择最早结束的会议,这样可以尽快去参与下一场会议,这样最终就能挑选出能在有限时间内参与更多会议的最优方案。

(3)编码实现

算法只是对问题求解方法的描述,它不依赖于任何语言,这里使用python来实现:

#会议类class meet: num=0 begin=0 end=0#所有会议meets=[]#初始化会议列表m=meet()m.num=1m.begin=8m.end=10meets.append(m)m=meet()m.num=2m.begin=9m.end=11meets.append(m)m=meet()m.num=3m.begin=10m.end=15meets.append(m)m=meet()m.num=4m.begin=11m.end=14meets.append(m)m=meet()m.num=5m.begin=13m.end=16meets.append(m)m=meet()m.num=6m.begin=14m.end=17meets.append(m)m=meet()m.num=7m.begin=15m.end=17meets.append(m)m=meet()m.num=8m.begin=17m.end=18meets.append(m)m=meet()m.num=9m.begin=18m.end=20meets.append(m)m=meet()m.num=10m.begin=16m.end=19meets.append(m)import operatorselectmeets=[] #选择参与的会议def selectmeet(meetlist): cmpfun = operator.attrgetter('end') #按照end进行排序 meetlist.sort(key = cmpfun) selectmeets.append(meetlist[0]) #先选第一个会议 endtime=meetlist[0].end #会议结束时间 for i in range(1,len(meetlist)): if endtime<=meetlist[i].begin: #如果结束时间小于该会议的起始时间 selectmeets.append(meetlist[i]) endtime=meetlist[i].end selectmeet(meets) for obj in selectmeets: print(obj.num) '''打印结果为: 14689'''

4、解决背包问题

(1)问题描述

假如你是一个小偷,趁天黑去打劫了一家超市,超市里有很多值钱的玩意,但你背的包只能承重12kg,你需要选择一套方案来保证偷出去的东西最值钱。

85aa3f4161c34b67b54dfaf7dc02ce4d.png

(2)问题分析

根据问题描述可以知道这是一个完全可以用贪心算法来解决的问题,每次往背包里塞性价比最高的东西(同等重量下价值更高),直到背包再也塞不下其他东西,这样最终就能实现偷到的东西利益最大。

(3)编码实现

同样,这里也使用python来实现:

#商品类class good: name="" #商品名 weight=0 #重量 price=0 #价格 p=0 #性价比goods=[]g=good()g.name="手表"g.weight=2g.price=85g.p=g.price/g.weightgoods.append(g)g=good()g.name="剃须刀"g.weight=3g.price=60g.p=g.price/g.weightgoods.append(g)g=good()g.name="西瓜"g.weight=5g.price=10g.p=g.price/g.weightgoods.append(g)g=good()g.name="篮球"g.weight=1.5g.price=30g.p=g.price/g.weightgoods.append(g)g=good()g.name="可乐"g.weight=1g.price=3.5g.p=g.price/g.weightgoods.append(g)g=good()g.name="香烟"g.weight=2.5g.price=75g.p=g.price/g.weightgoods.append(g)g=good()g.name="茅台"g.weight=1.2g.price=240g.p=g.price/g.weightgoods.append(g)g=good()g.name="烤鸡"g.weight=2.2g.price=22g.p=g.price/g.weightgoods.append(g)g=good()g.name="相机"g.weight=2g.price=2000g.p=g.price/g.weightgoods.append(g)g=good()g.name="袜子"g.weight=1g.price=12g.p=g.price/g.weightgoods.append(g)import operatorselectgoods=[] #挑选的商品def selectgood(goodlist): cmpfun=operator.attrgetter('p') #按性价比排序 goodlist.sort(key=cmpfun,reverse=True) residueweight=12 #背包剩余承重空间 for obj in goodlist: if residueweight>=obj.weight: #如果总重小于背包承重 selectgoods.append(obj) residueweight=residueweight-obj.weight selectgood(goods)for obj in selectgoods: print(obj.name)'''打印结果为:相机茅台手表香烟剃须刀袜子'''

如有错误,欢迎指正!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值