-
-
Notifications
You must be signed in to change notification settings - Fork 705
Description
Steps To Reproduce
- In any sage environment, run the following commands
%timeit OrderedTrees(1000).random_element().canonical_labelling()
%timeit OrderedTrees(10000).random_element().canonical_labelling()
%timeit OrderedTrees(100000).random_element().canonical_labelling()
- Compare the results
Expected Behavior
As we can go through the tree in linear time, we should be able to give canonical labeling (in this case, prefix labeling) in linear time. This is particularly useful for manipulating very large trees for random generation.
Actual Behavior
It seems that the runtime does not grow linearly. Here is the result on my machine for n=1000, 10000, 100000:
49.2 ms ± 2.96 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
1.3 s ± 358 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
38.3 s ± 9.66 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
Additional Information
It is because in AbstractTree.canonical_labelling(), the code does a sort of BFS and uses node_number() to compute the shift for the label of the roots of subtrees of the current tree. However, node_number() is implemented in a linear fashion (no extra field to store the number of nodes), so the combined complexity is much higher than linear (on average).
There are two solutions that I can think of. One is to get a field in AbstractTree to record the number of nodes and compute them on the fly using the information on subtrees. The other (what I used in my own code) is to simply do a DFS and put the labels accordingly. Here is the code, which is minimally written adapted to my own situation:
@staticmethod
def __canon_label(tree):
r'''
Internal function. Use a recursive approach to compute the canonical
labeling of a tree without using node_number, which is very costly.
More precisely, it is quadratic.
'''
def aux(tree, curl):
l = curl[0]
curl[0] += 1
return LabelledOrderedTree([aux(x, curl) for x in list(tree)],
label=l)
return aux(tree, [1])Environment
- **OS**: Ubuntu 22.04
- **Sage Version**: 9.5Checklist
- I have searched the existing issues for a bug report that matches the one I want to file, without success.
- I have read the documentation and troubleshoot guide