![]() |
1
118
这似乎可以通过对图形进行深度优先搜索来实现。 深度优先搜索将查找两个节点之间的所有非循环路径。 我注意到上面指定的图只有一条边是方向的(B,E)。这是打字错误还是真的是有向图?不管怎样,这个解决方案都是有效的。对不起,我不能用C语言写,我在这方面有点弱。我希望您能够翻译这个Java代码而不会有太多麻烦。 Graph.java:
Search.java:
程序输出:
|
![]() |
2
24
美国国家标准与技术研究所(NIST)算法和数据结构在线词典将该问题列为“ all simple paths" depth-first search . CLRS提供了相关的算法。 发现了一种使用Petri网的巧妙方法 here |
![]() |
3
13
这是我想出的伪代码。这不是任何特定的伪代码方言,但应该足够简单。 任何人都想把它拆开。
假设有一种查找相邻顶点的有效方法(第6行)。 1 PathList [p] 2 ListOfPathLists [x] 3 Vertex [s], [d] 4 PathFind ( Vertex [c] ) 5 Add [c] to tail end of list [p] 6 For each Vertex [v] adjacent to [c] 7 If [v] is equal to [d] then 8 Save list [p] in [x] 9 Else If [v] is not in list [p] 10 PathFind([v]) 11 Next For 12 Remove tail from [p] 13 Return |
![]() |
4
8
由于中给出了现有的非递归DFS实现 this answer 似乎是坏的,让我提供一个实际工作。
我用Python编写了这篇文章,因为我发现它可读性很强,实现细节也很整洁(而且它有方便的
此代码还使用单独的
或者,如果正在为节点使用自定义可变类/结构,则可以在每个节点中存储一个布尔标志,以指示它是否已作为当前搜索路径的一部分被访问。当然,如果您出于某种原因希望在同一个图上并行运行两个搜索,则此方法不允许您这样做。 下面是一些测试代码,演示了上述函数的工作原理:
在给定的示例图上运行此代码将生成以下输出: A -> B -> C -> D A -> B -> D A -> C -> B -> D A -> C -> D
请注意,虽然此示例图是无向图(即其所有边都是双向的),但该算法也适用于任意有向图。例如,删除
附言 对于这种简单的搜索算法(以及本线程中给出的其他算法),很容易构造出性能非常差的图。 例如,考虑在无向图上找到从A到B的所有路径的任务,其中起始节点A具有两个邻居:目标节点B(它没有其他邻居比A)和节点C是A的一部分。 clique 属于 N +1个节点,如下所示:
很容易看出,A和B之间的唯一路径是直接路径,但从节点A开始的中堂DFS将浪费O( !) 时间无用地探索集团内部的路径,即使(对人类而言)这些路径都不可能通向B。 也可以构造 DAGs 1. 和C 2. 1. 和D ,两者都连接到E 1. 2. 像这样排列的节点层,中堂搜索从a到B的所有路径将最终浪费O(2 N )在放弃之前,花时间检查所有可能的死胡同。 当然,从团中的一个节点(C除外)或DAG的最后一层向目标节点B添加边, 将 output sensitivity 这种中堂搜索的主要原因是他们对图形的全局结构缺乏认识。 虽然有各种各样的预处理方法(如迭代消除叶节点、搜索单节点顶点分隔符等)可以用来避免这些“指数时间死角”,但我不知道有任何通用的预处理技巧可以在任何情况下消除它们 全部的 案例。一个通用的解决方案是在搜索的每一步检查目标节点是否仍然可以到达(使用子搜索),如果不能到达,则尽早回溯——但遗憾的是,这将大大降低搜索速度(最坏的情况下,与图的大小成比例),因为许多图 不要 包含这种病态的死胡同。 |
![]() |
5
5
程序输出
|
![]() |
6
4
|
![]() |
7
3
这可能已经晚了,但这里是Casey提供的Java中DFS算法的C#版本,它使用堆栈遍历两个节点之间的所有路径。与往常一样,递归的可读性更好。
This is a sample graph to test: // Sample graph. Numbers are edge ids // 1 3 // A --- B --- C ---- // | | 2 | // | 4 ----- D | // ------------------ |
![]() |
8
1
我最近解决了一个类似的问题,而不是所有的解决方案,我只对最短的问题感兴趣。 我使用了一个“宽度优先”的迭代搜索,它使用了一个“状态”队列,每个队列都保存了一条记录,其中包含图形上的当前点和到达该点的路径。
通过代码的每次迭代都会将该项从列表的开头移除,并检查它是否是一个解决方案(到达的节点是您想要的,如果是,我们就完成了),否则,它会构造一个新的队列项,其中节点连接到当前节点,并根据前一个节点的路径修改路径,在末端附加新的跳跃。 现在,您可以使用类似的方法,但当您找到解决方案时,不要停止,而是将该解决方案添加到“已找到列表”并继续。 您需要跟踪已访问的节点列表,这样您就永远不会回溯自己,否则您将有一个无限循环。 如果你想要更多的伪代码,发表评论或其他东西,我会详细说明。 |
![]() |
9
1
我认为你应该描述一下这背后的真正问题。我这样说是因为你要求一些时间效率高的东西,但问题的答案似乎呈指数增长! 因此,我不希望有比指数算法更好的算法。
使用递归:
还是错了? 编辑: 哦,我忘了: 应该通过利用该节点堆栈消除递归调用 |
![]() |
10
1
下面是我用最小时间复杂度O(log*n)尝试的C代码,这意味着对于65536边列表,它需要4次搜索,对于2^65536,它需要5次搜索。我正在分享我的算法实现: Algorithm Course from Princeton university 提示:您可以从上面共享的链接中找到Java解决方案,并进行适当的解释。
|
![]() |
11
1
查找路径[s、t、d、k]这个问题由来已久,已经有了答案。然而,没有一种算法能更灵活地完成同样的任务。所以我要把我的帽子扔进拳击场。
我个人发现了一种形式的算法
使用编程语言的无穷形式
§显然,如果您使用的是有向图,并且希望
没有目标的
辅助函数我个人喜欢递归,尽管有时会很困难,但首先让我们定义我们的帮助函数:
主要功能这样一来,核心功能就变得微不足道了:
首先,让我们注意几件事:
|
![]() |
12
0
我脑子里有一个想法:
|
![]() |
13
0
|
![]() |
14
0
我找到了一种方法来枚举所有路径,包括包含循环的无限路径。 http://blog.vjeux.com/2009/project/project-shortest-path.html 寻找原子路径&周期
我们要做的是找到从点A到点B的所有可能路径。因为涉及到循环,所以不能只遍历并列举它们。相反,您必须找到不循环的原子路径和尽可能小的循环(您不希望自己的循环重复)。
这个定义很方便,它也适用于循环:点A的原子循环是从点A到点A的原子路径。 实施
为了获得从点A开始的所有路径,我们将从点A递归遍历图形。在遍历子对象时,我们将创建一个链接子对象->为了知道我们已经穿过的所有边缘。在转到该子级之前,必须遍历该链表,并确保尚未遍历指定的边。
要释放链接列表时会出现问题。它基本上是一棵按相反顺序链接的树。一个解决方案是双重链接该列表,当找到所有原子路径时,从起点释放树。 但一个聪明的解决方案是使用引用计数(灵感来自垃圾收集)。每次向父级添加链接时,都会向其引用计数添加一个链接。然后,当你到达一条路径的末端时,当引用计数等于1时,你返回并释放。如果它更高,您只需删除一个并停止。
查找A的原子循环与查找从A到A的原子路径是一样的。但是,我们可以进行一些优化。首先,当我们到达目的地时,我们只想在边成本之和为负时保存路径:我们只想经历吸收循环。 如前所述,在查找原子路径时,将遍历整个图形。相反,我们可以将搜索区域限制为包含A的强连通组件。查找这些组件需要使用Tarjan算法对图进行简单遍历。 结合原子路径和循环
|
![]() |
15
0
正如其他一些海报所巧妙地描述的,简言之,问题在于使用深度优先搜索算法递归地搜索图形以查找通信端节点之间的所有路径组合。 该算法本身从您给它的开始节点开始,通过展开出现的搜索树的第一个子节点来检查其所有传出链接,并不断深入搜索,直到找到目标节点,或者直到遇到没有子节点的节点。 然后搜索返回,返回到它尚未完成搜索的最近节点。 我 blogged 关于这个话题最近,在这个过程中发布了一个C++实现例子。 |
![]() |
16
0
除了Casey Watson的回答之外,还有另一个Java实现,。
|
![]() |
John V · 是否存在单元测试无法发现的逻辑/流错误类型? 7 年前 |
![]() |
Beefster · 为什么ANSI颜色转义以“m”而不是“]”结尾? 7 年前 |
![]() |
Guillermo Gutiérrez · STR转换是如何工作的? 7 年前 |
![]() |
RudziankoÅ · 合并排序数组算法 7 年前 |
|
user8852560 · 构造函数中的验证和构造函数冲突 7 年前 |
![]() |
jav974 · 订购产品时寻找最佳价格组合的算法 7 年前 |
![]() |
hippietrail · 确定浮点数中前导零的数量 7 年前 |