算法图解——常见算法

105 阅读2分钟

广度优先搜索

广度优先搜索用于图的算法,他研究的是最少的路径,对于一个没有权重的图,他先依次查找每个相邻节点再去查找每个相邻节点都相邻节点。 在找人的案例中,我们可以想象当我们寻找一位医生时,我们首先查找我们的朋友,其次是朋友的朋友。可以用一个列队来实现这个功能,首先添加“我”的朋友,其次利用列队先进先出的性质,检查第一个人是否符合要求,如果不合要求,就在尾部添加首个元素的相邻节点。同时用一个列表储存已经检查过的元素。

from collections import deque
graph= {}
graph["you"] = ["alice","bob","claire"]
graph["alice"] = ["peggy"]
graph["bob"] = ["thom","jonny"]
graph["claire"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []
def search(name):
    search_queue = deque()
    search_queue += graph["you"]
    searched = []
    while search_queue:
        person = search_queue.popleft()
        if person not in searched:
            if person_is(person):
                return True
            else:
                search_queue += graph[person]
                searched.append(person)
    return False

def person_is(person): #判断是否符合条件
    pass

狄克斯特拉算法

狄克斯特拉算法是对广度优先算法的优化,他考虑的是在节点间路径存在权重的情况,如果路径间存在权重,那就不能简单的以路径的多少来衡量结果,而是要计算总权重的大小。要不断寻找最便宜的节点,对于他的邻居,计算是否有更便宜的路径。 除了储存所有信息的散列表,我们还需要一个开销表来存储从起点前往该节点的花销。一个存储父节点的散列表,记录每个节点的父节点,用来记录路径。

graph = {} #所有信息的散列表

graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
# print(graph["start"])
graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}

infinity = float("inf") #开销表
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity

parents = {} #储存父节点的散列表
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None

processed = []

def find_lowest_cost_node(costs):
   lowcost = float("inf")
   lowcostnode = None
   for i in costs:
       cost = costs[i]
       if cost < lowcost and i not in processed:
           lowcostnode = i
           lowcost = cost
   return lowcostnode
   
   
node = find_lowest_cost_node(costs)

while node is not None:
   cost = costs[node]
   neighborhood = graph[node]
   for n in neighborhood.keys():
       newcost = cost + neighborhood[n]
       if newcost < cost[n]:
           cost[n] = newcost
           parents[n] = node
   processed.append(node)
   node = find_lowest_cost_node(costs)

贪婪算法

贪婪算法的思想是不断的从一系列选择中寻找最大值,每次找到最大值后,下一次就剔除本次最大值而寻找下一个最大值。贪婪算法的核心是在每一步都选择最优算法。要寻找一个能覆盖尽可能多区域的广播电台,会利用到一个交集来判断当前电台覆盖的区域是不是我们需要的区域。

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["ktree"] = set(["or","nv","ca"])
stations["kfour"] = set(["nv","ut"])
stations["kfive"] = set(["ca","az"])
final_station = set()
while states_needed:
    best_station = None
    states_covered = set()
    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_station.add(best_station)