简体   繁体   English

如何计算有向图中所有可达的节点?

[英]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])
  • This is O(V^2 + VE) worst vase, but since the graph has less nodes, V and E are now significantly lower.这是 O(V^2 + VE) 最差的花瓶,但由于图中节点较少,因此 V 和 E 现在明显较低。
  • Some local optimizations can be made, for example, if a node has a single child, you can reuse the pre-calculated value and not apply DFS on the child again, since there is no fear of counting twice in this case.可以进行一些局部优化,例如,如果一个节点只有一个子节点,则可以重复使用预先计算的值,并且不再对子节点应用 DFS,因为在这种情况下不必担心计数两次。

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: 伪代码:

  1. Find SCCs 查找 SCC
  2. Build G' 建造 G'
  3. Topological sort G' 拓扑排序 G'
  4. Find D[i] for each node in G' 为 G' 中的每个节点查找 D[i]
  5. apply value for all node u_i in U_i, for each U_i. 为 U_i 中的所有节点 u_i 应用值,对于每个 U_i。

Total time is O(|V|+|E|) . 总时间为 O(|V|+|E|)

You can use DFS or BFS algorithms for solving Your problem.您可以使用DFSBFS算法来解决您的问题。 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.

相关问题 在有向图中查找所有其他节点均可访问的节点 - Find nodes in directed graph that is reachable from all other nodes 有向无环图中所有节点的可达性计数 - Reachability Count for all nodes in a Directed Acyclic Graph 如何检查图中的所有节点是否可以从所有其他节点访问? - How to check if all nodes in a graph are reachable from all other nodes? 有向图 - 如何计算图中每个其他顶点可到达的顶点数? - Directed Graph - How to count the number of vertices from which each other vertex in graph is reachable? 如何使用networkx删除有向图中的所有相关节点? - How to delete all related nodes in a directed graph using networkx? 在有向图中查找可到达的顶点 - Finding reachable vertices in directed graph 如何在没有无限循环的情况下找到 Neo4j 中有向图中连接到某些节点的所有节点? - How to find all nodes connected to certain nodes in a directed graph in Neo4j without infinite loops? 如何在有向图中找到彼此距离 k 的所有节点(探索图中的每条边)? - How to find all nodes distance k away from each other in directed graph (exploring every edge in a graph)? 如何在不遍历所有图(有向图)的情况下找到通向节点A的节点 - How to find the nodes that leads to node A without traversing all the graph (directed graph) 如何为有向图的节点分配连续的数字? - How to assign consecutive numbers to nodes of directed graph?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM