我正在开发一个PHP类,能够从未加权和有向图系统中的两个点计算路线(特别是对于EVE Online)。我从来没有开发图形解决方案,所以我真的不知道计算图形路径的最快方法是什么,所以我环顾网络,即使我发现的只是以数学为中心的讨论或过于特殊的解决方案。
我的第一个想法是找到从节点A到节点B的所有路径并比较它们的长度。我后来注意到这是不必要的,因为我不需要比较,而是找到第一条最短路径。
然后我创建了一个递归系统,它实现了深度优先搜索算法(我在这里提出),但是当两个节点之间的距离增加时,它仍然太重了。我已经在几秒钟内成功跟踪了16步或更少的路径。当涉及到搜索更远的节点时,它将无法在90秒内完成。
请您帮我找一个更快的解决方案?我想创建一个包含各个节点之间所有距离和路径的表,但是我们谈论的是数千个节点,它会永远构建它(并维护它)。
http://hastebin.com/tilusubeli.coffee
班级“跳跃”。
$this->jumpsTable[node_id] = array(next_node_id_1, next_node_id_2, ...)
jumpsTable是图表的数据表示。
THE ALGORITHM:
IDDFS从深度0开始调用DLS并继续向上(最大深度),直到DLS返回有效路径。这样它就不会在相同长度的两条路线之间进行选择,但会选择第一条路线。
DLS是一种递归方法,并查找其“子节点”节点:如果其中一个子节点是目标节点,则返回路径,否则它会将每个子节点称为“起始节点”,并且减少深度值。如果任何DLS调用返回路径,则退出循环。如果没有DLS返回路径,则返回null。
答案 0 :(得分:0)
如果您进行深度优先搜索,则无法保证您找到的第一条路径是最短路径。您应该执行breadth-first search,因为您的图表未加权(否则,标准算法将为A*)。
但是,您需要对实现进行完整的返工,因为递归方法不适合广度优先搜索。请注意,这是一个非常经典的算法,您应该更容易找到现有的PHP实现,例如this one,并使其适应您自己的数据结构。
PS:处理问题的另一种方法是使用depth-first search with iterative deepening,这基本上是使用深度限制应用的深度优先搜索,并且重复应用增加限制(直到目标节点为实测值)。
PPS:如果时间是主要问题,请务必检查您是否多次处理同一节点。
PPPS:您可能会对此问题感兴趣:Given a directed graph, find out whether there is a route between two nodes。