zoukankan      html  css  js  c++  java
  • 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完全问题,目前还没有找到可以快速解决的方案,最佳的做法是使用近似算法。

  • 相关阅读:
    elasticsearch + python
    Django中的监控组件Prometheus
    MySQL索引原理以及最左前缀原则
    Insert ignore,还是insert replace还是insert on duplicate key update区别
    PyTorch中Tensor与numpy数据之间时共享的条件:
    在Numpy中numpy.nan显示成-9223372036854775808的缘故
    mac上安装pil报错: ERROR: Could not find a version that satisfies the requirement pil (from versions: none):
    OSError: [Errno 48] Address already in use
    curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused
    在实际项目中使用git推代码踩过的坑
  • 原文地址:https://www.cnblogs.com/tbgatgb/p/11258679.html
Copyright © 2011-2022 走看看