相关文章推荐
爱旅游的遥控器  ·  System.Runtime.Interop ...·  4 月前    · 
玩篮球的黄豆  ·  python xlwings库出现“ ...·  12 月前    · 
老实的葫芦  ·  js嵌套循环用同一个变量-掘金·  1 年前    · 
酒量大的西红柿  ·  微软新成立 AI4Science ...·  1 年前    · 
卖萌的佛珠  ·  Lua中实现sleep函数功能的4种方法_o ...·  1 年前    · 
Code  ›  算法学习笔记(二):贪心算法开发者社区
背包问题 背包问题动态规划 贪心算法
https://cloud.tencent.com/developer/article/1156592
腼腆的西瓜
1 年前
作者头像
free赖权华
0 篇文章

算法学习笔记(二):贪心算法

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > 赖权华的笔记 > 算法学习笔记(二):贪心算法

算法学习笔记(二):贪心算法

作者头像
free赖权华
发布 于 2018-07-04 15:34:22
907 0
发布 于 2018-07-04 15:34:22
举报

(一)    贪心法

贪心法在解决问题的策略上是根据当前已有的信息做出选择,不管将来有什么结果,这个选择都不会改变。换言之,贪心法并不是从整体最优考虑,它所做出的选择只是某种意义上的局部最优。

用贪心法求解的问题一般具有2个重要的性质:

(1)   最优子结构:当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构。问题的最优子结构是该问题能采用贪心法求解的关键性质。

(2)   贪心选择性质:指问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来得到。这也是贪心法和动态规划法的主要区别。

(二)    示例1

设有0,1,…,n-1个物品,体积分别为v0,v1,…,vn-1 ,将这些物品装入容量都为v的若干个箱子中,不同的装箱方案所需要的箱子数目可能不同,装箱问题要求使装尽这n种物品的箱子数最少。

约定:

(1)   物品体积不超过箱子容量。

(2)   现有的箱子足以装入所有物品

(3)   物品不能拆分

算法描述:

输入物品列表信息

输入箱子列表信息

将物品列表按体积降序排序(从大到小)

while 还有物品未装入箱子:

if 物品体积 <= 箱子容量:

将物品装入箱子

更新箱子容量

物品列表中移除已经装入箱子的物品

else:(如果当前箱子不足以装入物品)

获取下一个箱子的索引

 1 import random
 2 import operator
 3 #物品类
 4 class goods():
 5     def __init__(self,goods_name,goods_v):
 6         self.goods_name = goods_name #物品名称
 7         self.goods_v = goods_v   #物品体积
 8 #箱子类
 9 class box():
10     def __init__(self,box_name):
11         self.box_name = box_name #箱子名称
12         self.box_v = 50  #箱子容量
14 #贪心算法实现,goods_list:物品列表  box_list:箱子列表
15 def greedy(goods_list,box_list):
16     cmpfun = operator.attrgetter('goods_v')
17     goods_list.sort(key=cmpfun, reverse=True)  # 将物品列表按体积降序排序
18     i = 0 #物品列表索引(下标)
19     j = 0 #箱子列表索引(下标)
20     box_count = 0 #初始化箱子使用数量
21     while goods_list:
22         if goods_list[i].goods_v <= box_list[j].box_v:
23             print('将物品:'+str(goods_list[i].goods_name)+"    装入箱子:", box_list[j].box_name)
24             #更新箱子容量
25             box_list[j].box_v = box_list[j].box_v - goods_list[i].goods_v
26             j = 0
27             del goods_list[i] #从物品列表中移除已经装入箱子的物品
28         else:
29             j += 1
30             if box_count < j :
31                 box_count = j
32      # 因为索引从0开始的,所以这里+1后得到箱子使用数量
33     print('最终使用箱子数:',box_count+1)
34     return box_list
36 goods_list = []
37 #初始化10个物品
38 for i in range(10):
39     goods_name = "物品%s"%i
40     goods_v = random.randint(1,50)
41     goods_list.append(goods(goods_name,goods_v))
43 box_list = []
44 #初始化10个箱子
45 for i in range(10):
46     box_name = "箱子%s"%i
47     box_list.append(box(box_name))
49 box = greedy(goods_list,box_list)
50 print("箱子使用情况:")
51 for i in box:
52     print(i.box_name + '  剩余容量:' + str(i.box_v))

(三)    示例2(0-1背包问题)

现在商店有0,1,…,n件商品,体积分别为V0,V1,…,Vn ,价值分别为P0,P1,…,Pn ,假设背包容量为V,现在要求使背包装入商品的价值最大化。

约定:

(1)   背包不足以装入所有物品。

(2)   每个商品,要么完整装入,要么放弃该商品,不能只装入商品的一部分。

算法描述:

输入商品列表信息

输入背包容量

将商品列表按单位价值降序排序(就是性价比,例如:每斤值多少钱)

while 还有商品未装入背包(或者未排除):

if  商品体积小等于背包剩余容量:

将商品装入背包

更新背包剩余容量

在商品列表中移除已经装入背包的商品

else:(如果背包剩余容量不足以装入商品)

在商品列表中移除不能装入背包的商品

 1 import random
 2 import operator
 3 #商品类
 4 class goods():
 5     def __init__(self,goods_name,goods_v,goods_p):
 6         self.goods_name = goods_name #商品名称
 7         self.goods_v = goods_v   #商品体积
 8         self.goods_p = goods_p   #商品总价值
 9         self.value = self.goods_p/self.goods_v #商品单位价值
11 #贪心算法实现,goods_list:商品列表 V:背包剩余容量 result_list:存放最终装入背包的商品
12 def greedy(goods_list,V,result_list):
13     cmpfun = operator.attrgetter('value')
14     goods_list.sort(key=cmpfun,reverse=True) #将商品列表按单位价值降序排序
15     #打印排序后的所有商品信息,这里为方便看效果,实际可以去掉这个
16     for goods in goods_list:
17         print(goods.goods_name +"  体积:"+str(goods.goods_v)+"  价值:" + str(goods.goods_p) + "  单位价值:" +str(goods.value))
18     while goods_list and V > 0:
19         i = 0
20         #如果商品体积小等于背包容量
21         if goods_list[i].goods_v <= V:
22             #将商品放入背包
23             result_list.append(goods_list[i])
24             #更新背包剩余容量
25             V = V - goods_list[i].goods_v
26             #在列表中删除该商品
27             del goods_list[i]
28         else:
29             del goods_list[i]
30     print('背包剩余空间',V)
31     return result_list
34 V = 100 #初始化背包容量
35 goods_list = []
36 #初始化1000个商品
37 for i in range(1000):
38     goods_name = "商品%s"%i
39     goods_v = random.randint(1,100)
40     goods_p = random.randint(1,100)
 
推荐文章
爱旅游的遥控器  ·  System.Runtime.InteropServices.COMException (0x8004E00F): COM+ 无法与 Microsoft 分布式事务协调程序交谈 (异常来自 HRESU
4 月前
玩篮球的黄豆  ·  python xlwings库出现“ 服务器出现意外情况” - 知乎
12 月前
老实的葫芦  ·  js嵌套循环用同一个变量-掘金
1 年前
酒量大的西红柿  ·  微软新成立 AI4Science 团队,机器学习大牛 Christopher Bishop 担任主任,刘铁岩任北京负责人 - 知乎
1 年前
卖萌的佛珠  ·  Lua中实现sleep函数功能的4种方法_os.sleep lua_活在阳光下的博客-CSDN博客
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号