贪婪算法——集合覆盖问题

概念

我们生活往往会遇到很多类似于:书包里东西要怎样放才能装下尽可能多的东西。具体来说:比如我有一个可以装35磅的袋子,有一台重15磅价值1500美元的吉他;一台重20磅价值1000美元的电脑;台重30磅价值3000美元的音响。应该怎么怎么装装下价值最大的东西?
贪婪策略的思想是:(1)先装价值最大的物品
(2)剩下得空间再装价值最大的物品。
那么根据贪婪算法思想,我装3000美元音响,继而也得到了问题最优解
但是,如果电脑的价值变为了2500美元呢?
显然其没有得到最优解。

评价

优点:简单易行,每步采取最优解(对于单维度问题其是奏效的)
缺点:得到的解不一定是最优解,只能得到一个相对满意的解

例子

以集合覆盖问题为例:

假设你办了个广播节目,要让全美50个州的听众都能收听的到。为此,你需要决定在哪些广播台播出。在每个广播台播出都需要支付费用,因此你力图在尽可能少的广播台播出。现有广播台名单

广播台 覆盖的州
Kone id, nv, ut
Ktwo wa, id, mt
Kthree r, nv, ca
Kfour nv, ut
Kfive ca, az

在这里插入图片描述
每个广播台都覆盖特定的区域,不同广播台的覆盖区域可能重叠。
通过贪婪算法可以得到非常接近的解:
(1)选出这样一个广播台,即它覆盖了最多的未覆盖的州。即便这个广播台覆盖了一些已覆盖的州,也没有关系。
(2)重复第一步,直到覆盖了所有的州。

这是一种近似算法(approximation algorithm)。在获得精确解需要的时间太长时,可使用近似算法。

python实现

广播站清单,散列表
states_needed=set(["id","wa","mt","nv","ut","ca","az","or"])
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()
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_covered = covered
    states_needed -= states_covered
    final_stations.add(best_station)

print(final_stations)

参考链接:https://blog.csdn.net/u012285175/article/details/85000732

发布了18 篇原创文章 · 获赞 0 · 访问量 1278

猜你喜欢

转载自blog.csdn.net/Zengmeng1998/article/details/100549974