4

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

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

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

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

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

如果当前树没有变量,则评估它并用结果替换当前节点。

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

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

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

我怎样才能更有效地确定两个不同表达式的相等性(一个简单的例子是x+2and 2+x),有没有办法在没有大量 if 语句的情况下简化函数?

4

2 回答 2

0

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

  • 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

于 2014-08-22T00:02:57.023 回答
0

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

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

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

于 2015-12-13T20:02:35.347 回答