【问题标题】:Big-O notation and optimizing function to include memoization?Big-O 符号和优化功能包括记忆?
【发布时间】:2012-07-27 03:55:15
【问题描述】:

我试图找到能被每个整数 1-20(含)整除的最小数。这只是我在以前做过的练习上试图改进。

我写了一个函数,它接受一个参数并返回可以被每个小于参数(包括它自己)的正整数整除的最小数字,但是它没有优化并且随着数字变大运行相对缓慢。

我想知道这个函数的 Big-O 符号是什么以及为什么。那么,如果有的话,有没有办法加快这个速度,也许我不确定记忆?

def divide_by_all(x):
    ## the 'pos' variable will be matched up against the argument to keep track of how many of the numbers in ##
    ## the arguments range are dividing evenly. ##
    pos = 0
    ## the 'count' variable will be set to equal the input argument, possibly
    count = x
    ## create the range of integers for the argument ##
    divs = [i for i in range(1,x + 1)]
    while pos != x:
        for i in divs:
            ## check if each 'i' in the divs list is evenly divisible ##
            ## if 'i' is not evenly divisible the 'count'(answer) is incremented, the 'pos' is set back to zero to show ##
            ## the next 'count' has no evenly divisible in numbers div yet, and then loop over the divs list starts again ##
            if count % i != 0:
                count += 1
                pos = 0
                break
            ## if 'i' is evenly divides into current 'count' increment 'pos' ##
            if count % i == 0:
                pos += 1
            ## if 'pos' == the argument 'x', meaning every number in range(x) is evenly divisible ##
            ## return 'count' ##
            if pos == x:
                return count

欢迎任何提示和建议!

【问题讨论】:

  • 第一个提示:你真的需要检查一个数字是否可以被从 1 到 X 的所有数字整除吗?比如从 1 到 20,是否需要检查这个数字是否可以被 20 整除?
  • 要更有效地执行此操作,您可能对prime factorization theorem 感兴趣。
  • @Zenzen ,我想出了一些解决方案,我会先检查一个数字是素数还是奇数。这就是我在想记忆化可能很有用,但是我不太熟悉使用这种技术。
  • 您可以做两件简单的事情来加快速度:1) 如果一个数可以被 20 整除,则不需要检查它是否可以被 2、4、5 和 10 整除。所以想办法划掉不需要测试的数字。 2)它需要被整除的最大数字是20。这意味着您不需要测试数字1..19、21..39。即您要测试的数字将是最大除数的倍数。
  • 记忆化是一件很酷的事情,但是从一开始,例如,如果您检查一个数字是否可以被 4 和 5 整除,您还需要检查它是否可以被 20 整除吗?这就是我的观点:) Dougal 的评论可能真的很有帮助。

标签: python optimization big-o memoization


【解决方案1】:

要对这个算法的渐近运行时间给出一个好的估计实际上并不容易。作为一个大概的估计,它可能略小于 n! (即非常慢)。问题很简单,答案随着 n 快速增长:它是小于 n 的素数的最高幂的乘积(对于 n=20,即 2^4 * 3^2 *5*7*11*13 *17*19=232792560)。当您检查所有数字直至答案时,您的运行时间显然比这更长(确定需要做多少工作)。

记忆在这里不相关,因为您的算法不是递归的。

基本上,这是一道数学题,而不是算法题。

【讨论】:

  • 我不认为递归是使用记忆技术的先决条件,按照我的理解,它只是通过使用查找表来避免冗余的重新计算。这也可以用于迭代实现。
  • @Levon:你是对的。显然,这里无关紧要,但记忆不仅限于避免冗余递归调用。
  • 按照上面的建议,考虑一下并使用prime factorization theorem
  • erm,19 是小于 20 的素数。它不适用于 5。2*3 = 6。6 不能被 4 整除,也不能被 5 整除。
  • @elssar 愚蠢的错误,感谢您指出。我相应地编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多