是否有一种算法可以在有向图中检查一个顶点,比如V2,是否可以从顶点V1到达,而不是遍历所有顶点?
答案 0 :(得分:11)
你可能找到到该节点的路线而不遍历所有边缘,如果是这样,你可以尽快给出肯定答案。没有任何东西可以通过遍历所有边缘来确认节点是不可达的(除非你还没有说明其他约束可以用来消除之前的可能性。)
编辑:我应该补充一点,这取决于您需要进行查询的频率与图表的大小(和密集度)。如果您需要在相对较小的图形上进行大量查询,则可能有必要对图形中的数据进行预处理,以生成在任何V1和V2的交叉点处具有位的矩阵,以指示是否存在连接从V1到V2。这不会避免遍历图形,但可以避免在查询时遍历图形。即,它基本上是一种贪婪算法,假设您最终将使用足够的组合,最简单地遍历它们并存储结果。根据图形的大小,预处理步骤可能很慢,但一旦完成,执行查询就会变得非常快(恒定时间,通常是一个相当小的常量)。
答案 1 :(得分:7)
Depth first search或breadth first search。当你找到一个时停下来。但没有办法告诉没有人没有通过每一个,没有。您可以通过一些启发式方法来改善性能,例如,如果您有关于图表的其他信息。例如,如果图形表示像真实地图一样的坐标空间,并且大多数时候您知道将会有一个主要是直接的路径,那么您可以尝试使用深度优先搜索沿着“瞄准朝向”的线条。目标”。但是,想象一下起点和终点正确彼此相邻的情况,但中间没有矢量,并且为了找到它,你必须走 way 方式。您必须检查每个案例才能详尽无遗。
答案 2 :(得分:3)
我怀疑它有一个名字,但广度优先搜索可能会这样:
Add V1 to a queue of nodes to be visited
While there are nodes in the queue:
If the node is V2, return true
Mark the node as visited
For every node at the end of an outgoing edge which is not yet visited:
Add this node to the queue
End for
End while
Return false
答案 3 :(得分:2)
创建图表时创建adjacency matrix。在执行此操作的同时,创建由邻接矩阵的幂来组成的矩阵,直到图中的节点数。要查找是否存在从节点 u 到节点 v 的路径,请检查矩阵(从M ^ 1开始并转到M ^ n 并检查每个矩阵中( u , v )的值。如果对于检查的任何矩阵,该值大于零,则可以停止检查,因为确实存在连接。 (这也为您提供了更多信息:功能告诉您节点之间的步数,该值告诉您该步骤号的节点之间有多少路径。)
(注意,如果您知道图表中最长路径中的步数,无论出于何种原因,您只需要创建多个矩阵,直到该功率。同样,如果您想节省内存,可以只存储基本邻接矩阵并在你进行时创建其他矩阵,但对于大型矩阵,如果你没有使用有效的乘法方法,无论是从库中还是写在你的上,都可能需要相当长的时间。自己的。)
然而,正如其他人所建议的那样,进行深度或广度优先搜索可能是最容易的,不仅因为它们相对容易实现,而且因为你可以在你去的时候生成节点之间的路径沿。 (从技术上讲,你将生成多条路径,并在此过程中丢弃循环/无端循环,但无论如何。)答案 4 :(得分:1)
原则上,如果不遍历图形的某些部分,则无法确定路径是否存在,因为如果不遍历整个图形,则无法确定故障情况(路径不存在)。
您可以通过向后搜索(从目的地搜索到起点)或通过前后搜索步骤之间的交替来提高您的表现。
任何优秀的AI教科书都会详细讨论搜索技巧。 Elaine Rich的书在这方面表现很好。亚马逊是你的朋友。
答案 5 :(得分:1)
您提到here图表代表道路网络。如果图形是平面的,您可以使用Thorup's Algorithm创建一个O(nlogn)空间数据结构,该结构需要O(nlogn)时间来构建并在O(1)时间内回答查询。
答案 6 :(得分:0)
为了确定,你要么必须找到一个路径,要么遍历从V1可以到达的所有顶点。
我建议实现深度优先或广度优先搜索,当它遇到已经看过的顶点时停止。顶点将仅在第一次出现时处理。您需要确保搜索从V1开始,并在它用完顶点或遇到V2时停止。
答案 7 :(得分:0)
此问题的另一种方法是允许您忽略所有顶点。如果您只查看边缘,则可以生成一个传递闭包数组,该数组将显示可从任何其他顶点到达的每个顶点。
从边缘列表开始: Va - >虚电路 Va - > VD ....
创建一个数组,其中起始位置为行,结束位置为列。使用0填充数组。对于边列表中的每条边,在边的起点,终点坐标中放置一个。
现在你迭代几次,直到V1,V2为1或没有变化。
For each row:
NextRowN = RowN
For each column that is true for RowN
Use boolean OR to OR in the results of that row of that number with the current NextRowN.
Set RowN to NextRowN
如果您运行此算法直到结束,您将很快获得所有可到达顶点的完整列表,而无需查看其中任何顶点。运行时与边数成比例。这将适用于合理的实现和合理数量的边缘。
该算法稍微复杂一点的版本是仅计算V1可到达的顶点。为此,您可以将范围集中在当前可在任何给定时间到达的范围。您还可以限制仅将行添加一次,因为其他行永远不会更改。