You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求可自动优化表达式重复计算的工具(优先Python)

问题描述

假设有如下简单表达式:

c = ((a * b) / (x * y)) * sqrt(a * b + 1 + x * y)

计算机只需计算a * b和x * y各一次,但直接计算该表达式会让它们被重复计算两次。更优的写法是:

d = a * b
e = x * y
f = d / e
g = d + 1 + e
c = f * sqrt(g)

请问是否存在可将第一种代码块转化为第二种的函数(优先Python,其他语言也可)?我有一个从Mathematica Solve输出的超长表达式(长达数页),其中包含大量重复出现的唯一子项(远多于上述示例中的2个),手动优化不现实。此外,a * b这类子项后续可能用于计算其他量,我的应用对速度要求较高,此类优化十分必要。我曾尝试搜索相关功能,但可能未使用正确关键词。

可行解决方案
  • 使用SymPy的公共子表达式提取功能
    SymPy是Python的符号计算库,内置了提取公共子表达式(Common Subexpression Elimination, CSE)的工具,完全匹配你的需求。示例用法如下:

    from sympy import symbols, sqrt, cse, codegen
    
    # 定义符号变量
    a, b, x, y = symbols('a b x y')
    # 原表达式
    expr = ((a * b) / (x * y)) * sqrt(a * b + 1 + x * y)
    # 提取公共子表达式
    subexprs, simplified_expr = cse(expr)
    
    # 打印提取后的分步代码
    for var, subexpr in subexprs:
        print(f"{var} = {subexpr}")
    print(f"c = {simplified_expr[0]}")
    

    运行后会输出类似示例的分步赋值代码,还能通过codegen模块直接生成可执行的Python代码,适配超长表达式毫无压力。

  • 利用Mathematica自身的CSE功能
    既然表达式来自Mathematica,可直接用其内置的CSE函数处理,再导出为Python代码。比如在Mathematica中执行:

    expr = ((a*b)/(x*y))*Sqrt[a*b + 1 + x*y];
    CSE[expr]
    

    得到优化后的分步表达式后,再转换为Python代码即可,省去跨工具转换的额外麻烦。

  • 自定义提取逻辑(针对特定场景)
    如果你的表达式结构规则,也可以自行编写遍历逻辑,统计子表达式出现次数,将重复多次的子项替换为临时变量。但这种方法通用性不如前两种,适合处理特定格式的表达式。

内容的提问来源于stack exchange,提问作者Philliph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:20:29