【问题标题】:Implementing a basic mathematical expression simplifier实现一个基本的数学表达式简化器
【发布时间】:2014-04-28 22:28:05
【问题描述】:

我正在为我的 calc 类开发一个辅助项目,以区分 JavaScript 中的 y=x^2 等简单函数。为此,我将表达式解析为抽象语法树,然后硬编码衍生规则,如乘积规则和链规则。

唯一会用到的函数是 AP 微积分/第一年的微积分问题,所以三角、对数、指数都在起作用

我的程序很好地接受了导数,但我最终得到的是以一种荒谬的简单方式编写的函数。

例如,区分x^2 得到(2*(x^(2-1))),这在技术上是正确的,但可以更容易地写成 2*x。到目前为止,我有一个基本的简化器,它基本上重复分析树,并应用一些基本规则。

我的一般程序是用递归下降来分析它。

如果当前树没有变量,则对其求值并用结果替换当前节点。

否则,应用大量 if 语句来简化它。这包括诸如

之类的东西
  • 如果要乘以零,请将表达式替换为零
  • 如果要乘以 1,请将表达式替换为另一个操作数
  • 如果要提高到 0 的幂,请将表达式替换为 1。

等等等等。如果我真的想要进行任何真正的简化,比如组合类似的术语,这将很快失控。另外,如果我想确定任何两个表达式是否等价,我最好的解决方案是在函数的域中简单地生成随机数,看看它们是否相等。然而,这似乎不是很有效。

如何更有效地确定两个不同表达式的相等性(一个简单的例子是x+22+x),有没有一种方法可以在没有大量 if 语句的情况下简化函数?

【问题讨论】:

  • 我有一种感觉,确定两个表达式是否相等可能是世界上最困难的问题。如果你有一个高效的平等检查器,你不能插入are_equal(theory_I_want_to_prove, True),并证明/反驳你想要的任何理论吗?
  • 为了相等,我真正想要的是能够识别出术语乱序的东西,例如 2+x+x^2 和 x^2+2+x
  • @scrblnrd3 为什么不为 commutative operator 对变量进行排序的规则实现某种排序,例如按字母顺序,按指数,前面有标量
  • 您可以将 x/y 替换为 x*y^-1 并将 x-y 替换为 x + (-1)*y。那么你只需要担心时间和加号,你不需要除号和减号。

标签: javascript math derivative recursive-descent simplification


【解决方案1】:

我实际上正在开发一个使用二叉树的计算机代数系统。它有一个比较函数来确定两个表达式(树)在数学上是否相等,以便对它们进行因式分解。例如:

  • sin(x+1) + sin(1+x) = 2*sin(x+1)
  • sin(x-1) 和 sin(1-x) 不能相加
  • x + x^2 = x*(1+x)

算法是这样的:

每个节点都指定了一侧(左侧或右侧)。搜索树中的每个运算符,如果它是 + 或 * 子节点的边无关紧要。但如果运算符是 /、^ 或 - 子项的两侧很重要。在除法中,谁在分子中,谁在分母中。所以使用这个算法,x+2 将等于 2+x。

对不起我的英语不好:P

【讨论】:

    【解决方案2】:

    我将通过一系列步骤解决问题

    1. 以“规范”方式写入所有多项式节点
      • 例如,通过使用字典顺序和程度对其单项式进行排序(这样1 + x 始终表示为x + 1 等)
    2. 以“规范”方式写入所有有理节点
      • 有理表达式是两个多项式的商,因此您将在此处使用上面的 1。
    3. 拥有每个特定功能的身份列表
      • 例如ln(xy) = ln(x) + ln(y)
    4. 有一个减少注入的列表
      • 例如,sin x = sin y 当且仅当,x = y + 2*k*Pi 用于k 的某个整数值或ln(x) = ln(y) iff x = y 等。

    这些只是帮助您入门的一些想法。这个项目足够雄心勃勃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 2011-03-23
      • 2022-06-23
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多