【问题标题】:What is the algorithm to find the number of trees in a graph?查找图中树的数量的算法是什么?
【发布时间】:2021-10-16 03:08:33
【问题描述】:

给定一个节点列表,例如,

[1,2,3,4,5,6,7,8,9],

和一个元组列表来指示连接两个节点的非定向边,例如,

[(2,3), (2,7), (3,7), (4,3), (5,1), (5,6)],

我怎样才能找到不相交的树的数量?

一棵树是由至少一条边连接的一组音符,或者是一个不连接到任何其他节点的孤立节点。

在我的示例中,有 3 树是:

  1. {2,3,4,7}
  2. {1,5,6}
  3. {9}

我认为这是一个普通算法问题,所以这个问题很可能是重复的。但是我只是在网上找不到解决方案。也许我没有使用正确的术语进行搜索。

【问题讨论】:

  • 集团搜索
  • 您正在寻找已连接的components grpah。
  • @ravenspoint 这些例子似乎不是完整的图表。
  • 不确定,你对 tree 的理解是什么(也许你的意思只是连接的组件)但是{2,3,4,7} 不是一棵树,因为 3 和 7 各有两个父母,而 2 和 4 没有,这与我对 的理解相矛盾,而节点 8 呢,它本身就是一棵树。

标签: algorithm graph-algorithm


【解决方案1】:

根据您的描述,不相交的树不一定是。他们可能有周期。它们通常称为components

解决此问题的方法之一是使用Disjoint Set 的概念。

您的语言环境可能在本机或作为库实现了不相交集,但这里是 Python 中不相交集的实现:

# Implementation of Union-Find (Disjoint Set)
class Node:
    def __init__(self):
        self.parent = self
        self.rank = 0

    def find(self):
        if self.parent.parent != self.parent:
            self.parent = self.parent.find()
        return self.parent

    def union(self, other):
        node = self.find()
        other = other.find()
        if node == other:
            return True # was already in same set
        if node.rank > other.rank:
            node, other = other, node
        node.parent = other
        other.rank = max(other.rank, node.rank + 1)
        return False # was not in same set, but now is

所以以上是通用的,与您的图形问题没有特别关系。现在要将它用于您的图,我们为每个图节点创建一个Node 实例,并调用union 来指示连接的节点属于同一个图组件:

def count_components(nodeids, edges):
    # Create dictionary of nodes, keyed by their IDs
    nodes = {
        nodeid: Node() for nodeid in nodeids
    }
    # All connected nodes belong to the same disjoined set:
    for a, b in edges:
        nodes[a].union(nodes[b])
    # Count distinct roots to which each node links
    return len(set(node.find() for node in nodes.values()))

我们可以为您的示例图运行它,如下所示:

vertices = [1,2,3,4,5,6,7,8,9]
edges = [(2,3), (2,7), (3,7), (4,3), (5,1), (5,6)]
print(count_components(vertices, edges))  # 4

由于这些已识别的不相交集,因此打印 4:

{2,3,4,7}
{1,5,6}
{8}
{9}

【讨论】:

    【解决方案2】:

    【讨论】:

    • 这基本上是一个仅链接的答案(不是一件好事)。
    • 此外,第二个链接后面的内容仅供高级订阅者访问。
    猜你喜欢
    • 2011-12-17
    • 2020-05-13
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    相关资源
    最近更新 更多