Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在图形中搜索路径?_Java_Algorithm_Data Structures - Fatal编程技术网

Java 如何在图形中搜索路径?

Java 如何在图形中搜索路径?,java,algorithm,data-structures,Java,Algorithm,Data Structures,假设我有一个边列表,每个边包含两个节点(到和从)。找到两个给定节点的边的最佳方法是什么?请注意,边中的节点可能会重复 假设我有此格式的edge: 15 37 5.6 26 然后,像15这样的查询将返回true 然后像52这样的查询将返回true,因为5连接6,6连接2 然后像17这样的查询将返回false 然后,像7 4这样的查询将返回false,因为4不存在,这意味着它是无边节点。您基本上希望测试给定的一对节点之间是否有路径。这是最短路径问题的一般情况。然而,请注意,如果我们能在所讨论的节点对

假设我有一个边列表,每个边包含两个节点(到和从)。找到两个给定节点的边的最佳方法是什么?请注意,边中的节点可能会重复

假设我有此格式的edge:

15

37

5.6

26

然后,像15这样的查询将返回true

然后像52这样的查询将返回true,因为5连接6,6连接2

然后像17这样的查询将返回false


然后,像7 4这样的查询将返回false,因为4不存在,这意味着它是无边节点。

您基本上希望测试给定的一对节点之间是否有路径。这是最短路径问题的一般情况。然而,请注意,如果我们能在所讨论的节点对之间找到一条最短路径,这就足够了。使用任何适合您的表示法(邻接矩阵、邻接列表、边集、联合查找…),并继续为所有节点对执行BFS/Djikstra实现。这仅仅是一个为查询提供服务的问题。或者,您可以在惰性的基础上运行Djikstra/BFS(并以增量方式缓存过去的计算)。

请查看库,它专门研究图形算法并满足您的需要。

我觉得您只是在问无向图形中两个顶点之间是否存在路径,但不一定是该路径。这与询问两个顶点是否位于图的同一连通组件中相同

如果你真的只需要知道两个顶点是否在同一个连接的组件中,那么有一个简单而有效的算法使用一个

要在处理所有边后确定两个顶点之间是否存在路径,只需检查两个顶点是否在同一子集中。如果是,则它们之间存在某种路径


在DSS的高效实现中,该算法的性能略差于线性时间,即使是DSS的简单链表实现,它也是O(n
*
log(n))。正如j
\uuu
random
\uu
hacker提到的,Floyd Warshall是O(n^3)时间和O(n^2)存储,无论您是否只计算传递闭包,使用Dijkstra算法都需要O(n
*
日志(n))每个查询的计算。

您可能需要一些不同的算法来查找所有图形顶点之间的最短路径。据我所知,你只需要一个无向图。以下是伪代码:

for k = 1 to n
  for i = 1 to n
    for j = 1 to n
      W[i][j] = W[i][j] or (W[i][k] and W[k][j])
W
在运行此代码之前,该代码应该是图形的二进制邻接矩阵(
W[i][j]==1
i
j
)。
之后将是一个传递闭包。也就是说,
W[I][j]
等于
1
当且仅当
j
可从
I
访问时,您有一个边列表,您想知道如何找到边?你能提供更多的信息吗?你似乎没有很好地解释你的问题。对不起,我还是很困惑。您是否正在尝试确定两个节点是否构成一条边?你想找到最近的边缘吗?如果是这样的话,除了边之外,我们还有其他节点吗?如果你从数学上定义这个问题,可能会有所帮助。Sasha,(5 2)不是该列表中的边,所以如果你想找到边,那么(5 2)不会返回TRUE。如果你希望(52)为真,那么你在搜索两个节点之间的路径,而不是边。@Sasha:从数学上讲,你要寻找的是两个顶点是否属于一个图中相同的连接组件。我建议你(再次)更改标题。在任何情况下,请参阅Theran的答案以获得有效的解决方案。这是(唯一)正确的、有效的问题修订版答案。事实上,这个问题并不意味着知道不相交的顶点集。这太过分了。你只需要一个图的传递闭包。不需要最短路径——请参阅Theran的解决方案。请仔细阅读整篇文章或至少是代码片段。如果你仔细观察,你会发现这个算法只确定一个顶点是否可以从另一个顶点到达。Floyd使用O(n^3)时间和大量内存。这显然不是解决这个问题的最佳算法。嗯,我同意这可能不是最好的,但它是最简单的。@dragonfly:我现在知道你只计算传递闭包而不是最短路径,但我怀疑使用“or”和“and”比分别使用“min()”和“+”快得多。在任何情况下,复杂度仍然是O(n^3),而塞兰的接近线性(逆阿克曼)。-1。这不需要最短路径——请参阅Theran的解决方案。(我知道你可能已经回答了这个问题的早期版本,但无论如何,这个答案不再正确。)@j_random_hacker:如果你注意我的回答,我也提到了union find。我只是把一个定义不清的问题转换成了一个已知的问题。@j_random_hacker:至于最短路径——我只强调了许多可能的答案中的一个。@Dirkgent:你确实提到了它,但你在一堆其他不必要的方法中提到了它——为什么?这个问题(正如现在所说的,虽然可能不是在最新的编辑之前)已经很明确了。@j_random_hacker:我不认为它们是多余的。它们是解决问题的替代方法。
for k = 1 to n
  for i = 1 to n
    for j = 1 to n
      W[i][j] = W[i][j] or (W[i][k] and W[k][j])