1

我正在尝试实现一种方法,该方法返回表示表达式的导数的新树。我有原始表达式树,以及我可以使用的精确副本。我知道当节点是常数或数字时,我可以递归地使用微分规则和基本情况。但是我在思考如何存储新表达式时遇到了麻烦。

我不需要一个确切的答案,只需要一些关于如何存储新表达式的指导/建议?

图很有帮助,谢谢!我到了那里,但是仍然无法实现工作代码。

  if(this.getValue().equals("mult")){
        this.deepCopy().setValue("add");
        this.deepCopy().getRightChild().setValue("mult");
        this.deepCopy().getLeftChild().setValue("mult");
        // not sure what to recursively here!

        }
4

2 回答 2

0

显而易见的答案是使用一种专为对公式进行符号操作而设计的语言。提示:它开始于 1960 年之前,是四个字母的单词。

嘿,看看这个,这方面似乎有一些新技术:http ://www.autodiff.org/

http://www.cs.berkeley.edu/~fateman/papers/ADIL.pdf

于 2012-03-16T23:49:44.533 回答
0

基本上,您从原始树的根部开始向下工作,在必要时计算节点的导数。例如,由于 D fg = f'g+fg',对于乘法节点,您将输出乘积之和:

           ....                   ....
             \                      \
              *                      +
             / \           ->       / \
            F   G                  *   *
                                  / \ / \
                                 F' G F G'

你从哪里得到 F' 和 G'?这就是递归开始的地方。

更新:原则上你并不遥远,你只需要填写乘法的子树:

Node right = this.deepCopy().getRightChild();
Node left = this.deepCopy().getLeftChild();
right.setLeftChild(derivative(this.getLeftChild()))   // F'
right.setRightChild(this.getRightChild()))            // G
left.setLeftChild(this.getLeftChild())                // F
left.setRightChild(derivative(this.getRightChild()))) // G'

虽然我必须说 API 看起来有点奇怪。deepCopy总是返回相同的对象吗?它的名字暗示它每次都会制作一个新副本。

于 2012-03-17T00:26:10.113 回答