C++ 使用Boost图搜索DAG图?
我需要搜索一个DAG图,但我不想在看到所有其他有指向它的定向链接的节点之前先通过一个节点 是否有一个现有的算法来处理这种特殊情况,深度优先搜索和呼吸优先搜索不适用于这种遍历顺序 即:C++ 使用Boost图搜索DAG图?,c++,boost,graph,boost-graph,C++,Boost,Graph,Boost Graph,我需要搜索一个DAG图,但我不想在看到所有其他有指向它的定向链接的节点之前先通过一个节点 是否有一个现有的算法来处理这种特殊情况,深度优先搜索和呼吸优先搜索不适用于这种遍历顺序 即: 在看到B和C之前,我不想到达D。使用普通的图遍历算法无法做到这一点,因为您要求该算法神奇地掌握图形结构的知识,在不违反其自身要求的情况下无法遍历。您必须使用两次遍历的方法,首先构建反向树,告诉您哪些节点与哪些其他节点有连接,然后执行修改后的广度优先搜索,使用第一次遍历的信息适当地延迟遍历。我怀疑某些图结构可能会使第
在看到B和C之前,我不想到达D。使用普通的图遍历算法无法做到这一点,因为您要求该算法神奇地掌握图形结构的知识,在不违反其自身要求的情况下无法遍历。您必须使用两次遍历的方法,首先构建反向树,告诉您哪些节点与哪些其他节点有连接,然后执行修改后的广度优先搜索,使用第一次遍历的信息适当地延迟遍历。我怀疑某些图结构可能会使第二次遍历死锁。先进行拓扑排序,然后对排序后的图进行深度优先搜索怎么样
这行吗?任何DAG都至少有一个叶节点。删除任何叶节点和所有传入圆弧将留下另一个DAG。递归地,这个较小的DAG也至少有一个叶节点。通过以这种方式递归删除所有节点,最终根节点成为叶节点
如果现在颠倒移除节点的顺序,则具有具有所需属性的遍历顺序。通过最后访问叶节点,您可以保证首先看到所有父节点。因此,我最新的想法是,每当添加或删除边时,对整个图进行拓扑排序,并存储每个节点要遍历的直接子节点的顺序(这可能是一个需要编写的复杂算法) 然后我做了一个修改过的广度优先搜索(如chaos所建议的),并在下面的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图的方法…你要找的是Kahn(1962)的拓扑排序算法。这不是当前在BGL中实现的拓扑排序算法,该算法基于DFS,访问所有顶点,并以相反的拓扑顺序输出结果,而是非常类似于BFS,并以您在第一段中描述的方式访问顶点。您必须自己编写遍历,但算法很简单 请参阅拓扑排序Wikipedia条目中列出的第一个算法:。另请参阅Sedgewick的“C语言中的算法”中的程序19.8 提示1:使用辅助数据结构来维护每个顶点的入边数,不要实际执行“从图形中删除边”部分
提示2:对于一个正在工作的GPLV3'ed示例,您可以在我的CoFlo控制流图生成和分析项目中查看Kahn算法的实现,特别是这里的文件Topology_visit_Kahn.h:不要将DAG图带到ATM机上并使用PIN码,或者你可能会感染HIV病毒。我认为这必须是排序图上的广度优先搜索。谢谢,这也被称为拓扑排序,并且在Boost中实现得就像这样:)现在我如何从这个有序的节点列表开始,只搜索任何特定节点下游的节点(仍在使用此订单),最好不写我自己的遍历算法?你的意思是,当特定节点不是根节点时?看起来很简单:从拓扑上对整个DAG进行排序,并丢弃从特定节点无法访问的所有节点。其余节点是根在特定节点中的子图的遍历顺序。
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)