【问题标题】:DFID (Dept-First Iterative Deeping) vs. IDA* (Iterative-Deeping A*)DFID(深度优先迭代加深)与 IDA*(迭代加深 A*)
【发布时间】:2011-05-21 02:17:27
【问题描述】:

我想知道这两种算法的优缺点是什么。我想写AddEmUp C++ 已解决,但我不确定我应该使用哪种(IDA 或 DFID)算法。

我找到的最好的文章是this one,但它似乎太旧了 - '93。有更新的吗?

我认为 IDA* 会更好,但是.. ?还有其他想法吗?

任何想法和信息都会有所帮助。

谢谢! (:

编辑: 一些关于 IDA* 的好文章和对算法的好解释?

EDIT2: 或者该游戏的一些好的启发式函数?我不知道怎么想一些:/

【问题讨论】:

  • 难道 DFID 不只是 IDA* 的一个特例,其中启发式函数始终为 0?所以本质上你是在问你是否应该使用启发式函数。
  • @huaiyuan:这是一个特例,但没有任何用处。

标签: c++ algorithm artificial-intelligence solver


【解决方案1】:

Russel 和 Norvig 的书是关于这些算法的极好参考,我会给 larsmans 一个虚拟的高五来推荐它;但是我不同意 IDA* 在任何方面都比 A* 更难编程。我已经为一个项目完成了它,我必须编写一个 AI 来解决一个滑块拼图 - 熟悉的问题是有一个 N x N 网格编号的瓷砖,并使用单个可用空间来滑动瓷砖直到它们是按升序排列。

回忆:

F(n) = g(n) + h(n).

TotalCost = PathCost + Heuristic.

g(n) = 路径成本,从初始状态到当前状态的距离

h(n) = 启发式,从当前状态到最终状态的成本估计。要成为一个可接受的启发式算法(从而确保 A* 的最优性),您在任何情况下都不能高估成本。 See this question for more info on the effects of overestimating/underestimating heuristics on A*.

请记住,迭代深化 A* 只是 A* 对允许遍历的节点的 F 值有限制。这个FLimit随着每次外部迭代而增加;在每次迭代中,您都在加深搜索。

Here's my C++ code 同时实现 A* 和 IDA* 来解决上述滑块难题。您可以看到我使用带有自定义比较器的std::priority_queue 将拼图状态存储在按其 F 值优先排序的队列中。您还将注意到 A* 和 IDA* 之间的唯一区别是添加了一个 FLimit 检查和一个递增此 FLimit 的外循环。我希望这有助于阐明这个主题。

【讨论】:

  • 非常感谢,这对我很有帮助(:已接受。
  • @Aphex 在您的实现中,A* 和 IDA* 的最终迭代使用相同的空间。最初提出的实现(参见citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.91.288),作者在IDA*的每次迭代中使用深度优先搜索,其优点是不需要存储A*的打开和关闭列表(在DFS期间有一个访问列表如果图不是树,则需要存储)。
  • 这就是IDA*的理念;您可能在某个(希望是浅的)深度内找到解决方案而无需遍历更深的节点的机会。您和那篇文章所描述的似乎是 IDDFS - 迭代加深深度优先搜索(也称为 DFID) - 不是迭代加深 A*。
  • @Aphex 引用的文章是 IDA* 的原始出版物。引入该算法是因为它减少了内存使用(这使其适用于本文中解决的特定问题,解决魔方,而 A* 或具有深度限制的 A* 则不适用)。
【解决方案2】:

查看Russell & Norvig,第 3 章和第 4 章,并意识到 IDA* 很难正确编程。您可能想尝试递归最佳优先搜索 (RBFS),也由 R&N 描述,或普通的旧 A*。后者可以使用std::priority_queue 来实现。

IIRC,R&N 在第一版中描述了 IDA*,然后在第二版中将其替换为 RBFS。我还没有看到第三版。

关于您的第二次编辑,我还没有研究过游戏,但是推导启发式的一个很好的过程是宽松问题。你拿走游戏规则,直到你得到一个启发式易于表达和实现(并且计算成本低)的版本。或者,按照自下而上的方法,您检查主要规则,看看哪一个允许简单的启发式,然后尝试并根据需要添加其他规则。

【讨论】:

  • 谢谢(:但如果我没记错的话,IDA* 似乎更适合这个游戏。由于我的研究,我一直相信这是解决这个问题的正确算法。如你说这很难,我希望有人能反过来说服我.. :/ :)
  • @Kiril:您是否尝试过实现任何搜索算法?为此类任务选择正确的算法并不是一门精确的科学:您必须尝试多种算法,直到找到一个运行良好的算法。您可能只需要一个简单的算法。
  • 啊,你是对的。我没试过。但是我没有太多时间测试,我只是想知道这种游戏是否有推荐的算法。 AddEmUp 看起来(有点)像 8-puzzle 问题,使用 IDA* 可以最有效地解决。但你是对的,我同意。
  • “IDA* 最有效地解决”在不指定启发式的情况下仍然没有多大意义。我建议在更难的实例上尝试 IDS(或您的源调用它的 DFID)直到它中断,然后在它发生时实施 A* 或 RBFS。实现搜索时有很多选择,这就是为什么还没有人为它编写 库的原因。
  • 非常感谢您提供的信息和您的帮助(:感谢。+1 的关注、解释和建议 R&N。10q
【解决方案3】:

DFID 只是 IDA* 的一个特例,其中启发式函数是常数 0;换句话说,它没有引入启发式方法的规定。如果问题不够小以至于可以在不使用启发式的情况下解决,那么您似乎别无选择,只能使用 IDA*(或 A* 系列的其他成员)。也就是说,IDA* 真的没有那么难:AIMA 的作者提供的implementation 只有大约半页 Lisp 代码;我想 C++ 实现不应该超过两倍。

【讨论】:

  • 啊,非常感谢您的回答!我一定会使用 IDA*。来自我的 +1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
相关资源
最近更新 更多