必威体育Betway必威体育官网
当前位置:首页 > IT技术

《算法图解》——第八章 贪婪算法

时间:2019-10-11 08:12:14来源:IT技术作者:seo实验室小编阅读:70次「手机版」
 

贪婪算法

       第八章    贪婪算法

1  简单的贪婪算法

每步都采取最优的做法,每步都选择局部最优解。


2  背包问题

有些情况下,完美是优秀的敌人。如果你只需要找到一个大致解决问题的算法,贪婪算法挺不错,因为实现容易,结果与正确结果相当接近。

练习

8.1 你在一家家具公司工作,需要将家具发往全国各地,为此你需要将箱子装上卡车。每个箱子的尺寸各不相同,你需要尽可能利用每辆卡车的空间,为此你将如何选择要装上卡车的箱子呢?请设计一种贪婪算法。使用这种算法能得到最优解吗?

选择可以装入卡车中最大的箱子,不断重复,直到不能再装,这种算法得不到最优解。

8.2 你要去欧洲旅行,总行程为7天。对于每个旅游胜地,你都给它分配一个价值——表示你有多想去那里看看,并估算出需要多长时间。你如何将这次旅行的价值最大化?请设计一种贪婪算法。使用这种算法能得到最优解吗?

不断地挑选可以在剩下的时间内完成的价值最大的活动,知道剩下的时间不能够完成任何活动为止。同样这种算法得不到最优解。


3  集合覆盖问题

假设你办了个广播节目,要让全美50个州的听众都收听得到。为此,你需要决定在哪些广播台播出。在每个广播台播出都需要支付费用,因此你力图在尽可能少的广播台播出。每个广播台都覆盖特定的区域,不同广播台的覆盖区域可能重叠。

具体方法如下:

①列出每个可能的广播台集合,这被称为幂集(power set)。可能的子集有2**n个。

②在这些集合中,选出覆盖全美50个州的最小集合。

由于可能的子集有2**n个,因此运行时间为O(2**n)。

用贪婪算法可得到非常接近的解:

①选出这样一个广播台,它覆盖了最多的未覆盖的州。即使有重复的州也没有关系

②重复第一步,直到覆盖了所有的州

这是一种近似算法。判断近似算法优劣的标准如下:

①速度有多快

②得到的近似解与最优解的接近程度。在这个例子中贪婪算法的运行时间为O(n**2)


上述问题代码实现过程(简化问题):

①准备工作,首先,创建一个列表,其中包含要覆盖的州:states_needed = set(["mt", "wa", "or", "id", "nv", "ut","ca", "az"])(使用集合的不重复特点);还需要有可供选择的广播清单,用散列表来表示它:

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["kfive"] = set(["ca", "az"])

其中,键为电台名字,值为覆盖的州。最后用一个集合来保存最终选择的电台:final_stations = set()

②计算答案

需要从中选择覆盖了最多的未覆盖州的广播台。将整个广播台存储在best_station 中。

states_needed = (["mt", "wa", "or", "id", "nv", "ut","ca", "az"])    #这个代码有问题没解决
stations = {}
stations["kone"] = (["id", "nv", "ut"])
stations["ktwo"] = (["wa", "id", "mt"])
stations["kthree"] = (["or", "nv", "ca"])
stations["kfour"] = (["nv", "ut"])
stations["kfive"] = (["ca", "az"])
final_stations = ()
while states_needed:
    best_station = ()
    states_covered = ()
    for station, states_for_station in stations.items():
        covered = states_needed and states_for_station
        if len(covered) > len(states_covered):
           best_station = station
           states_covered = covered
states_needed -= states_covered
final_stations.add(best_station)
print(final_stations)      #这是结果set(['ktwo', 'kthree', 'kone', 'kfive'])

states_covered 是一个集合,包含该广播台覆盖的所有未覆盖的州。 for 循环迭代每个广播台,并确定它是否是最佳的广播台。下面来看看这个 for 循环的循环体。

covered 是一个集合,包含同时出现在 states_needed 和states_for_station 中的州;

贪婪算法和精确算法的运行时间对比:

练习

下面各种算法是否是贪婪算法。

8.3 快速排序。否

8.4 广度优先搜索。是

8.5 狄克斯特拉算法。是


4  NP完全问题

旅行商问题详解:

2个城市时,2条;3个城市时,6条;4个城市时,24条;同理:N个城市就是N!条,这被称为阶乘函数

如何识别NP完全问题:

①元素较少时算法的运行速度非常快,但随着元素数量的增加,速度会变得非常慢。

②涉及“所有组合”的问题通常是NP完全问题。

③不能将问题分成小问题,必须考虑各种可能的情况。这可能是NP完全问题。

④如果问题涉及序列(如旅行商问题中的城市序列)且难以解决,它可能就是NP完全问题。

⑤如果问题涉及集合(如广播台集合)且难以解决,它可能就是NP完全问题。

⑥如果问题可转换为集合覆盖问题或旅行商问题,那它肯定是NP完全问题。

练习

8.6 有个邮递员负责给20个家庭送信,需要找出经过这20个家庭的最短路径。请问这是一个NP完全问题吗?类似旅行商问题,是一个NP完全问题

8.7 在一堆人中找出最大的朋友圈(即其中任何两个人都相识)是NP完全问题吗?类似集合覆盖问题,同样是一个NP完全问题

8.8 你要制作美国地图,需要用不同的颜色标出相邻的州。为此,你需要确定最少需要使用多少种颜色,才能确保任何两个相邻州的颜色都不同。请问这是NP完全问题吗?也是


5  小结

贪婪算法寻找局部最优解,企图以这种方式获得全局最优解。

对于NP完全问题,还没有找到快速解决方案

面临NP完全问题时,最佳的做法是使用近似算法。

贪婪算法易于实现、运行速度快,是不错的近似算法。

相关阅读

冒泡排序——《图解算法》

冒泡排序分从大到小和从小到大两种排序方式。它们的唯一区别就是两个数交换的条件不同,从大到小排序是前面的数比后面的小的时候交

经典算法之关键路径

问题提出: 设一个工程有11项活动,9个事件,事件V1 ----- 表示整个工程开始,事件V9 ----- 表示整个工程结束。 每个事件的开始必须是它

机器学习算法(3)之决策树算法

前言:首先,在了解树模型之前,自然想到树模型和线性模型有什么区别呢?其中最重要的是,树形模型是一个一个特征进行处理,之前线性模型是所

Machine Learning学习笔记(七)粒子群优化算法

粒子群优化算法( PARTICAL SWARMS OPTIMIZATION) 粒子群优化,是除了蚁群算法,鱼群算法之外的一种群体智能的优化算法,源自对鸟类捕

flume之退避算法backoff algorithm

flume之退避算法backoff algorithm什么是退避算法:In a single channel contention based medium access control (MAC) protocols

分享到:

栏目导航

推荐阅读

热门阅读