[英]In numpy, most computationally efficient way to find the array with shortest non-zero sequence in array of arrays
[英]What is the most computationally efficient method to recursively calculate the Fibonacci sequence?
这是我目前的代码。
def fibonacci(n):
if n == 1:
return 1
elif n == 2:
return 1
else:
value = fibonacci(n - 1) + fibonacci(n - 2)
return value
这目前需要相当长的时间来计算大于n = 30的值。是否有更高计算效率的方法来实现这一目标?
添加值缓存以交换一些内存以减少处理时间可能是一种有用的方法。 纯递归程序将尝试反复计算值,但是这需要较长时间的值。 如果值没有改变,那么存储它们会很有帮助。 然而,重要的是要注意,如果值是易变的,则可能需要不同的方法。
fibonacci_value_cache = {}
def fibonacci(n):
if n == 1:
return 1
elif n == 2:
return 1
elif n in fibonacci_value_cache:
return fibonacci_value_cache[n]
else:
fibonacci_value_cache[n] = fibonacci(n - 1) + fibonacci(n - 2)
return fibonacci_value_cache[n]
n = 100
print("Fib " + str(n) + ": " + str(fibonacci(n)))
在这里,我们检查值是否在字典中,如果是,则返回它,否则我们计算它并将其添加到字典中。 这意味着我们不会多次计算相同的值,从而更好地利用处理器。
使用动态编程的思想,并存储中间结果以节省计算成本,它可以非常有效。 在笔记本电脑上,对于n=10000
,以下代码的成本低于0.02s
。
def fib(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
for i in range(n):
result.append(b)
a, b = b, a + b
return result
有一个装饰器的配方,它以您想要的为例。 它在PythonDecoratorLibrary中命名为Memoize 。
这似乎memoized
矫枉过正,但是让memoized
装饰器可以用于其他未来的任务。 也就是说,这是完整的(尽管我最后改变了print
):
import collections
import functools
class memoized(object):
'''Decorator. Caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned
(not reevaluated).
'''
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
if not isinstance(args, collections.Hashable):
# uncacheable. a list, for instance.
# better to not cache than blow up.
return self.func(*args)
if args in self.cache:
return self.cache[args]
else:
value = self.func(*args)
self.cache[args] = value
return value
def __repr__(self):
'''Return the function's docstring.'''
return self.func.__doc__
def __get__(self, obj, objtype):
'''Support instance methods.'''
return functools.partial(self.__call__, obj)
@memoized
def fibonacci(n):
"Return the nth fibonacci number."
if n in (0, 1):
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(12))
无需缓存/ memoization。 这是一个Python 3实现,它将Fibonacci序列表示为矩阵的幂,然后通过减半和平方来进行有效取幂。 结果是时间和存储中的O(log n)。
def matrix_fib(n):
if n == 1:
return [0,1]
else:
f = matrix_fib(n // 2)
c = f[0] * f[0] + f[1] * f[1]
d = f[1] * (f[1] + 2 * f[0])
return [c,d] if (n & 1) == 0 else [d,c+d]
def fib(n):
return n if n == 0 else matrix_fib(n)[1]
print(fib(1000000))
在我的笔记本电脑上,这会在超过半秒的时间内咳出百万分之一的斐波那契数值,其中大部分可能是大整数算术和输出格式化 - 结果非常大。 但是,您不必担心堆栈溢出。 调用堆栈深度仅为log2(1000000)= 20。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.