[英]How to count all reachable nodes in a directed graph?
There is a directed graph (which might contain cycles), and each node has a value on it, how could we get the sum of reachable value for each node.有一个有向图(可能包含循环),每个节点上都有一个值,我们如何获得每个节点的可达值的总和。 For example, in the following graph:
例如,在下图中:
the reachable sum for node 1 is: 2 + 3 + 4 + 5 + 6 + 7 = 27节点 1 的可达和为:2 + 3 + 4 + 5 + 6 + 7 = 27
the reachable sum for node 2 is: 4 + 5 + 6 + 7 = 22节点 2 的可达和为:4 + 5 + 6 + 7 = 22
..... .....
My solution: To get the sum for all nodes, I think the time complexity is O(n + m), the n is the number of nodes, and m stands for the number of edges.我的解决方案:要获得所有节点的总和,我认为时间复杂度为 O(n + m),n 是节点数,m 代表边数。 DFS should be used,for each node we should use a method recursively to find its sub node, and save the sum of sub node when finishing the calculation for it, so that in the future we don't need to calculate it again.
应该使用DFS,对于每个节点,我们应该递归地使用一种方法来找到它的子节点,并在为它完成计算时保存子节点的总和,以便以后我们不需要再次计算它。 A set is needed to be created for each node to avoid endless calculation caused by loop.
需要为每个节点创建一个集合,以避免循环导致无限计算。
Does it work?它有效吗? I don't think it is elegant enough, especially many sets have to be created.
我觉得它不够优雅,尤其是要创建很多集合。 Is there any better solution?
有没有更好的解决办法? Thanks.
谢谢。
This can be done by first finding Strongly Connected Components (SCC) , which can be done in O(|V|+|E|)
.这可以通过首先找到强连通分量 (SCC)来完成,这可以在
O(|V|+|E|)
。 Then, build a new graph, G'
, for the SCCs (each SCC is a node in the graph), where each node has value which is the sum of the nodes in that SCC.然后,为 SCC 构建一个新图
G'
(每个 SCC 是图中的一个节点),其中每个节点的值是该 SCC 中节点的总和。
Formally,正式地,
G' = (V',E')
Where V' = {U1, U2, ..., Uk | U_i is a SCC of the graph G}
E' = {(U_i,U_j) | there is node u_i in U_i and u_j in U_j such that (u_i,u_j) is in E }
Then, this graph (G') is a DAG, and the question becomes simpler, and seems to be a variant of question linked in comments .那么,这个图(G')是一个有向无环图,问题变得更简单了,似乎是在评论中链接的问题的变体。
EDIT previous answer (striked out) is a mistake from this point, editing with a new answer. EDIT previous answer (strike out) 从这一点来看是一个错误,用新答案编辑。 Sorry about that.
对此感到抱歉。
Now, a DFS can be used from each node to find the sum of values:现在,可以从每个节点使用 DFS 来查找值的总和:
DFS(v):
if v.visited:
return 0
if v is leaf:
return v.value
v.visited = true
return sum([DFS(u) for u in v.children])
A DP solution for this problem (DAG) can be:
此问题的 DP 解决方案 (DAG) 可以是:
D[i] = value(i) + sum {D[j] | (i,j) is an edge in G' }
This can be calculated in linear time (after
topological sort of the DAG).
这可以在线性时间内计算(在 DAG 的
拓扑排序之后)。
Pseudo code:
伪代码:
Total time is
O(|V|+|E|)
.
总时间为
O(|V|+|E|)
。
You can use DFS or BFS algorithms for solving Your problem.您可以使用DFS或BFS算法来解决您的问题。 Both have complexity
O(V + E)
两者都有复杂度
O(V + E)
You dont have to count all values for all nodes.您不必计算所有节点的所有值。 And you dont need recursion.
而且你不需要递归。 Just make something like this.
做这样的事情。
Typically DFS looks like this.通常 DFS 看起来像这样。
unmark all vertices
choose some starting vertex x
mark x
list L = x
while L nonempty
choose some vertex v from front of list
visit v
for each unmarked neighbor w
mark w
add it to end of list
In Your case You have to add some lines在您的情况下,您必须添加一些行
unmark all vertices
choose some starting vertex x
mark x
list L = x
float sum = 0
while L nonempty
choose some vertex v from front of list
visit v
sum += v->value
for each unmarked neighbor w
mark w
add it to end of list
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.