《图解算法》读书笔记(八) 贪婪算法

章节内容

  • 学习如何处理NP问题
  • 学习识别NP完全问题
  • 学习近似算法,使用他们可快速找到NP完全问题的近似解
  • 学习贪婪策略

教室调度问题

学校在给某间教室安排课程时,需要安排尽可能多的课程。
我们没法让全部课程都在这间教室,因为有些课程的上课时间冲突。
我们应该如何选择呢?其实问题很简单:

  1. 选出最早结束的课,这就是这间教师的第一节课
  2. 接下来只能选择第一堂课结束后才开始的课。同第一步,选择最早结束的课
    重复以上步骤就能安排尽可能多的课了。
    这就是贪婪算法,每一步都选择局部最优解,最终得到的就是全局最优解。

背包问题

加入有个背包可以装35磅的东西,现有音响30磅3000美元,笔记本电脑20磅2000美元,吉他15磅1500美元,怎么装价值最高?
这时候贪婪算法就不能获取最优解了。如果根据贪婪算法,我们应该优先装价值最高的音响,这时候背包只剩下5磅的重量可以装了。
但其实如果你选择装吉他和笔记本电脑,刚好35磅,且总价值3500美元,比音响的3000美元多。

集合覆盖问题

一个广播节目,需要让全美50各州的听众都收听的到。每个广播台可以覆盖几个州,如何选择尽可能少的广播台?
假设广播台有n个,按照数学的计算,可能的集合有2^n个。这样算法复杂度就是幂级别的了。
我们可以采用贪婪算法做近似算法。

  1. 选出一个广播台,覆盖了最多的未覆盖的州。
  2. 重复第一步,直至所有州都已经覆盖
while states_needed:
      best_station = None
      states_covered = set()
      for station, states in stations.items():
            covered = states_needed & states
            if len(covered) > len(states_covered)
                  best_station = station
                  states_coverd = covered

states_needed -= states_covered
final_stations.add(best_station)

NP完全问题

旅行商问题

为解决集合覆盖问题,必须计算每个可能的集合。这和第一章的旅行商问题相同。
旅行商问题中的集合大小为n!,n为城市的个数。

如何识别NP完全问题

  1. 元素较少时算法的运行速度非常快,但随着元素数量的增加,速度会变得非常慢
  2. 设计所有组合的问题通常都是NP完全问题
  3. 不能将问题分成小问题,必须考虑各种可能的情况。这可能是NP完全问题
  4. 如果问题设计序列且难以解决,可能是NP完全问题
  5. 如果问题设计集合且难以解决,可能是NP完全问题
  6. 如果问题可转换为集合覆盖问题或旅行商问题,肯定是NP完全问题

小结

  1. 贪婪算法寻找局部最优解,企图以这种方式获得全局最优解
  2. 对于NP完全问题,还没有找到快速解决方案
  3. 面临NP完全问题时,最佳的做法是使用近似算法
  4. 贪婪算法易于实现,运行速度快,是不错的近似算法
posted @ 2020-09-05 23:15  無花無酒鋤作田  阅读(88)  评论(0编辑  收藏  举报