groovy fibonacchi蹦床和记忆
我正在尝试评估groovy fibonacchi蹦床和记忆,groovy,Groovy,我正在尝试评估10000000的fibonacchi序列 使用basic蹦床看起来是这样的 def rFibonacchi rFibonacchi = { BigInteger n, prev = 0, next = 1 -> (n < 2) ? prev : rFibonacchi.trampoline(n - 1, prev, next + prev) }.trampoline() 这是我的算法的问题吗?您的算法不会从使用记忆中获得任何好处。引用 me
10000000
的fibonacchi序列
使用basic蹦床
看起来是这样的
def rFibonacchi
rFibonacchi = {
BigInteger n, prev = 0, next = 1 ->
(n < 2) ? prev : rFibonacchi.trampoline(n - 1, prev, next + prev)
}.trampoline()
这是我的算法的问题吗?您的算法不会从使用记忆中获得任何好处。引用 memonization允许缓存闭包调用的结果。如果一个函数(闭包)的计算速度很慢,这是很有趣的,但是您知道这个函数将经常使用相同的参数调用。Fibonacci套件就是一个典型的例子。简单的实现可能如下所示:
def fib
fib = { long n -> n<2?n:fib(n-1)+fib(n-2) }
assert fib(15) == 610 // slow!
缓存使用参数的实际值工作
您使用的是改进的斐波那契算法。您的更具迭代性,它从不使用相同的参数调用两次mFibonacchi
。这会导致groovy缓存每次调用的结果,但从未实际使用此缓存,从而导致内存溢出。回忆录实际上是一个问题
您的算法相当于:
BigInteger fibonacchi(BigInteger n) {
BigInteger prev = 0, next = 1
for (; n > 2; n--) {
BigInteger temp = prev
prev = next
next = prev + temp
}
return prev
}
你的算法不会从使用记忆中得到任何好处。引用 memonization允许缓存闭包调用的结果。如果一个函数(闭包)的计算速度很慢,这是很有趣的,但是您知道这个函数将经常使用相同的参数调用。Fibonacci套件就是一个典型的例子。简单的实现可能如下所示:
def fib
fib = { long n -> n<2?n:fib(n-1)+fib(n-2) }
assert fib(15) == 610 // slow!
缓存使用参数的实际值工作
您使用的是改进的斐波那契算法。您的更具迭代性,它从不使用相同的参数调用两次mFibonacchi
。这会导致groovy缓存每次调用的结果,但从未实际使用此缓存,从而导致内存溢出。回忆录实际上是一个问题
您的算法相当于:
BigInteger fibonacchi(BigInteger n) {
BigInteger prev = 0, next = 1
for (; n > 2; n--) {
BigInteger temp = prev
prev = next
next = prev + temp
}
return prev
}
那么,为了使用缓存调用,是否有可能修复它呢?是的,但是您必须切换到递归版本的计算[e.F(n)=F(n-1)+F(n-2)],就像groovy网站上的示例和我上面的评论一样。我认为可以为fibonacchi组合蹦床和记忆。对于仅递归(尽管有StackOverflow错误),这太容易了。trampoline不允许
+
Woops。你说得对。我的错误。我删除了我的旧评论。我会想一想,但你所拥有的可能是最好的结合方式。记住你的方式的主要目的是快速地调用tFibonacchi。您可以添加注释以限制缓存的大小,但这无法达到此目的。因此,是否可以修复它以使用缓存调用?是的,但您必须切换到递归版本的计算[即F(n)=F(n-1)+F(n-2)]就像groovy网站上的例子和我上面的评论一样,我认为将蹦床和记忆结合起来是可能的。对于仅递归(尽管有StackOverflow错误),这太容易了。trampoline不允许+
Woops。你说得对。我的错误。我删除了我的旧评论。我会想一想,但你所拥有的可能是最好的结合方式。记住你的方式的主要目的是快速地调用tFibonacchi。您可以添加注释来限制缓存的大小,但这无法达到此目的。