【问题标题】:Creating a random tree?创建随机树?
【发布时间】:2013-01-30 10:56:11
【问题描述】:

创建随机树(或满足树属性的邻接矩阵)的好方法是什么?我目前有以下要返回的数据结构,但我想随机生成它。有什么建议?

    return [{
        Source: "A1",
        Target: "A2",
    }, {
        Source: "A2",
        Target: "A3",
    }, {
        Source: "A1",
        Target: "A4",
    }, {
        Source: "A4",
        Target: "A6",
    }, {
        Source: "A4",
        Target: "A7",
    }, {
        Source: "A3",
        Target: "A8",
    }, {
        Source: "A3",
        Target: "A5",
    }];

【问题讨论】:

  • 当你说随机......你的意思是平衡树吗?
  • @SajitKunnumkal:实际上,一切都很好。最好是有更多叶节点的东西,但除此之外我没有任何偏好。

标签: javascript python-3.x algorithm graph graph-theory


【解决方案1】:

根据上述想法,我们可以生成一个 20 节点标记的随机树(python):

  1. 从随机生成的长度为 18 的序列开始,每个元素都从集合 {1,2,...,20} 中选择。
  2. 使用生成的字符串作为 20 个顶点上完整图 K20 的生成树的 Prufer 序列,并使用以下算法(来自here)生成相应的标记树(因为始终存在 1-1 对应关系)。

下一个代码 sn-p 实现上述算法,在给定 prufer 序列的情况下生成标记树(通过计算边):

def get_tree(S):
    n = len(S)
    L = set(range(1, n+2+1))
    tree_edges = []
    for i in range(n):
        u, v = S[0], min(L - set(S))
        S.pop(0)
        L.remove(v)
        tree_edges.append((u,v))
    tree_edges.append((L.pop(), L.pop()))
    return tree_edges

现在,我们总是可以随机生成一个 prufer 序列(长度为 n-2),然后生成相应的生成树(在 n 个顶点上),它可以作为我们的随机树(可以认为是从Kn)的n^(n-2)个生成树的集合。

n = 20 # Kn with n vertices
N = 25 # generate 25 random trees with 20 vertices (as spanning trees of K20)
for i in range(N):
    S = np.random.choice(range(1,n+1), n-2, replace=True).tolist()
    T_E = get_tree(S) # the spanning tree corresponding to S
    # plot the tree generated (with `networkx`, e.g.,)

下一个动画展示了一些这样随机生成的带有 20 个节点的标记树。

【讨论】:

    【解决方案2】:

    一棵有n个节点的树可以用n-2个整数的序列唯一表示(范围为[0, n-1])。这称为Prüfer sequence

    创建一个随机序列应该没问题。然后你只需要将序列转换为你的树结构就可以了。

    【讨论】:

    • 谢谢!这正是我正在寻找的。我假设当您说creating a random sequence should be no problem 时,这只是一个随机整数数组,并且它们不需要遵循特定的约束。它是否正确?我的意思是如果有办法控制生成的树的深度。
    • 是的,序列没有进一步的限制(条目范围除外)。如果要控制深度,则需要定义树的深度。毕竟,您可以将任意节点设置为根节点。但除此之外,没有办法控制深度。
    • 太棒了!感谢您的宝贵时间。
    • 更正:Prufer 序列的数字必须在[1, n-1] 范围内
    • @AkshayLAradhya 不,n 必须包含在内。考虑树1 - 3 - 21 是最小的叶子,所以3 将被添加到 Prüfer 序列中。这个范围可能会根据我们使用从零开始的索引还是从一开始的索引而改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多