繁体   English   中英

如果记忆是自上而下的深度优先,而 DP 是自下而上的广度优先,那么自上而下的广度优先/自下而上的深度优先等价物是什么?

[英]If memoization is top-down depth-first, and DP is bottom-up breadth-first, what are the top-down breadth-first / bottom-up depth-first equivalents?

我刚刚阅读了 Krishnamurthi 教授撰写的关于递归记忆与动态编程的心智模型的简短文章 在其中, Krishnamurthi将记忆化的自顶向下结构表示为递归树,将 DP 的自底向上结构表示为 DAG,其中源顶点是第一个(可能是最小的)子问题解决,而汇顶点是最终计算(本质上是图与前面提到的递归树相同,但所有边都翻转了)。 很公平,这完全有道理。

不管怎样,最后他给读者一个心理练习:

记忆化是对答案的自上而下、深度优先计算的优化。 DP 是对答案的自底向上、广度优先计算的优化。

我们自然应该问,那呢?

  • 自顶向下,广度优先
  • 自下而上,深度优先

它们在哪里适合通过权衡空间来避免重新计算的技术空间?

  • 我们已经为他们取了名字吗? 如果是,是什么?,或者
  • 我们是否遗漏了一两个重要的技巧?,或者
  • 有什么原因我们没有这些名字吗?

然而,他停在那里,对这些问题没有给出他的想法。


我迷路了,但这里是:

我的解释是,自上而下、广度优先的计算需要对每个函数调用进行单独的处理。 自底向上、深度优先的方法会以某种方式将最终解决方案拼凑在一起,因为每个跟踪都到达“汇顶点”。 一旦完成所有呼叫,该解决方案最终将“累加”到正确答案。

我怎么样了? 有人知道他三个问题的答案吗?

让我们分析一下这两个图中的边是什么意思。 从子问题ab的边表示一种关系,其中b的解用于计算a并且必须在它之前求解。 (在另一种情况下反过来。)

会想到拓扑排序吗?

进行拓扑排序的一种方法是执行深度优先搜索,然后在离开每个节点的途中对其进行处理。 这基本上就是递归记忆的作用。 您从每个子问题开始使用深度优先,直到遇到您尚未解决的问题(或您尚未访问的节点)并解决它。

动态规划,或自下而上 - 广度优先解决问题的方法涉及解决较小的问题并从中构建解决较大问题的方法。 这是进行拓扑排序的另一种方法,您访问入度为 0 的节点,对其进行处理,然后将其删除。 在 DP 中,最小的问题首先被解决,因为它们的入度较低。 (较小是对手头问题的主观感受。)

这里的问题是生成必须解决子问题集的序列。 自上而下的广度优先和自下而上的深度优先都不能做到这一点。 即使进程被分成线程,自上而下的广度优先最终仍然会做一些与深度优先计数器非常相似的事情。 有一个必须解决问题的顺序。 自底向上的深度优先方法可能能够部分解决问题,但最终结果仍然类似于广度优先的对应部分。 子问题将以类似的顺序解决。

鉴于这些方法与其他方法相比几乎没有任何改进,不能很好地与类比转化并且实施起来很乏味,因此它们还没有很好地建立。

@AndyG 的评论在这里非常重要。 我也喜欢@shebang 的回答,但这里有一个在这种情况下直接回答这些问题的回答,而不是通过归结为另一个问题。

只是不清楚自上而下、广度优先的解决方案会是什么样子。 但是,即使您以某种方式暂停计算以不进行任何子计算(人们可以想象可能实现这一点的各种基于延续的方案),这样做也没有意义,因为会共享子问题。

同样,自下而上、深度优先的解决方案能否解决这个问题也不清楚。 如果您自下而上进行,但一直在计算的某些脊椎上充电,但其他子问题的解决方案尚未准备好并等待,那么您就是在计算垃圾。

因此,自上而下的广度优先没有任何好处,而自下而上的深度优先甚至没有提供解决方案。

顺便说一句,上述博客文章的更新版本现在是我文本中的一个部分(这是 2014 版;期待更新

暂无
暂无

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

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