Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

提高 graph.py 中 binary_tree() 的效率 #80

Merged
merged 4 commits into from
Feb 19, 2021

Conversation

Sweetlemon68
Copy link
Contributor

生成二叉树时,每次需要随机选择一个节点作为父节点。这需要维护一个集合,支持加入元素和随机删除一个元素。

原代码中,使用 Python 的 set 维护这个集合,每次把 set 转换成 tuple 再用 random.choice() 选择元素,这样的复杂度是单次 O(n) 的,在生成较大的二叉树时无法承受。

为了优化这个复杂度,我尝试把它修改成 set.pop(),但这个方法返回的元素不是随机的。后来我参考 这个回答,用 list 实现了单次 O(1) 的复杂度,实测有一定的性能提升。

修改后通过了 unit_test.py 的单元测试(环境:Python 2.7.17, Python 3.6.9; Ubuntu 18.04)。

Use a list to choose node randomly in O(1), instead of converting the set into a tuple every time.
@tim1103
Copy link

tim1103 commented Jul 18, 2020

生成二叉树时,每次需要随机选择一个节点作为父节点。这需要维护一个集合,支持加入元素和随机删除一个元素。

原代码中,使用 Python 的 set 维护这个集合,每次把 set 转换成 tuple 再用 random.choice() 选择元素,这样的复杂度是单次 O(n) 的,在生成较大的二叉树时无法承受。

为了优化这个复杂度,我尝试把它修改成 set.pop(),但这个方法返回的元素不是随机的。后来我参考 这个回答,用 list 实现了单次 O(1) 的复杂度,实测有一定的性能提升。

修改后通过了 unit_test.py 的单元测试(环境:Python 2.7.17, Python 3.6.9; Ubuntu 18.04)。

python3性能提升不大明显?

@Sweetlemon68
Copy link
Contributor Author

生成二叉树时,每次需要随机选择一个节点作为父节点。这需要维护一个集合,支持加入元素和随机删除一个元素。
原代码中,使用 Python 的 set 维护这个集合,每次把 set 转换成 tuple 再用 random.choice() 选择元素,这样的复杂度是单次 O(n) 的,在生成较大的二叉树时无法承受。
为了优化这个复杂度,我尝试把它修改成 set.pop(),但这个方法返回的元素不是随机的。后来我参考 这个回答,用 list 实现了单次 O(1) 的复杂度,实测有一定的性能提升。
修改后通过了 unit_test.py 的单元测试(环境:Python 2.7.17, Python 3.6.9; Ubuntu 18.04)。

python3性能提升不大明显?

测试的是什么规模的数据呢?我当时测试时生成的二叉树的 n 是 1e5 级别的,用原来的方法生成,耗时完全无法承受

@kkksc03 kkksc03 merged commit 183d983 into luogu-dev:master Feb 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants