[笔记]《算法图解》第八章 贪婪算法
贪婪算法
贪婪算法很简单:每步都采取最优的做法。你每步都选择局部最优解,最终得到的就是全局最优解。
贪婪算法并非在任何情况下都行之有效。
近似算法
在有些情况下,完美是优秀的敌人。有时候,你只需找到一个能够大致解决问题的算法,此时贪婪算法正好可派上用场,因为它们实现起来很容易,得到的结果又与正确结果相当接近。
- 判断近似算法优劣的标准如下:
1.速度有多快
2.得到的近似解和最优解的接近程度
集合
集合类似于列表,只是不能包含重复的元素。
集合运算:并集、交集和差集。
1.并集意味着将集合合并。
2.交集意味着找出两个集合中都有的元素。
3.差集意味着将从一个集合中剔除出现在另一个集合中的元素。
算法实现
final_stations=set()
while states_need:
best_station=None
states_covered=set()
for station,states_for_station in stations.items():
covered=states_need & states_for_station#求交集
if len(covered)>len(states_covered):
best_station=station
states_covered=covered
states_need-=states_covered
final_stations.add(best_station)
NP完全问题
NP完全问题的简单定义是, 以难解著称的问题, 如旅行商问题和集合覆盖问题。 很多非常聪明的人都认为, 根本不可能编写出可快速解决这些问题的算法。
判断NP完全问题:
- 元素较少时算法的运行速度非常快, 但随着元素数量的增加, 速度会变得非常慢。
- 涉及“所有组合”的问题通常是NP完全问题。
- 不能将问题分成小问题, 必须考虑各种可能的情况。 这可能是NP完全问题。
- 如果问题涉及序列(如旅行商问题中的城市序列) 且难以解决, 它可能就是NP完全问题。
- 如果问题涉及集合(如广播台集合) 且难以解决, 它可能就是NP完全问题。
- 如果问题可转换为集合覆盖问题或旅行商问题, 那它肯定是NP完全问题。
小结
- 贪婪算法寻找局部最优解, 企图以这种方式获得全局最优解。
- 对于NP完全问题, 还没有找到快速解决方案。
- 面临NP完全问题时, 最佳的做法是使用近似算法。
- 贪婪算法易于实现、 运行速度快, 是不错的近似算法。