广度优先搜索的效率

时间:2014-08-10 21:49:54

标签: c++ algorithm shortest-path a-star breadth-first-search

计算从无界/无限棋盘上的x1,y1到x2,y2所需的最少跳数的最有效方法是什么?假设从x1,y1我们总能生成一组合法的移动。

这听起来是为BFS量身定做的,我已成功实施了一个。但如果x2,y2任意大,它的空间和时间复杂性似乎很残酷。

我一直在研究各种其他算法,如A *,双向搜索,迭代加深DFS等,但到目前为止,我对于哪种方法将产生最佳(和完整)解决方案毫无头绪。我缺少一些见解吗?

3 个答案:

答案 0 :(得分:2)

我还没有完整的证据,但我相信如果x1,y1和x2,y2在两个方向都很远,那么任何最优解都会有很多动作直接向x2移动直接朝向y2(在这个方向上移动的2个可能的L形移动)。如果当前位置x接近x2但是当前位置y例如远离y2,则在两个移动之间交替,这两个移动朝向y2移动两个方格。并且类似地,如果y接近y2并且x和x2很远。然后,只要到x2,y2的垂直和水平距离都小于某个相当小的阈值(可能是5或10),那么你必须用BFS或其他什么来解决问题以获得最优解,并且解决方案你得到的应该保证是最佳的。当我有证据时我会更新我的答案,但我几乎可以肯定这是真的。如果是这样,这意味着无论x1,y1和x2,y2彼此相距多远,你基本上只需要解决水平和垂直距离都是5或10的问题,这可以很快完成。 / p>

答案 1 :(得分:2)

如果合法移动的集合与当前空间无关,那么这似乎是整数线性规划(ILP)问题的理想选择。您基本上可以解决每种类型的移动的数量,从而最小化移动的总数。例如,对于仅限于向上和向右移动的骑士(因此每次移动都是x+=1, y+=2x+=2, y+=1,您最小化a1+a2,受{2*a1+a2 == x2-x1, a1+2*a2 == y2-y1, a1 >= 0, a2 >= 0限制1}}。虽然ILP通常是NP完全的,但我希望标准的爬山算法能够非常有效地解决它。

答案 2 :(得分:1)

要扩展评论中的讨论,像广度优先搜索(BFS)这样的不知情的搜索将找到最佳解决方案(最短路径)。但是,它仅考虑节点g(n)的成本最高n,并且其成本随着源到目标的距离呈指数增长。要在确保搜索找到最佳解决方案的同时驯服搜索成本,您需要通过启发式h(n)向搜索算法添加一些信息

您的情况非常适合A *搜索,其中启发式是衡量从节点到目标的距离(x2,y2)。你可以使用欧几里德距离“作为乌鸦飞行”,但是当你考虑骑士时,曼哈顿距离可能更合适。无论您选择何种度量,它都必须小于(或等于)从节点到目标的实际距离,以便搜索找到最优解(在这种情况下,启发式被称为“可接受的”)。请注意,您需要将每个距离除以常数,以使其低估移动:曼哈顿距离除以3,欧几里德距离除以sqrt(5)(sqrt(5)是对角线的长度)一个2乘1平方)。

当您运行算法时,您估计距我们已经达到的任何节点f(n)的总距离n作为距离到目前为止加上启发距离。即f(n) = g(n) + h(n)其中g(n)是从(x1,y1)到节点n的距离,h(n)是从节点n到{{1}的估计启发距离}。根据您必须拥有的节点,您始终选择具有最低(x2,y2)的节点n。我喜欢你说的方式:

  

f(n)维护要检出的节点的优先级队列。

如果启发式是可接受的,则算法找到最优解,因为次优路径永远不会位于优先级队列的前面:最佳路径的任何片段总是具有较低的总距离(其中,总距离)是发生距离加启发距离)。

我们在这里选择的距离测量是单调的(即随着路径延长而不是上升或下降而增加)。在这种情况下,可以证明它是有效的。像往常一样,请参阅网络上的wikipedia或其他来源以获取更多详细信息。 Colorado state university page特别好,并且对最优性和效率进行了很好的讨论。

举一个从(-200,-100)到(0,0)的例子,这相当于你的(0,0)到(200,100)的例子,在我的实现中我们用曼哈顿启发式看到的如下

enter image description here

实现过多搜索,因为启发式g(n) + h(n)曼哈顿距离,采用跨越1 up 2 的步骤似乎与跨越2的最佳步骤一样好1 ,即h =值不区分这两者。然而,该算法仍然找到100次移动的最佳解决方案。这需要2118步,这仍然比广泛的第一次搜索要好得多,广泛的第一次搜索像墨水印迹一样展开(我估计它可能需要20000到30000步)。

如果选择f()欧几里德距离,该怎么办?

enter image description here

这好多了!它只需要104步,并且它做得很好,因为它结合了我们的直觉,你需要朝着大致正确的方向前进。但在我们祝贺自己之前,让我们尝试另一个例子,从(-200,0)到(0,0)。这两种启发式算法都找到了长度为100的最佳路径。欧几里得启发式算法需要12171步才能找到最佳路径,如下所示。

enter image description here

而曼哈顿启发式需要16077步

enter image description here

撇开曼哈顿启发式更糟糕的事实,我认为这里的真正问题是存在多条最佳路径。这并不奇怪:最佳路径的重新排序仍然是最佳的。通过按照@Sneftel答案的方式以数学形式重述问题,自动将这一事实考虑在内。

总之,具有可接受启发式的A *比BFS更有效地产生最优解,但很可能存在更有效的解决方案。在你可以轻松提出距离启发式的情况下,A *是一个很好的默认算法,虽然在这种情况下它不会是最好的解决方案,但是通过实现它可以学到很多关于这个问题的知识。 / p>

按照您的要求在C ++中编写以下代码。

h =

请注意,这个测试不是很好,所以可能存在错误,但我希望这个概念很清楚。