使用Boost Graph搜索DAG图表?

时间:2009-10-07 15:58:55

标签: c++ boost graph boost-graph

我需要搜索DAG图,但在看到所有其他指向链接的节点之前,我不想超越节点。

是否存在处理此特定情况的现有算法,深度优先搜索和呼吸优先搜索不适用于此遍历顺序。

即:

A -> B
B -> C
C -> D
A -> C

在看到B和C之前,我不想达到D.

5 个答案:

答案 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还具有至少一个叶节点。通过以这种方式递归地移除所有节点,最终根节点变为叶节点。

如果现在反转删除节点的顺序,则会有一个具有所需属性的遍历顺序。通过最后访问叶节点,您可以保证首先看到所有父节点。