首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >groovy fibonacchi弹床和memoize

groovy fibonacchi弹床和memoize
EN

Stack Overflow用户
提问于 2016-03-22 02:42:03
回答 1查看 206关注 0票数 0

我正在尝试评估10000000的fibonacchi序列。

使用基本的trampoline,它看起来像这样

代码语言:javascript
复制
def rFibonacchi
rFibonacchi = { 
    BigInteger n, prev = 0, next = 1 ->
        (n < 2) ? prev : rFibonacchi.trampoline(n - 1, prev, next + prev)
}.trampoline()

但是使用trampoline & memoize组合,我经常得到OutOfMemoryError

代码语言:javascript
复制
def tFibonacchi, mFibonacchi

mFibonacchi = { BigInteger n, prev, next ->
    n < 2 ? prev : tFibonacchi.trampoline(n - 1, next, prev + next)
}.memoize()

tFibonacchi = { BigInteger n, prev = 0, next = 1 ->
    mFibonacchi(n, next, prev)
}.trampoline()

tFibonacchi(10000000); // GC overhead limit exceed

是我的算法的问题吗?

EN

回答 1

Stack Overflow用户

发布于 2016-03-25 07:03:27

您的算法不会从使用memoization中获得任何奖励。引用the groovy docs on memoization:

Memoization允许缓存调用闭包的结果。如果一个函数(闭包)的计算速度很慢,这是很有趣的,但你知道这个函数会经常用相同的参数调用。一个典型的例子是Fibonacci套件。一个简单的实现可能如下所示:

定义fib ={ long n -> n<2?n:fib(n-1)+ fib (n-2) }断言fib(15) == 610 //慢!

这是一个天真的实现,因为'fib‘经常用相同的参数递归调用,导致一个指数算法:

  • computing fib(15)需要fib(14)fib(13)

的结果

  • 计算fib(14)需要fib(13)和fib的结果

由于调用是递归的,您已经可以看到我们将一次又一次地计算相同的值,尽管它们可以被缓存。这个简单的实现可以通过使用memoize缓存调用的结果来“修复”:

fib ={ long n -> n<2?n:fib(n-1)+fib(n-2) }.memoize() assert fib(25) == 75025 //快速!

缓存使用参数的实际值工作。

您正在使用一个改进的Fibonacci算法来实现上面的算法。您的方法更具迭代性,并且它不会使用所有相同的参数调用mFibonacchi两次。这会导致groovy缓存每次调用的结果,但实际上从未使用过这个缓存,这会导致内存溢出。记忆实际上是一个问题。

你的算法相当于:

代码语言:javascript
复制
BigInteger fibonacchi(BigInteger n) {
    BigInteger prev = 0, next = 1
    for (; n > 2; n--) {
        BigInteger temp = prev
        prev = next
        next = prev + temp
    }
    return prev
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36139115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档