树或图表收缩

时间:2015-12-23 19:20:40

标签: python algorithm tree graph-reduction

我目前正在使用Python来解决“树摘要”问题。我的树由具有权重和子节点的节点组成。一个例子

Node(
    name: "Parent", weight: 20, children: {[
        Node(name: "Child 1" weight: 10, children: {[]},
        Node(name: "Child 2", weight: 10, children: {[
           Node(name: "Grandchild 1", weight: 5, children: {[]}
        ]}
     ]})

我有兴趣找到可通过边缘收缩获得的所有可能的图表。当我收缩两条边时,旧顶点被一个新顶点所取代,该顶点的权重是旧顶点的总和。例如,将Child 2与Grandchild 1签订合同会导致:

Node(
    name: "Parent", weight: 20, children: {[
        Node(name: "Child 1" weight: 10, children: {[]},
        Node(name: "(Child 2, Grandchild 1)", weight: 15, children: {[]}
     ]})

当然这只是一种可能的边缘收缩。即使对于这棵小树,也会有更多的收缩(例如(child 1, child 2)(child 1, parent)(child 2, parent))。

对于这些新树中的每一个,我需要再次找到通过收缩一个节点获得的所有树(最终,问题是将n节点树缩减为m节点树)。

我目前正在“暴力破解”,递归调用edge_contract()直到我到达正确节点大小的树。但是代码需要能够在中等大小的树上工作(~25-50个节点),而当前的实现不是。

这种类型的树木收缩是一个解决的问题。有什么好方法可以解决这个问题?

1 个答案:

答案 0 :(得分:1)

每次转换树时,您都要决定要收缩的边集。在您给出的示例中,该集合仅包含来自" Child 2"给孙子1"。

如果您有兴趣找到通过收缩边缘可以获得的所有树,那将是2 ^ d(其中d是原始树中边的总数)。 如您所说,您希望将n节点树转换为m节点树。如果你已经知道" m"那么你需要从具有m-1个元素的总共2 ^ d个集合中找到所有集合(因为m节点树将具有m-1个边缘)。

如果您只对m节点树的子集感兴趣,则随机选择您想要的数量。