我需要搜索DAG图,但在看到所有其他指向链接的节点之前,我不想超越节点。
是否存在处理此特定情况的现有算法,深度优先搜索和呼吸优先搜索不适用于此遍历顺序。
即:
A -> B
B -> C
C -> D
A -> C
在看到B和C之前,我不想达到D.
答案 0 :(得分:2)
您正在寻找的是Kahn(1962)的拓扑排序算法。这不是当前在BGL中实现的拓扑排序算法,它是基于DFS的,访问所有顶点,并以反向拓扑顺序输出结果,而是非常类似于BFS并以您在您的描述中完全按照您描述的方式访问顶点第一段。你必须自己编写遍历,但算法很简单。
请参阅拓扑排序维基百科条目中列出的第一个算法:http://en.wikipedia.org/wiki/Topological_sorting。另请参阅Sedgewick的“C算法”中的程序19.8。
提示1:使用辅助数据结构来保持每个顶点的边缘数,不要实际执行“从图中删除边”部分。
提示2:对于一个有效的GPLV3示例,您可以在我的CoFlo控制流图生成和分析项目中查看Kahn算法的实现,特别是文件topology_visit_kahn.h:http://coflo.svn.sourceforge.net/viewvc/coflo/trunk/src/controlflowgraph/topological_visit_kahn.h?view=log < / p>
答案 1 :(得分:1)
所以我的最新想法是每当添加或删除边时对整个图进行拓扑排序,并存储每个节点要遍历的直接子节点的顺序(这可能是一个棘手的算法写入)。
然后我做了一个修改后的广度优先搜索(如混沌所示),并在下面的bfs伪代码中修改该行:
for each vertex v in Adj[u]
是:
for each vertex v in OrderedAdj[u]
伪代码:
BFS(G, s)
for each vertex u in V[G]
color[u] := WHITE
d[u] := infinity
p[u] := u
end for
color[s] := GRAY
d[s] := 0
ENQUEUE(Q, s)
while (Q != Ø)
u := DEQUEUE(Q)
for each vertex v in Adj[u]
if (color[v] = WHITE)
color[v] := GRAY
d[v] := d[u] + 1
p[v] := u
ENQUEUE(Q, v)
else
if (color[v] = GRAY)
...
else
...
end for
color[u] := BLACK
end while
return (d, p)
我相信这是实现这一目标的最佳方式,但确实涉及我编写自己的bfs遍历算法,并在每个节点上存储节点的顺序(我希望避免的内存开销),以及编写我的拥有dfs访问者以查找订单并将其存储在缓存阶段的节点上。
我感到惊讶的是,现在还没有这样做的方法,因为在我看来,这是一种导航dag图的相当常见的方法......
答案 2 :(得分:0)
你不能用普通的图遍历算法做到这一点,因为你要求算法神奇地具有图形结构的知识,它不能在不违反自身要求的情况下遍历。您必须使用两遍方法,首先构建后向树,告诉您哪些节点与其他节点有连接,然后执行修改后的广度优先搜索,该搜索使用第一遍中的信息来适当地延迟遍历。我怀疑某些图形结构可能会使第二次传递死锁。
答案 3 :(得分:0)
首先进行拓扑排序,然后在排序图上进行深度优先搜索?
那会有用吗?
答案 4 :(得分:0)
任何DAG至少有一个叶节点。删除任何叶节点节点和所有传入的弧都会留下另一个DAG。递归地,这个较小的DAG还具有至少一个叶节点。通过以这种方式递归地移除所有节点,最终根节点变为叶节点。
如果现在反转删除节点的顺序,则会有一个具有所需属性的遍历顺序。通过最后访问叶节点,您可以保证首先看到所有父节点。