简体   繁体   English

你如何计算连接图的数量?

[英]How do you calculate the number of connected graphs?

给定一个节点数组和一个边数组,如何计算连接图的数量?

  • Start at one of the node do the BFS or DFS to get all the nodes connected from this node. 从其中一个节点开始执行BFS或DFS以获取从该节点连接的所有节点。
  • Now iterate through the node list to find any node which is not included in already, 现在遍历节点列表以查找尚未包含的任何节点,
  • do the same procedure on the node. 在节点上执行相同的过程。 Repeat till all the nodes are visited. 重复,直到访问所有节点。
  • By now you will have all the graphs in your data. 到现在为止,您将拥有数据中的所有图表。

You can use a union find (you can search it up). 您可以使用联合查找(您可以搜索它)。 Start with all of the nodes as separate sets, then for each edge join the two nodes that the edge connects into the same set. 从所有节点开始作为单独的集合,然后为每个边缘连接边缘连接到同一集合的两个节点。 Then check how many different sets there are by going through all the nodes and finding how many different representatives there are. 然后通过遍历所有节点并查找有多少不同的代表来检查有多少不同的集合。

To elaborate on quasiverse's answer, here's a short pseudo code for it: 要详细说明quasiverse的答案,这里有一个简短的伪代码:

make_set(v) creates a new set whose only member is v. make_set(v)创建一个新集合,其唯一成员是v。

union(x, y) unites the two sets x and y. union(x,y)将两组x和y联合起来。 The representative element for the new set is chosen from one of the two sets 新集的代表性元素选自两组中的一组

get_representatve(v) returns the representative of the set the given node is a member of. get_representatve(v)返回给定节点所属集合的代表。

Find connected components in a graph G = (V, E): 在图表中查找连接的组件G =(V,E):

foreach vertex v in V:
    make_set(v)

foreach edge (u, v) in E:
    if get_representatve(u) != get_representatve:
         union(u, v)

Implementing the necessary functions is an exercise for the reader ;-) Anyway it'll work fine for undirected graphs, but if you want strongly connected components you should look at Tarjan's algorithm. 实现必要的功能是读者的练习;-)无论如何它对于无向图表都可以正常工作,但是如果你想要强连接组件,你应该看看Tarjan的算法。

For parallel implementations there exists afaik no work-efficient deterministic algorithm, but some interesting random ones. 对于并行实现,存在没有工作效率的确定性算法,但是存在一些有趣的随机算法。

Yes, there is an algorithm which is linear in the size of the graph, O(|V| + |E|). 是的,有一种算法在图的大小上是线性的,O(| V | + | E |)。

visited := the empty set
count := 0
for each vertex v in vertices:
    if v not in visited:
        count++
        add v and all nodes reachable from v to visited
return count

For undirected graphs, this can be done in O(n) time, with a simple DFS. 对于无向图,这可以在O(n)时间内完成,使用简单的DFS。 Here's how: 这是如何做:

Define explore as a procedure that finds all the nodes that can be reached from a given node. explore定义为查找可从给定节点到达的所有节点的过程。 This is just a recursive DFS-like procedure where at each node, you find all the children of that node and push them onto the stack. 这只是一个递归的类似DFS的过程,在每个节点上,您可以找到该节点的所有子节点并将它们推送到堆栈中。

To find the answer, start the DFS at any node and initiate the explore procedure on that node. 要查找答案,请在任何节点启动DFS并在该节点上启动explore过程。 Keep an integer(lets say cc ) and pass it to the explore procedure every time it is called. 保持一个整数(比方说cc )并在每次调用时将其传递给explore过程。 Also, keep a hashmap/dictionary or such that maps cc to the corresponding node. 另外,保留一个hashmap / dictionary或者将cc映射到相应的节点。 At each level of the explore procedure, map the current node to cc at the moment. explore过程的每个级别,此时将当前节点映射到cc Every time the explore procedure is called recursively, pass it the same value of cc . 每次以递归方式调用explore过程时,将相同的cc值传递给它。

Every time explore returns to the DFS loop, increment cc and pass that value the next time. 每次explore返回DFS循环时,增加cc并在下次传递该值。 Once you are done with the entire DFS, you will have a dictionary that maps each node to it's corresponding connected component number. 完成整个DFS后,您将拥有一个字典,将每个节点映射到相应的连接组件编号。 The value of cc at the end of this procedure can give you the number of connected components there are in the graph. 此过程结束时cc的值可以为您提供图表中连接组件的数量。

Here's the pseudo-code: 这是伪代码:

function explore(node, graph, cc, map){
    map(currentNode) = cc
    //find all children of current node, and push onto stack. 
    //mark current node as visited
    for i in stack:
        explore(i, graph, cc, map)
}

function DFS{
     int cc = -1
     for node in keysOfGraph:
          if not visited:
              cc++
              explore(node, graph, cc, map)

return cc
}

From Dasgupta Algorithms (section 3.2.3) 来自Dasgupta算法 (第3.2.3节)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM