繁体   English   中英

隐含图的Python搜索算法

[英]Python Search Algorithm from Implied Graphs

不久前,我问了一个问题( python中的深度优先搜索算法 ),@ 6502很好地回答了这个问题。 它使我可以更精确地考虑这个问题,并导致这个后续问题。

在上一个问题中,您有一个类似这样的函数的隐式有向树:

def neighbors1(node):
    "Returns neighboring nodes in directed tree"
    #some code
    yield node_1
    #some more code
    yield node_2
    #...
    yield node_n

成功标准的功能如下:

def goal(node):
    "Returns true if node is the end goal and false otherwise"
    if node #meets some goal#:
        return True
    else:
        return False

第一个功能暗含某种图形,根据细节,它可以是树或带有循环的图形,并且可以是有向的或无向的。 但是,假设以上内容暗示一棵有向树(如图表所示)。

在此处输入图片说明

这意味着对于任何节点,您都可以找到子节点,然后递归地继续搜索此树。 现在,如果您要从节点A到达节点H(例如),则可以使用上一个问题中的代码,将neighbors1函数传递给搜索函数(如下所示):

def search(start_state, neighbors, goal):
    path = [start_state]

    class PathFound(RuntimeError):
        pass

    def rsearch(x):
        if goal(x):
            raise PathFound
        for y in neighbors(x):
            path.append(y)
            rsearch(y)
            path.pop()

    try:
        rsearch(start_state)
    except PathFound:
        return path

    return None # No path exists

因此,您只需致电

search(A,neighbors1,goal)

现在(经过漫长的介绍),问题是,如果邻居函数隐含不同的图怎么办?

我认为,如果邻居函数隐含这样的非定向树:

在此处输入图片说明

则上述方法可能不起作用,因为您可能会遇到一个无限循环,在该循环中您在B和F之间来回跳跃。但是,我认为可以通过添加简单的检查来查看是否要加倍返回来解决此问题。 :

def search(start_state, neighbors, goal):
    path = [start_state]

    class PathFound(RuntimeError):
        pass

    def rsearch(x):
        if goal(x):
            raise PathFound
        for y in neighbors(x):
            if y in path: continue  #New line for undirected graphs
            path.append(y)
            rsearch(y)
            path.pop()

    try:
        rsearch(start_state)
    except PathFound:
        return path

    return None # No path exists

关于上述欢迎的效率/效果的想法或意见。

但是,问题的症结在于,如果您具有由邻居函数隐含的通用图(如下所示),该怎么办:

随机图

是否有类似的搜索功能,使您可以探索通过它的最短路径(再次使用邻居功能,而不是整个图形的先验知识)。 一种选择是实现dijkstra的算法,但是我认为(尽管很适合找到最佳解决方案),但这对于为大型图找到好的解决方案可能效率不高。 是否存在像这样的深度优先搜索图之类的东西? 还是可以用类似的方式实现dijkstra? 还是您会考虑采用哪种方法?

我希望这个问题有意义,并且对更多人有用,而不仅仅是我!

Dijkstra算法有一个相当有效的版本来查找路径。 将搜索分为两个瓣,从每个终端节点开始。 在这两者之间交替,在每次迭代中扩展一个深度级别。

成功是将节点添加到已经在另一个列表上的一个列表中:两个搜索在中间相遇。


了解:深度优先搜索,通过检查找到终端节点。 在这种情况下,我们需要进行一些简单的更改:

def rsearch(x, found=[]):
    if goal(x):
        raise PathFound
    for y in neighbors(x) and y not in found:
        found.append(y)
        path.insert(0, y)    # switch to depth-first search
        rsearch(y, found)
        path.pop()

您还可以通过向节点对象添加一个布尔值,并在触摸每个节点时对其进行标记,来处理“找到的”列表。

如何为您工作? 当您接近目标节点时,您是否有任何直觉? 如果是这样,可能会有一些启发式方法来缩短搜索时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM