读书笔记 《算法图解》第八章 贪婪算法

本文深入探讨了贪婪算法在解决特定问题中的应用,包括教室调度、背包问题及集合覆盖问题。通过实例解析,阐述了贪婪算法的原理及其在面对NP完全问题时的局限性和优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读书笔记 《算法图解》第八章 贪婪算法

8.1教室调度问题


emmm很显而易见是 美术 + 数学 + 音乐
连着上三堂课不会吐吗
贪婪算法就是 每步都是最优解 最终达到全局最优解

8.2贪婪算法并不总对 —— 背包问题

假设你是个小偷你要偷东西,按贪婪算法来说:
在这里插入图片描述
此时的最优解应该是 电脑 + 吉他 = 3500 > 3000
不过呢 其实也差不多
所以在很多时候 完美是优秀的敌人 用个贪婪算法大差不差也不是不可以

8.3 集合覆盖问题

假设你办了个广播节目,要让全美50个州的听众都收听得到。为此,你力图在尽可能少的广播台播出。现有广播台名单如下。
在这里插入图片描述

每个广播台都覆盖特定的区域,不同广播台的覆盖区域可能重叠

如何找出覆盖全美50个州的最小广播台合集呢?

1)列出广播台的所有子集 2^n
2)选出覆盖州最多且数量最少的子集

运行时间(大O表示法)
找出所有子集的时间 O(n^2)
问题是,如果n的数量增大,时间会急速增长。

此时 贪婪算法 成了该问题的近似算法:
每一次都选出覆盖最多的州,就算后面有重合也没关系,重复步骤直到覆盖了所有州。

衡量近似算法优劣的标准

  • 速度有多快
  • 得到的近似解和最优解的相似程度

贪婪算法速度快,大概为O(n^2)

代码部分

# 创建一个列表,其中包含了要覆盖的州
states_needed = set(['mt', 'wa', 'or', 'id', 'nv', 'ut', 'ca', 'az'])

# 创建可供选择的广播台清单,用dic来表示它们
stations = {}
stations['kone'] = set(['id', 'nv', 'ut'])
stations['ktwo'] = set(['wa', 'id', 'mt'])
stations['kthree'] = set(['or', 'nv', 'ca'])
stations['kfour'] = set(['nv', 'ut'])
stations['kive'] = set(['ca', 'az'])

# 写一个集合来表示最后选择的广播台
final_stations = set()

# 最佳电台(当前没有) 和 覆盖州
while states_needed:
    best_station = None
    states_covered = set()
    for station, states_for_station in stations.items():
        covered = states_for_station & states_needed
        if len(covered) > len(states_covered):
            best_station = station
            states_covered = covered
    final_stations.add(best_station)
    states_needed -= states_covered


print(final_stations)

广度优先搜索和狄杰斯特拉算法都是贪婪算法
其实狄杰斯特拉算法的本质就是广度优先 在相邻的节点上选择而不是一条路线一条路线的选择 这就造成了可能会忽视含有负数加权的最优解。

8.4 NP完全问题

NP 完全问题的简单定义是,以难解著称的问题,如旅行商问题和合集覆盖问题。很多非常聪明的人都认为,根本不可能编写出可快速解决这些问题的算法。

NP问题的特点:

  • 元素较少时算得贼快,较多时算的贼慢
  • 一般需要整排列组合的问题
  • 不能将问题分解成小问题,必须全局考虑
  • 涉及序列(旅行商问题)且难以解决
  • 涉及集合(电台问题)且难以解决

见到NP问题就要去寻找近似算法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值