C++ 广度优先搜索的效率

C++ 广度优先搜索的效率,c++,algorithm,shortest-path,a-star,breadth-first-search,C++,Algorithm,Shortest Path,A Star,Breadth First Search,在无界/无限棋盘上,计算从x1,y1到x2,y2所需最少跳数的最有效方法是什么?假设从x1,y1我们总是可以生成一组合法移动 这听起来是为BFS量身定做的,我已经成功地实现了一个。但是,如果x2,y2任意大,它的空间和时间复杂度似乎非常糟糕 我一直在研究其他各种算法,如A*、双向搜索、迭代深化DFS等,但到目前为止,我不知道哪种方法会产生最佳(和完整)解决方案。我还没有一个完整的证据,但我相信如果x1,y1和x2,y2在两个方向上都很遥远,那么任何最优的解决方案都会有很多直接朝着x2和y2移动的

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

这听起来是为BFS量身定做的,我已经成功地实现了一个。但是,如果x2,y2任意大,它的空间和时间复杂度似乎非常糟糕


我一直在研究其他各种算法,如A*、双向搜索、迭代深化DFS等,但到目前为止,我不知道哪种方法会产生最佳(和完整)解决方案。我还没有一个完整的证据,但我相信如果x1,y1和x2,y2在两个方向上都很遥远,那么任何最优的解决方案都会有很多直接朝着x2和y2移动的移动(两个可能的L形移动在这个方向移动)。例如,如果当前位置x接近x2,但当前位置y远离y2,则在将两个正方形移向y2的两个移动之间交替。同样地,如果y接近y2,x和x2则相距很远。然后,只要到x2,y2的垂直和水平距离小于某个很小的阈值(可能是5或10),那么您就必须使用BFS或其他方法来解决问题,以获得最佳解决方案,并且您得到的解决方案应该保证是最佳的。当我有证据时,我会更新我的答案,但我几乎可以肯定这是真的。如果是这样的话,这意味着无论x1、y1和x2、y2之间的距离有多远,你基本上只需要解决一个水平距离和垂直距离像5或10的问题,这可以很快解决。

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

要扩展评论中的讨论,像广度优先搜索(BFS)这样的未提供信息的搜索将找到最佳解决方案(最短路径)。但是它只考虑到目前为止的成本
g(n)
对于节点
n
而言,其成本随着源到目标的距离呈指数增长。为了在确保搜索找到最佳解决方案的同时降低搜索成本,您需要通过启发式方法
h(n)
向搜索算法添加一些信息

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

当你运行算法时,你估计从任何一个节点到目前为止我们已经得到的距离加上启发式距离的总距离。例如,
f(n)=g(n)+h(n)
其中
g(n)
是从
(x1,y1)
到节点
n
h(n)的距离
是从节点
n
(x2,y2)
的估计启发式距离。考虑到必须到达的节点,您总是选择
n
具有最低
f(n)
的节点。我喜欢您这样说:

按照
g(n)+h(n)
的顺序维护要签出的节点的优先级队列

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

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

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

由于使用启发式
h=
Manhattan距离,跨越1到2的步骤似乎与跨越2到1的最佳步骤一样好,因此实现的搜索太多,即
f()
值无法区分这两种情况。但是,该算法仍然可以找到100步的最优解。它需要2118个步骤,这仍然比广度优先搜索要好得多,广度优先搜索像墨迹一样展开(我估计是