我目前正在使用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个节点),而当前的实现不是。
这种类型的树木收缩是一个解决的问题。有什么好方法可以解决这个问题?
答案 0 :(得分:1)
每次转换树时,您都要决定要收缩的边集。在您给出的示例中,该集合仅包含来自" Child 2"给孙子1"。
如果您有兴趣找到通过收缩边缘可以获得的所有树,那将是2 ^ d(其中d是原始树中边的总数)。 如您所说,您希望将n节点树转换为m节点树。如果你已经知道" m"那么你需要从具有m-1个元素的总共2 ^ d个集合中找到所有集合(因为m节点树将具有m-1个边缘)。
如果您只对m节点树的子集感兴趣,则随机选择您想要的数量。