Uninformed search Python實現【譯】

譯自 Uninformed search algorithms in Python
版權全部,如需轉載,請聯繫譯者node

圖的搜索能夠分爲uninformed搜索和informed搜索,二者的區別是前者是的搜索是盲目的,它不知道目標節點在哪,然後者是啓發式的搜索。python

主要的uninformed 搜索分爲如下三類:git

  • 深度優先搜索(DFS)github

  • 廣度優先搜索(BFS)算法

  • 一致代價搜索(UCS)app

建立圖

使用鄰接矩陣的形式建立圖,爲簡便起見,這裏省去節點的其餘信息,直接使用一個字典表示,key表示節點,value表示鄰接節點:code

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

深度優先搜索

深度優先搜索會優先檢索第一個鄰接節點,而後重複這個過程,直到到達分支的底部,而後回溯。DFS能夠經過遞歸實現,也能夠經過遞歸實現。orm

具體實現須要保存已經訪問的節點,同時判斷邊緣條件:blog

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)

一致代價搜索

該算法主要針對的是加權圖,加權圖每條邊都有一個權值,權值低的邊優先遍歷,首先,咱們建立一個加權圖類:

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會檢索出一條邊最少的路徑。

相關文章
相關標籤/搜索