贪婪算法:每步的局部最优解,可能是全局最优解。
问题1:有几个广播台,每个广播台都覆盖特定的区域,不同的广播台的覆盖区域可能重叠。找出覆盖全美50个州的最小广播台集合。
1)选出这样一个广播台,即它覆盖了最多的未覆盖州。即便这个广播台覆盖了一些已覆盖的州,也没有关系。
2)重复第一步,直到覆盖了所有的州。
这个实例中,贪婪算法的时间复杂度为o(n^2)
python中集合类似于列表,只是同样的元素只能出现一次,即集合不能包含重复的元素。
代码实例:
# 首先,创建一个列表,其中包含要覆盖的州
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中
while states_needed:
best_station = None
states_covered = set()
# states_covered 是一个集合,包含该广播台覆盖的所有未覆盖的州。for循环迭代每个广播台,并确定它是否是最佳的广播台。
for station, states_for_station in stations.items():
covered = states_needed & 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)
NP完全问题:
1)旅行商问题
旅行者需要前往5个不同的城市,他需要找出前往这5个城市的最短路径
涉及两个城市,可能的路线是2条
涉及三个城市,可能的路线是6条
涉及4个城市,可能的路线是24条
涉及n个城市,可能的路线是n!条
旅行商问题和集合覆盖问题有一些共同之处:你需要计算所有的解,并从中选出最小或者最短的那个。这两个问题都属于NP完全问题。
旅行商贪婪策略:随便选择出发的城市,然后每次选择要去的下一个城市时,都选择还没去过的最近的城市。
如何判断问题是不是NP完全问题
1)元素较少时算法的运行速度非常快,但随着元素数量的增加,速度会变得非常慢。
2)涉及“所有组合”的问题通常是NP完全问题。
3)不能将问题分成小问题,必须考虑各种可能的情况。这可能是NP完全问题。
4)如果问题涉及序列(如旅行商问题的城市序列)且难以解决,它可能就是NP完全问题。
5)如果问题涉及集合(如广播集合)且难以解决,它可能就是NP完全问题。
6)如果问题可转换为集合覆盖问题或者旅行商问题,那它肯定是NP完全问题。