【问题标题】:Is there a good way to exit a DFS procedure?有没有退出 DFS 程序的好方法?
【发布时间】:2021-02-19 01:30:27
【问题描述】:

我了解到递归深度优先搜索过程会按深度搜索整棵树,并跟踪所有可能的选择。

但是,我想修改函数,以便可以在中间调用“完全退出”,这将完全停止递归。有没有有效的方法来做到这一点?

【问题讨论】:

  • 抛出异常?
  • 另外,您可以切换到带有堆栈的迭代 DFS,然后使用简单的 break 语句提前终止非常简单。
  • 不清楚call a "total exit" in the middle是什么意思。这是否意味着递归函数本身应该在找到有趣的东西后取消 DFS。或者用户,或者超时计时器,是否应该有能力在中间取消 DFS?

标签: algorithm recursion depth-first-search


【解决方案1】:

有 3 种方法可以做到这一点。

  1. 返回一个表示您已完成的值,并在每次调用后检查它。
  2. 抛出异常并在顶层捕获它。
  3. 从递归切换到堆栈,然后break 循环。

第三个效率最高,但工作量也最多。第一个是最清楚的。第二种简单且有效..但往往使代码更复杂并且在许多语言中效率低下。

【讨论】:

    【解决方案2】:

    一个常见的 DFS 是这样工作的:

    DFS(u){
        mark[u] = true
        for each v connected to u:
            if(!mark[v]) DFS(v)
    }
    

    你可以试试这样的:

    static bool STOP = false;   
    
    DFS(u){
        if(STOP) return;
        mark[u] = true
        for each v connected to u:
            if(!mark[v]) DFS(v)
    }
    

    在 DFS 的开头放置一个静态 bool 应该保证一旦你将 STOP 设置为 true,从现在开始不会对 DFS 的堆栈递归调用执行任何重要操作。不幸的是,它不仅会忽略堆叠的函数调用,而且会立即完成。

    【讨论】:

      【解决方案3】:

      协程

      比利接受的答案是错误的三分法。有超过三 (3) 种方法可以做到这一点。 Coroutines 非常适合这种情况,因为它们是可暂停、可恢复和可取消的 -

      def dfs(t):
        if not t:
          return                      # <- stop 
        else:
          yield from dfs(t.left)      # <- delegate control to left branch
          yield t.value               # <- yield a value and pause
          yield from dfs(t.right)     # <- delegate control to right branch
      

      调用者可以控制协程的执行 -

      def search(t, query):
        for val in dfs(t):
          if val == query:
            return val        # <- return stops dfs as soon as query is matched
        return None           # <- otherwise return None if dfs is exhausted
      

      支持协程的语言通常具有一些其他通用函数,这些函数使它们以多种方式发挥作用


      持久迭代器

      另一个类似于协程的选项是流或持久迭代器。具体示例见this Q&A

      【讨论】:

        猜你喜欢
        • 2021-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多