about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/networkx/algorithms/tree/operations.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/networkx/algorithms/tree/operations.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-4a52a71956a8d46fcb7294ac71734504bb09bcc2.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/networkx/algorithms/tree/operations.py')
-rw-r--r--.venv/lib/python3.12/site-packages/networkx/algorithms/tree/operations.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/networkx/algorithms/tree/operations.py b/.venv/lib/python3.12/site-packages/networkx/algorithms/tree/operations.py
new file mode 100644
index 00000000..6c3e8394
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/networkx/algorithms/tree/operations.py
@@ -0,0 +1,105 @@
+"""Operations on trees."""
+
+from functools import partial
+from itertools import accumulate, chain
+
+import networkx as nx
+
+__all__ = ["join_trees"]
+
+
+# Argument types don't match dispatching, but allow manual selection of backend
+@nx._dispatchable(graphs=None, returns_graph=True)
+def join_trees(rooted_trees, *, label_attribute=None, first_label=0):
+    """Returns a new rooted tree made by joining `rooted_trees`
+
+    Constructs a new tree by joining each tree in `rooted_trees`.
+    A new root node is added and connected to each of the roots
+    of the input trees. While copying the nodes from the trees,
+    relabeling to integers occurs. If the `label_attribute` is provided,
+    the old node labels will be stored in the new tree under this attribute.
+
+    Parameters
+    ----------
+    rooted_trees : list
+        A list of pairs in which each left element is a NetworkX graph
+        object representing a tree and each right element is the root
+        node of that tree. The nodes of these trees will be relabeled to
+        integers.
+
+    label_attribute : str
+        If provided, the old node labels will be stored in the new tree
+        under this node attribute. If not provided, the original labels
+        of the nodes in the input trees are not stored.
+
+    first_label : int, optional (default=0)
+        Specifies the label for the new root node. If provided, the root node of the joined tree
+        will have this label. If not provided, the root node will default to a label of 0.
+
+    Returns
+    -------
+    NetworkX graph
+        The rooted tree resulting from joining the provided `rooted_trees`. The new tree has a root node
+        labeled as specified by `first_label` (defaulting to 0 if not provided). Subtrees from the input
+        `rooted_trees` are attached to this new root node. Each non-root node, if the `label_attribute`
+        is provided, has an attribute that indicates the original label of the node in the input tree.
+
+    Notes
+    -----
+    Trees are stored in NetworkX as NetworkX Graphs. There is no specific
+    enforcement of the fact that these are trees. Testing for each tree
+    can be done using :func:`networkx.is_tree`.
+
+    Graph, edge, and node attributes are propagated from the given
+    rooted trees to the created tree. If there are any overlapping graph
+    attributes, those from later trees will overwrite those from earlier
+    trees in the tuple of positional arguments.
+
+    Examples
+    --------
+    Join two full balanced binary trees of height *h* to get a full
+    balanced binary tree of depth *h* + 1::
+
+        >>> h = 4
+        >>> left = nx.balanced_tree(2, h)
+        >>> right = nx.balanced_tree(2, h)
+        >>> joined_tree = nx.join_trees([(left, 0), (right, 0)])
+        >>> nx.is_isomorphic(joined_tree, nx.balanced_tree(2, h + 1))
+        True
+
+    """
+    if not rooted_trees:
+        return nx.empty_graph(1)
+
+    # Unzip the zipped list of (tree, root) pairs.
+    trees, roots = zip(*rooted_trees)
+
+    # The join of the trees has the same type as the type of the first tree.
+    R = type(trees[0])()
+
+    lengths = (len(tree) for tree in trees[:-1])
+    first_labels = list(accumulate(lengths, initial=first_label + 1))
+
+    new_roots = []
+    for tree, root, first_node in zip(trees, roots, first_labels):
+        new_root = first_node + list(tree.nodes()).index(root)
+        new_roots.append(new_root)
+
+    # Relabel the nodes so that their union is the integers starting at first_label.
+    relabel = partial(
+        nx.convert_node_labels_to_integers, label_attribute=label_attribute
+    )
+    new_trees = [
+        relabel(tree, first_label=first_label)
+        for tree, first_label in zip(trees, first_labels)
+    ]
+
+    # Add all sets of nodes and edges, attributes
+    for tree in new_trees:
+        R.update(tree)
+
+    # Finally, join the subtrees at the root. We know first_label is unused by the way we relabeled the subtrees.
+    R.add_node(first_label)
+    R.add_edges_from((first_label, root) for root in new_roots)
+
+    return R