有向无环图的函数定义

时间:2015-02-20 20:10:02

标签: algorithm graph vertex directed-acyclic-graphs topological-sort

让我们考虑以下问题:对于有向非循环图G = (V,E),我们为每个顶点u定义函数“levels”,如l(u)所示:
1。 l(u)> =每个u的0 2。如果有从u到v(u - > v)的路径,则l(u)> l(v)
3. 对于每个顶点u,l(u)是满足条件1和2的最小整数。

问题是:
a。证明对于每个DAG,上述功能是唯一定义的,即它是唯一满足条件1,2和3的功能。
b。查找为每个顶点计算此函数的O(|V| + |E|)算法。

以下是基于拓扑排序的可能算法: 首先,我们找到G的转置,G^T,定义为G^T = (V,E^T),其中E^T={(u,v): (v,u) is in E}如果基于邻接列表实现,总共取O(|V|+|E|)(O(|V|)用于分配和sum for all v in V of |Adj[v]| = O(|E|))。拓扑排序需要Theta(|V|+|E|),因为它在列表中包含BFS和|V|插入,每个插入O(1)

TRANSPOSE(G){
    Allocate |V| list pointers for G^T i.e. (Adj'[])
    for(i = 1, i <= |V|, i++){
        for every vertex v in Adj[i]{
            add vertex i to Adj'[v]
        }
    }
}
L = TopSort(G)

2 个答案:

答案 0 :(得分:2)

  

一个。证明对于每个DAG,上述函数是唯一定义的,即它是满足条件1,2和3的唯一函数。

也许我错过了一些东西,但这对我来说似乎很明显:如果你把它定义为满足这些条件的最小值,那么怎么会有不止一个?

  

湾找到一个为每个顶点计算此函数的O(| V | + | E |)算法。

我认为你的拓扑排序是正确的(注意拓扑排序 是BFS),但它应该在转置图上执行(反转每个边的方向)。然后拓扑排序中的第一个值得到0,下一个得到1等。例如,对于转置图:

1   2   3
*-->*-->*
        ^
*-------|
1

我已经在拓扑排序中对节点进行了编号。您可以通过使用BFS实现拓扑排序来对节点进行编号。从FIFO队列中提取节点时,从所有可到达节点的indegree中减去1。当该indegree变为0时,在队列中插入它变为0的节点,并将其编号为exracted_node + 1.在我的示例中,编号为1的节点以indegree 0开头。然后,最底部的1从indegree中减去1标记为3的节点,但该indegree将为1,而不是零,因此我们不会将其插入队列中。我们插入2但是因为它的indegree将变为0。

<强>伪代码

G = G^t
Q = a FIFO queue
push all nodes with indegree 0 in Q
set l(v) = 0 for all nodes with indegree 0
indegree(v) = how many edges are going into node v
while not Q.Empty():
  x = Q.Pop()
  for all nodes v reachable from x:
    if indegree[v] > 0:
      indegree[v] = indegree[v] - 1
      if indegree[v] == 0:
        Q.Push(v)
        l[v] = l[x] + 1

您也可以使用DFS来计算递归返回后每个节点的值,如下所示:

value(v) = 1 + max{value(c), c a child of v}

请注意,DFS不在转置图上,因为我们让递归以拓扑排序顺序处理遍历。

答案 1 :(得分:1)

我们假设您的拓扑类型为G。然后您可以按相反的顺序考虑顶点:如果您有u -> v边缘,则v在排序前u之前。

如果您使用此订单循环节点,则如果没有传出边缘l(u) = 0,请l(u) = 1 + max(l(v), for each v such that there is an edge (u, v))。这是最佳的,并为您提供O(|V| + |E|)算法来解决此问题。

证明留作练习。 :d