qml.transforms.intermediate_reps.preorder_traverse¶
- preorder_traverse(tree, source, source_parent=None)[source]¶
Pre-order traverse a tree graph, starting from (but excluding) the node
source.- Parameters:
tree (nx.Graph) – Tree graph to traverse. Must contain
source. Must containsource_parentif it is not None. Typing assumes integer-labeled nodes.source (int) – Node to start the traversal from
source_parent (Optional[int]) – Parent node of
sourceintree. Should not be provided manually but is used in recursion.
- Returns:
Pairs of nodes that constitute pre-order traversal of
treestarting atsource. Strictly speaking, the traversal is encoded in the first entry of each pair, and the second entry simply is the parent node for each first entry.- Return type:
list[tuple[int]]
A useful illustration of depth-first tree traversals can be found on Wikipedia.
Example
Consider the tree
(4) | (6) - (2) - (0) - (1) - (3) - (8) | | (7) (5)
and consider
(0)to be the source, or root, of the tree. We may construct this tree as anx.Graphby providing the edge data:>>> import networkx as nx >>> G = nx.Graph([(0, 1), (0, 2), (1, 3), (1, 4), (1, 5), (2, 6), (2, 7), (3, 8)])
As for every tree traversal, pre-order traversal results in a reordering of the nodes of the tree, with each node appearing exactly once. Pre-order traversing the graph means that for every node we reach, we first append the node itself to the ordering and then visit its child nodes (in standard sorting of the node labels/indices).
The pre-order traversal reads
[0, 1, 3, 8, 4, 5, 2, 6, 7]. For the output convention of this function, each node is accompanied by its parent node, because this is useful information needed down the line, and it is not easy to retrieve from thenx.Graphitself. In addition, the first entry, which always is the root of the tree provided via thesourceargument, is not included in the output.>>> traversal = qml.transforms.preorder_traverse(G, 0) >>> print(traversal) [(1, 0), (3, 1), (8, 3), (4, 1), (5, 1), (2, 0), (6, 2), (7, 2)] >>> expected = [1, 3, 8, 4, 5, 2, 6, 7] # Skipping leading root >>> all(child == exp for (child, parent), exp in zip(traversal, expected, strict=True)) True
To see how this comes about, start at the root
(0)and perform the following steps:Append
(0), the root.Visit the first child of
(0), which is(1), and append it.Visit the first child of
(1), which is(3), and append it.Visit the first and only child of
(3), which is(8), and append it.Visit the next child of
(1), which is(4), and append it.Visit the last child of
(1), which is(5), and append it.Visit the second and last child of
(0), which is(2), and append it.Visit the first child of
(2), which is(6), and append it.Visit the second and last child of
(2), which is(7), and append it.
Note that the
source_parentargument should not be provided when calling the function but is used for the internal recursive structure.