幂函数图规模计算优化:支持大输入的BDD最大规模计算函数改进
你对进程被杀原因的判断不正确。核心原因并非运行耗时过长,而是代码中pow(2, pow(2, n-i+1))的计算触发了指数爆炸:当n-i+1 ≥ 5时,内层幂运算结果会超过32,此时你需要计算2的42亿次方甚至更大的数,这个数的十进制位数超过十亿位,无论是计算资源占用还是内存存储需求都会直接超出系统限制,导致进程被杀死。
优化思路
- 首先推导min项的大小阈值:我们可以提前判断
min(2^(i-1), 2^(2^(n-i+1)) - 2^(2^(n-i)))的取值规律,当n-i ≥3时,第二项的大小已经远大于n≤1000场景下的所有可能的第一项取值,此时min的结果永远是第一项2^(i-1)。 - 累加过程简化:前
n-4次循环的累加是首项为1、公比为2的等比数列,求和结果为2^(n-4) -1,不需要循环计算,直接代入公式即可得到结果。 - 仅需单独计算最后4次循环的min值:对应
i = n-3到i=n的4个取值,此时n-i ≤2,需要计算的幂运算最大值仅为2^(2^3) = 256,完全没有性能压力。
优化后代码
def max_size_BDD(n): size = 2 # 处理n<4的边界情况 if n < 4: for i in range(1, n+1): term1 = 2 ** (i-1) k = n - i term2 = (2 ** (2 ** (k+1))) - (2 ** (2 ** k)) add = min(term1, term2) size += add print(f"{i+1} // {size}") return size # 前n-4项等比数列求和 size += (2 ** (n-4) - 1) # 单独计算最后4项 for offset in range(4): i = n - 3 + offset term1 = 2 ** (i-1) k = n - i term2 = (2 ** (2 ** (k+1))) - (2 ** (2 ** k)) add = min(term1, term2) size += add print(f"{i+1} // {size}") return size
优化后可以支持n到数千甚至数万的输入,秒出结果,不会出现进程被杀死的问题。
内容的提问来源于stack exchange,提问作者Daniel Miedema
相关产品推荐
相关产品推荐

