【问题标题】:Find highest possible number under certain time span?在特定时间跨度内找到最大可能的数字?
【发布时间】:2017-06-18 12:43:40
【问题描述】:

对于 Python 3,是否有可能在特定时间跨度内的函数中找到可能的最高计算数? 例如,如果某件事几乎需要“永远”,有没有办法找出在 1 分钟内计算出的最大可能数字?

代码如下:

def fibonacci5(n):
f1, f2 = 1, 0               
while n > 0:
    f1, f2 = f1 + f2, f1     
    n -= 1
return f2

我正在尝试使用可能的解决方案来通过 timeit 查找需要 1 秒的数字。

repeats = 10
t = timeit.Timer("fibonacci5(500000)", globals=globals())
time = t.timeit(repeats)
print ("average execution time:", time/repeats)

但是 500.000 平均需要 2.6 秒,而 250.000 平均需要 0.6 秒 - 所以这个解决方案无法工作。

【问题讨论】:

  • 这完全取决于算法是什么。我们需要更多背景信息。
  • 这里是计算斐波那契数。
  • 好吧,斐波那契数列是无限的,所以任何曾经编写过的斐波那契函数都需要能够在序列结束之前停止。您是否查找过斐波那契函数的实现?
  • 至于在一分钟内尽可能多地计算广告:一旦你了解了如何停止序列,你就可以计算出你在一秒钟内可以进行多少次迭代,然后乘以 60,然后你有你的极限。或者计算每次迭代需要多长时间,然后将 60 除以该时间长度。
  • 如果您将其实现为生成中间值的生成器函数,您可以在检查已过去多少时间的同时迭代该函数。如果您将函数的代码添加到您的问题中,如果您不理解,我们可以告诉您如何操作。

标签: python python-3.x time max


【解决方案1】:

您可以在函数中添加一个计时器,使其在给定时间后停止:

from datetime import datetime, timedelta

max_runtime = timedelta(seconds=1)

def fibonacci5(n):

    stop_time = datetime.now() + max_runtime

    f1, f2 = 1, 0
    while n > 0:
        f1, f2 = f1 + f2, f1
        n -= 1
        if datetime.now() > stop_time:
            return f2, 'timelimit reached'
    return f2

请注意,如果它在时间用完时返回,它不仅会返回一个数字,还会返回一个包含数字和字符串'timelimit reached' 的元组。这样你就可以区分正常终止和超时(可能有更好的方法来处理......)。

这里需要注意的是if 行(至少只要您的ints 仍然非常小)可能是占用最多时间的函数行...结果将因此不能非常准确地代表实际的运行时间...

另请注意,有方法更有效的方法来计算斐波那契数。

【讨论】:

  • 在花费太长时间之前粗略估计您可以走多远非常有用。谢谢!
【解决方案2】:

如果我们像这样写斐波那契数列生成器

def fibonacci():
    a, b = 0, 1
    while True:
        yield b
        a, b = b, a + b

它看起来很幼稚,但运行速度足够快,例如如果您需要500000th 斐波那契数,我们可以使用itertools.islice

from itertools import islice

fibonacci_500000 = next(islice(fibonacci(), 500000, 500001))
print(fibonacci_500000)

在我的旧机器上花了大约 5 秒,输出太大而无法插入,但看起来像

47821988144175...more digits here...2756008390626

但如果您确实需要找出我们在一段时间后计算出的值 - 我们可以使用 timedeltadatetime 之类的对象

from datetime import datetime, timedelta


def fibonacci():
    a, b = 0, 1
    while True:
        yield b
        a, b = b, a + b


if __name__ == '__main__':
    duration = timedelta(seconds=5)
    fibonacci_numbers = fibonacci()
    stop = datetime.now() + duration
    for index, number in enumerate(fibonacci_numbers, start=1):
        if datetime.now() >= stop:
            break
    print(index)

这给了我们在大约 5 秒后计算出的505352th 斐波那契数(我们也可以打印 number,但它太长了)

【讨论】:

  • 问题是我不需要数字本身,我需要在计算时间太长之前找出最大值:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 2023-03-20
  • 2013-09-12
  • 1970-01-01
相关资源
最近更新 更多