搜索算法-递归风格

作者: FreakWill | 来源:发表于2019-07-02 10:40 被阅读0次

深度优先搜索

伪代码

function dfs(start, isgoal, visited=[])
    if isgoal(start)
        return [start]
    else
        visited += [start]
    for child in children of start excluding visited
        path = dfs(child, isgoal, visited)
        if path is not empty
            return [start] + path
    else
        # has no child or no child returns a path
        return []

Python 实现

def dfsi(start, isgoal, visited=[]):
    if isgoal(start):
        return [start]
    else:
        push start to visited
    for child in rule(start):
        if child not in visited:
            path = dfsi(child, isgoal, visited)
            if path:
                return [start] + path
            else:
                visited.append(child)
    else:
        return []

graph = {'A':{'B','C'},'B':{'D','E'}, 'C':{'E', 'F', 'H'}, 'D':{'I', 'J'}, 'E':{'G', 'K'}, 'F':{'L','M', 'H'}, 'H':{'N', 'M'}}

rule = lambda x: graph.get(x, {})
isgoal = lambda x: x == 'N'
p = dfsi('A', isgoal)
print(p)
# => ['A', 'C', 'F', 'H', 'N']

宽度有限搜索

伪代码

function bfs(starts, isgoal, possible=None, visited=[])
     for start in starts
        if start is goal
            return [start]
        else
            push start to visited
    new_starts =[]
    if possible is None
        possible = [[start] for start in starts]
    new_possible = []
    for start, path in zip(starts, possible)
        for child in rule(start) excluding visited
                if child is goal
                    return path + [child]
                else
                    push child to new_starts
                    push path + [child] to new_possible
    return bfsi(new_starts, isgoal, new_possible, visited)

稍微简化一下,完全等价,但是减少了存储。

function bfs(starts, isgoal, possible=None, visited=[])
     for start in starts
        if start is goal
            return [start]
        else
            push start to visited
    new_starts =[]
    if possible is None
        possible = [[] for start in starts]
    new_possible = []
    for start, path in zip(starts, possible)
        for child in rule(start) excluding visited
                if child is goal
                    return path + [start, child]
                else
                    push child to new_starts
                    push path + [start] to new_possible
    return bfsi(new_starts, isgoal, new_possible, visited)

Python 实现


def bfsi(starts, isgoal, possible=None, visited=[]):

    for start in starts:
        if isgoal(start):
            return [start]
        else:
            visited.append(start)
    new_starts =[]
    if possible is None:
        possible = [[start] for start in starts]
    new_possible = []
    for start, path in zip(starts, possible):
        for child in rule(start):
            if child not in visited:
                if isgoal(child):
                    return path + [child]
                else:
                    new_starts.append(child)
                    new_possible.append(path + [child])
    return bfsi(new_starts, isgoal, new_possible, visited)

graph = {'A':{'B','C'},'B':{'D','E'}, 'C':{'E', 'F', 'H'}, 'D':{'I', 'J'}, 'E':{'G', 'K'}, 'F':{'L','M', 'H'}, 'H':{'N', 'M'}}

rule = lambda x: graph.get(x, {})
isgoal = lambda x: x == 'N'
p = bfsi(['A'], isgoal)
print(p)

# 等价地
def bfsi(starts, isgoal, possible=None, visited=[]):

    for start in starts:
        if isgoal(start):
            return [start]
        else:
            visited.append(start)
    new_starts =[]
    if possible is None:
        possible = [[] for start in starts]
    new_possible = []
    for start, path in zip(starts, possible):
        for child in rule(start):
            if child not in visited:
                if isgoal(child):
                    return path + [start, child]
                else:
                    new_starts.append(child)
                    new_possible.append(path + [start])
    return bfsi(new_starts, isgoal, new_possible, visited)

或者简单封装一下

def bfsi(start, isgoal, possible=None, visited=[]):

    def _bfsi(starts, isgoal, possible=None, visited=[]):

        for start in starts:
            if isgoal(start):
                return [start]
            else:
                visited.append(start)
        new_starts =[]
        if possible is None:
            possible = [[start] for start in starts]
        new_possible = []
        for start, path in zip(starts, possible):
            for child in rule(start):
                if child not in visited:
                    if isgoal(child):
                        return path + [child]
                    else:
                        new_starts.append(child)
                        new_possible.append(path + [child])
        return _bfsi(new_starts, isgoal, new_possible, visited)
    return _bfsi([start], isgoal, possible, visited)

graph = {'A':{'B','C'},'B':{'D','E'}, 'C':{'E', 'F', 'H'}, 'D':{'I', 'J'}, 'E':{'G', 'K'}, 'F':{'L','M', 'H'}, 'H':{'N', 'M'}}

rule = lambda x: graph.get(x, {})
isgoal = lambda x: x == 'N'
p = bfsi('A', isgoal)
print(p)

相关文章

  • 搜索算法-递归风格

    深度优先搜索 伪代码 Python 实现 宽度有限搜索 伪代码 稍微简化一下,完全等价,但是减少了存储。 Pyth...

  • Depth First Search

    概述 DFS(Depth First Search) => 深度优先搜索算法 => 递归与回溯,通常隐含了栈的实现...

  • 马踏棋盘算法

    最近在学习深度优先搜索算法,接触到了马踏棋盘,决定尝试一下。 涉及算法:递归,回溯法,深度优先搜索算法 题目需求:...

  • 二叉树的插入和搜索--python实现

    本文首先介绍了二分查找法,采用“循环”和“递归”2种方法实现。采用递归算法实现了二叉树的插入和搜索算法。 一、二分...

  • 算法汇总

    关于算法: 基础技巧:分治、二分、贪心排序算法:快速排序、归并排序、计数排序搜索算法:回溯、递归、深度优先遍历,广...

  • 算法与数据结构简介

    0x01 算法 基础技巧:分治、二分、贪心 排序算法:快速排序、归并排序、计数排序 搜索算法:回溯、递归、深度优先...

  • 搜索问题

    问题抽象① 从N个数中选择x个数,使其满足一定的条件。这个在搜索算法中非常有用。(用递归完成) 例如:输入N个数,...

  • DFS简单理解

    DFS(深度优先搜索) DFS是一种搜索算法,在我的理解中,它是通过一种类似树状的结构来进行搜索的,运用递归算法。...

  • 算法-二分搜索算法

    算法:二分搜索算法(折半查找算法)时间复杂度: 二分搜索算法概述 二分搜索算法伪代码 二分搜索算法实现 二分搜索算...

  • DFS(深度优先搜索)和BFS(广度优先搜索)

    深度优先搜索算法(Depth-First-Search)深度优先搜索算法(Depth-First-Search),...

网友评论

    本文标题:搜索算法-递归风格

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