贪心法的基本思想
贪心算法是利用问题的贪心性质,简化了分解原始问题的过程,每次只关注在当前状态下可以获得的局部最优解,通过凭借各阶段的局部最优解获得最终问题的解。
贪心法解决问题的条件
- 问题是否适用于贪心法求解,即索取求解问题是否具有贪心选择性质。
贪心选择性质是指应用同一规则,将原问题变为一个相似的但规模更小的子问题,而后的每一步都是当前看似最佳的选择。 - 问题是否具有局部最优解,从而通过一个贪心标准,可以得到问题的最优解。
应用贪心法的基本思路
- 建立对问题精确描述的数学模型,包括定义最优解的模型
- 将问题纷纷昵称一系列子问题,同时定义子问题的最优解结构
- 应用贪心算法原则可以却动每个子问题的局部最优解,并根据最优解模型,用字问题的局部最优解堆砌出全局的解
贪心法实例
1. 硬币找零问题
[问题描述] 假设市面上有6种不同面值的硬币,各硬币的面值分别为5分、1角、2角、5角、1元、2元,要找零10.5元,求出最少硬币的数量。
'''
贪心法--硬币找零问题
假设市面上有6种不同面值的硬币,各硬币的面值分别
为5分、1角、2角、5角、1元、2元,要找零10.5元,求出最少硬币的数量
本题选择的贪心策略为:总是选择当前面值最大的硬币
'''
import collections
def getChange(coins, amount):
# 存放结果
res = collections.OrderedDict()
# 将硬币面值按从大到小排列
coins.sort()
coins.reverse()
for each in coins:
if amount >= each:
n = int(amount // each)
res[each] = n
amount -= n * each
return res
# print(coins)
coins = [0.05, 0.1, 0.2, 0.5, 1, 2]
amount = 10.5
res = getChange(coins, amount)
print('共需',end='')
for key, value in res.items():
print(f'{value}枚{key}元硬币',end=' ')
[结果] 共需5枚2元硬币 1枚0.5元硬币
2. 活动安排问题
[问题描述] 学校有开学典礼、课外讲座、话剧演出、音乐会、芭蕾舞演出和教职工会议等一系列活动
需要在礼堂矩形,具体活动信息如下,怎么安排才能是尽可能多的活动得以开展?
活动 | 开学典礼 | 课外讲座 | 话剧演出 | 音乐会 | 芭蕾舞演出 | 教职工会议 |
---|---|---|---|---|---|---|
开始时间(s) | 1 | 3 | 0 | 5 | 3 | 7 |
结束时间(f) | 3 | 4 | 4 | 7 | 6 | 8 |
'''
贪心法-活动安排问题
学校有开学典礼、课外讲座、话剧演出、音乐会、芭蕾舞演出和教职工会议等一系列活动
需要在礼堂矩形,具体活动信息如下,怎么安排才能是尽可能多的活动得以开展?
*****************************************************************
活动 *开学典礼*课外讲座*话剧演出*音乐会*芭蕾舞演出*教职工会议
*****************************************************************
开始时间 s* 1 * 3 * 0 * 5 * 3 * 7
*****************************************************************
结束时间 f* 3 * 4 * 4 * 7 * 6 * 8
本体采用的贪心策略为:总是选择最早结束的活动
'''
# 对结束时间进行排序,同时得到对应的开始时间的list
def insert_sort(s ,f):
# 插入排序
for i in range(1, len(s)): # 未排序的序列
for j in range(i): # 已排序的序列
if f[j] > f[i]:
temp_s = s.pop(i)
temp_f = f.pop(i)
s.insert(j, temp_s)
f.insert(j, temp_f)
break
return s,f
def greedy_activity(s, f):
res = []
a = [True for x in range(len(s))]
j = 0
for i in range(1, len(s)):
if s[i] >= f[j]:
a[i] = True
j = i
else: a[i] = False
for k in range(len(a)):
if a[k]:
res.append((s[k],f[k]))
return res
s = [1,3,0,5,3,7]
f = [3,4,4,7,6,8]
s, f = insert_sort(s, f)
res = greedy_activity(s,f)
print(res)
[结果] (1, 3), (3, 4), (5, 7), (7, 8)