前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Uninformed search Python实现【译】

Uninformed search Python实现【译】

作者头像
用户2936342
发布2018-08-27 14:14:06
1.1K0
发布2018-08-27 14:14:06
举报
文章被收录于专栏:nummynummy

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

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

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

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

创建图

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

代码语言:javascript
复制
small_graph = {
    'A': ['B', 'C'],
    'B': ['D', 'A'],
    'C': ['A'],
    'D': ['B']
}

深度优先搜索

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

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

代码语言:javascript
复制
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,即可实现广度优先搜索。深度优先搜索总是会展开最新的节点,而广度优先搜索总是展开最老的节点,这就是他们为什么一个使用栈,一个使用队列的原因。

代码语言:javascript
复制
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)

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

代码语言:javascript
复制
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实现,但是使用的是加权队列

代码语言:javascript
复制
from queue import PriorityQueue

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

代码语言:javascript
复制
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会检索出一条边最少的路径。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.08.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建图
  • 深度优先搜索
  • 广度优先搜索
  • 一致代价搜索(UCS)
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档