Mathematica中的尾递归优化

函数在内部执行过程中调用自身,叫做递归。如果函数执行的最后一步单纯地去调用自身,就称为尾递归。

实际上这个尾递归的概念在函数式编程思想中十分重要,因为会在编程中大量出现。

事实上以学习C或Java等非函数式语言入门的人,会觉得Mathematica的语法十分特别,感觉非常不习惯。但是如果你学过Lisp语言,你会发现,两者不仅语法相似,而且编程思想也十分吻合。

Mathematica是一种多范式的编程语言,它支持过程式编程,也支持函数式编程,其函数式编程思想及语法广泛借鉴了Lisp语言。

实际上在大多数学习资料(尤其是官方的演示项目)中,主要是采用了函数式编程范式,因为这样更能体现出Mathematica的代码简练及清晰的优势,也更符合数学思维。而Mathematica本质上是数学运算平台,使用Mathematica的人大多数也是用于数学相关的领域(尤其是符号计算)。

函数式编程必然会大量出现递归,通常递归会对性能造成极大影响,而尾递归则不会。

先看一个示例,如下是一个可求解斐波那契数的例子:

y[1] = 1;
y[2] = 1;
y[x_] := y[x - 1] + y[x - 2];

计算:

y[20]  (*输出 6765*)

但是当输入参数较大时,比如y[35],计算则会很慢。

将上面的例子改写成尾递归的形式,则执行效率很显著提升:

f[a_, b_, n_] := If[n == 0, b, f[b, a + b, n - 1]]

计算:

f[1, 0, 35]  (*输出 9227465*)

可以看到,几乎是瞬间计算出结果。

所有的循环都用递归实现,通过怎样的方式能够将普通的递归或者循环语句改写成尾递归形式,这是另外的一个话题。

可以参考如下文章:

http://www.ruanyifeng.com/blog/2015/04/tail-call.html

你可能感兴趣的:(递归,函数式编程,Mathematica,斐波那契数)