如何用SymPy实现考拉兹猜想(Collatz conjecture)步数计算函数?
实现基于SymPy的考拉兹猜想步数计算函数
你的纯Python版本能正常计算自然数的考拉兹步数,但直接传入SymPy Symbol会进入死循环——这是因为SymPy的抽象符号无法确定n%2==0的真假,导致while循环永远无法终止;而RecursiveSeq仅支持固定步长的线性递归,确实不适合考拉兹这种分支跳转的递归逻辑。
针对你的需求,我们可以结合递归+SymPy的数值判断/分段表达式来实现兼容自然数输入的SymPy版本函数,同时也能支持符号化定义:
实现代码
from sympy import sympify, Piecewise, Integer def collatz_sympy(n): n = sympify(n) # 基础终止条件:n=1时步数为0 if n == 1: return Integer(0) # 针对具体自然数,分奇偶递归计算 if n.is_even: return Integer(1) + collatz_sympy(n // 2) elif n.is_odd: return Integer(1) + collatz_sympy(3 * n + 1) # 针对符号变量,返回分段递归表达式 else: return Piecewise( (1 + collatz_sympy(n // 2), n % 2 == 0), (1 + collatz_sympy(3 * n + 1), n % 2 == 1) ) # 用sympy.Lambda包装(可选) from sympy import Lambda, symbols n_sym = symbols('n', integer=True, positive=True) collatz_lambda = Lambda(n_sym, collatz_sympy(n_sym))
使用示例
# 计算自然数27的步数,输出111,和纯Python版本一致 print(collatz_sympy(27)) # 用Lambda调用,结果相同 print(collatz_lambda(27))
关键说明
- 数值处理逻辑:对于具体的自然数(SymPy Integer类型),函数会通过递归分奇偶计算步数,和纯Python版本逻辑一致,但用SymPy的数值判断
is_even/is_odd确保符号兼容性。 - 符号处理逻辑:如果传入抽象符号,函数会返回
Piecewise定义的递归表达式——不过由于考拉兹猜想尚未被数学证明,SymPy无法直接对抽象符号求值得到具体步数,仅能返回表达式形式。 - 栈溢出注意:对于极大的自然数,递归可能触发栈溢出,此时可以将递归改写为循环形式,结合SymPy的数值判断即可:
def collatz_sympy_iter(n): n = sympify(n) step = Integer(0) while n != 1: if n.is_even: n = n // 2 else: n = 3 * n + 1 step += 1 return step
内容的提问来源于stack exchange,提问作者user1488065
相关产品推荐
相关产品推荐

