内容概要
一、贪婪算法概念
二、分数背包、01背包问题
三、活动安排问题
四、数字拼接问题
五、找零问题
1、贪婪算法概念
贪婪算法是指,在对问题求解最优解时,总是做出当前开来最好的选择。也就是说不从整体最优上加以考虑,它做出的是在某种意义上的局部最优解。
贪婪算法并不保证会得到最优解,但是在部分中,由贪婪算法得到的结果就是最优解。要判断一个问题是否能够使用贪婪算法解决
2、分数背包、01背包问题
分数背包
假设有一个小偷到商店偷东西,在他面前有价值600,共重1kg的商品A、价值1200,共重3kg的商品B、价值1000,共2kg的商品C,三种商品都能够被拆分携带。小偷只能拿走重5kg的物品。
问:小偷要怎么拿才能带走价值最多的商品?
# 每次都拿走单位价值最高的商品
goods = [(600, 1), (1200, 3), (1000, 2)]
goods.sort(key=lambda x: x[0] / x[1], reverse=True)
print(goods)
def max_value(g, w):
"""
:param g: good list
:param w: max_w
:return: tuple of change_method, total_value, remain_weight
"""
m = [0 for _ in range(len(g))]
total_v = 0
for i, (prize, weight) in enumerate(g):
if w >= weight:
total_v += prize
m[i] = weight
w -= weight
else:
total_v += prize * w / weight
m[i] = w
w = 0
break
return m, total_v, w
print(max_value(goods, 5))
01背包问题
如果选择的商品不能分割,只能选择全部带走或者不选择
这种情况下不适合使用贪婪算法求解最优解
3、活动安排问题
假如有一个场地,同时只能开始一场活动,现在有若干个活动,它们分别从s时间开始,f时间结束(活动执行时间为[s,f)),现在求怎样安排活动能够使得一天内举办的活动次数最多
i 1 2 3 4 5 6 7 8 9 10
s 1 3 5 0 6 9 2 3 5 8
f 4 5 7 2 8 10 4 5 6 10
activities = [(1, 4), (3, 5), (5, 7), (0, 2), (6, 8), (9, 10), (2, 4), (3, 5), (5, 6), (8, 10)]
activities.sort(key=lambda x: x[1])
print(activities)
# 贪婪地求活动结束时间最早的活动
def activity_max(a):
m = [a[0]]
a_num = 1
for i in range(1, len(a)):
if a[i][0] >= m[-1][1]:
m.append(a[i])
a_num += 1
return m, a_num
print(activity_max(activities))
4、数字拼接问题
假如有多个字符串数字123,423,88,92,23,现在要将他们拼接成最大的数928842323123,问如何完成
特别注意当存在128和1286,或是存在728或7286时
如果只是单纯的比较大小,1286比128大,7286比728大,正常拼接后为1286128和7286728,前者是最大的拼接法,后者不是,最大的拼接数为7287286
所以不使用a+b if a > b else b+a
而是使用a+b if a+b > b+a else b+a
num_li = ['128', '1286', '88', '92', '29', '55'] # 想象成一个简单的冒泡排序
def number_join(a):
length = len(a)
for i in range(1, length):
for j in range(length - i):
if a[j] + a[j+1] < a[j+1] + a[j]:
tmp = a[j]
a[j] = a[j+1]
a[j+1] = tmp
result_num = ''
for i in a:
result_num += i
return result_num
print(number_join(num_li))
5、找零问题
moneys = [100, 50, 20, 10, 5, 1]
moneys.sort(reverse=True)
def change(m_l, m):
result = [0 for _ in range(len(m_l))]
for i, v in enumerate(m_l):
if not m:
break
result[i] = m // v
m %= v
return result, m
print(change(moneys, 277))
***待补充***