2019.7.28

说明:以下内容均参考:[美]Aditya Bhargava所著的《算法图解》

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

贪婪算法的特点是速度快、简单且易于实现,可以作为解决NP完全问题的一种近似算法,但并非在任何情况下都行之有效。

集合覆盖问题的一种近似算法便如下面的贪婪算法所示:

(1)选出这样一个广播台,即它覆盖了最多的未覆盖州(即便这个广播台覆盖了一些已覆盖的州,也没有关系);

(2)重复第(1)步,直到覆盖了所有的州。

在集合覆盖问题中,如果要寻找问题的精确解,则时间复杂度为\(O(2^n)\),而贪婪算法的时间复杂度为\(O(n^2)\),其中\(n\)为广播台数量。

以上贪婪算法的代码如下:

# 首先创建一个集合,其中包含要覆盖的州
states_total = 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()

# 算法的思路是每一次都在所有的广播台中寻找一个广播台,使得这个广播台能够在剩余的区域中覆盖的区域最大
# 直至剩余的区域为空,循环停止
# 前面的final_stations之所以使用set,是为了把重复找到的广播台自动过滤掉
while states_total:
    best_station = None # 每一次的best_station和states_covered都要重新设置
    states_covered = set()
    for station, states in stations.items(): # 字典的items函数以列表返回可遍历的(key, values)元组数组
        covered = states_total & states # 集合的与运算
        if len(covered) > len(states_covered): # 找到能覆盖区域最多的广播台
            best_station = station
            states_covered = covered
    
    states_total -= states_covered # 每一次找到局部最优的广播台后,总的区域都要减掉这个广播台可覆盖的区域
    final_stations.add(best_station) # 并将这个局部最优广播台添加到final_stations中
                                     # 这里要注意,set不能用+的方式添加新元素,只能用add方法

print(final_stations)

关于NP完全问题,可以参考:https://www.jianshu.com/p/dcb0b52f4935

NP完全问题的全称是:Non-deterministic Polynomial,即多项式复杂程度的非确定性问题。

P类问题:所有可以在多项式时间内求解的判定问题构成P类问题。

NP类问题:所有非确定性多项式时间内可解的判定问题构成NP类问题。

旅行商问题:算法的时间复杂度强烈依赖于目标的数目,为\(O(n!)\)

旅行商问题和集合覆盖问题都属于NP完全问题,它们有一些共同之处:需要计算所有的解,并从中选取最优的那个。

NP完全问题无处不在,但要判断问题是不是NP完全问题很难,易于解决的问题和NP完全问题的差别通常很小,但以下方法可以帮助识别是不是NP完全问题:

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

(2)涉及“所有组合”的问题通常是NP完全问题;

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

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

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

(6)如果元素较少时算法的运行速度非常快,但随着元素数量的增加,速度会变得非常慢,它可能就是NP完全问题。

对于NP完全问题,目前还没有找到可以快速解决的方案,最佳的做法是使用近似算法。

posted @ 2019-07-28 13:32  mingyu02  阅读(188)  评论(0编辑  收藏  举报