美文网首页python进阶
Uninformed search Python实现【译】

Uninformed search Python实现【译】

作者: nummycode | 来源:发表于2017-08-20 10:22 被阅读48次

    译自 Uninformed search algorithms in Python
    版权所有,如需转载,请联系译者

    图的搜索可以分为uninformed搜索和informed搜索,两者的区别是前者是的搜索是盲目的,它不知道目标节点在哪,而后者是启发式的搜索。

    主要的uninformed 搜索分为以下三类:

    • 深度优先搜索(DFS)
    • 广度优先搜索(BFS)
    • 一致代价搜索(UCS)

    创建图

    使用邻接矩阵的形式创建图,为简便起见,这里省去节点的其他信息,直接使用一个字典表示,key表示节点,value表示邻接节点:

    small_graph = {
        'A': ['B', 'C'],
        'B': ['D', 'A'],
        'C': ['A'],
        'D': ['B']
    }
    

    深度优先搜索

    深度优先搜索会优先检索第一个邻接节点,然后重复这个过程,直到到达分支的底部,然后回溯。DFS可以通过递归实现,也可以通过递归实现。

    具体实现需要保存已经访问的节点,同时判断边缘条件:

    def dfs(graph, start, goal):
        visited = set()
        stack = [start]
    
        while stack:
            node = stack.pop()
            if node not in visited:
                visited.add(node)
    
                if node == goal:
                    return
                for neighbor in graph[node]:
                    if neighbor not in visited:
                        stack.append(neighbor)
    

    广度优先搜索

    实际上,只需要将上面算法中的stack改为queue,即可实现广度优先搜索。深度优先搜索总是会展开最新的节点,而广度优先搜索总是展开最老的节点,这就是他们为什么一个使用栈,一个使用队列的原因。

    from collections import deque
    
    def bfs(graph, start, goal):
        visited = set()
        queue = [start]
    
        while queue:
            node = queue.pop()
            if node not in visited:
                visited.add(node)
    
                if node == goal:
                    return
                for neighbor in graph[node]:
                    if neighbor not in visited:
                        queue.appendleft(neighbor)
    

    一致代价搜索(UCS)

    该算法主要针对的是加权图,加权图每条边都有一个权值,权值低的边优先遍历,首先,我们创建一个加权图类:

    class Graph:
        def __init__(self):
            self.edges = {}
            self.weights = {}
    
        def neighbors(self, node):
            return self.edges[node]
    
        def get_cost(self, from_node, to_node):
            return self.weights[(from_node + to_node)]
    

    UCS跟广度优先搜索类似,也使用一个queue实现,但是使用的是加权队列

    from queue import PriorityQueue
    

    当每条边的cost相同时,UCS实际上就是BFS。

    def ucs(graph, start, goal):
        visited = set()
        queue = PriorityQueue()
        queue.put((0, start))
    
        while queue:
            cost, node = queue.get()
            if node not in visited:
                visited.add(node)
    
                if node == goal:
                    return
                for i in graph.neighbors(node):
                    if i not in visited:
                        total_cost = cost + graph.get_cost(node, i)
                        queue.put((total_cost, i))
    

    总结

    UCS会检索一条权重之和最小的路径,而BFS会检索出一条边最少的路径。

    相关文章

      网友评论

        本文标题:Uninformed search Python实现【译】

        本文链接:https://www.haomeiwen.com/subject/khxfdxtx.html