Esempio n. 1
0
def prune(G):
    """
    G: an instance of the Graph class
    return: a list of Graphs in which the first element is the trunk
            and the remaining elements are the trees.

    The exception is that if G was already a tree then we return
    it as the first and only component of the list.

    The treeSerialNo fields of the nodes in all non-trunk components will have
    been set, and the identifyRootNode method called on each, so their
    self.rootNode fields are already set to the root node of the tree.

    Note: it IS necessary to take all the nodes which are leaves at a given moment
    all together, and then take the next batch of leaves.
    If you just pick any leaf, one by one, then the root can wind up
    anywhere in the entire tree, and you don't actually find the "centre" node.
    """
    B = NodeBuckets(G)
    H = Graph()
    L = B.takeLeaves()
    while L:
        S = stemsFromLeaves(L)
        G.severNodes(L, buckets=B)
        if G.isEmpty():
            # This case only arises when G was a tree with a double centre
            # U--V. At this point we must have:
            #     S == [Stem(U,V), Stem(V,U)]
            # and we must only add one (doesn't matter which) of those stems
            # to H.
            S = S[:1]
        for stem in S:
            stem.addSelfToGraph(H)
        L = B.takeLeaves()
    C = H.connComps()
    for c in C:
        c.identifyRootNode()
    # G will now have 3 or more nodes iff it was
    # not in fact a tree, to begin with.
    if G.getNumNodes() >= 3:
        C.insert(0, G)
        # It will be helpful to let each root node in G know that it is a root node.
        for c in C[1:]:
            rp = c.rootNode
            r = G.nodes[rp.ID]
            r.isRootNode = True
    return C