【问题标题】:How can I justify and analyze code's running time, is it O(n)?我如何证明和分析代码的运行时间,是 O(n) 吗?
【发布时间】:2019-04-20 16:29:24
【问题描述】:

如何证明和分析递归调用代码的运行时间,是O(n)吗?

A = [10,8,7,6,5]
def Algorithm(A):
  ai = max(A)             # find largest integer
  i = A.index(ai)
  A[i] = 0
  aj = max(A)             # finding second largest integer 

  A[i] = abs(ai - aj)     # update A[i]
  j = A.index(aj)
  A[j] = 0                # replace the A[j] by 0
  if aj == 0:             # if second largest item equals
    return ai       # to zero return the largest integer
 return Algorithm(A)     # call Algorithm(A) with updated A

【问题讨论】:

  • 你能描述一下这个函数应该做什么吗?是对列表进行排序吗?它似乎比O(n) 更大,因为对max()index() 的调用都需要O(n) 时间。因此,如果此递归调用完成n 次,它将是O(n^2)

标签: python recursion time runtime time-complexity


【解决方案1】:

这是它的细分:

def Algorithm(A):
    ai = max(A)             # O(n)
    i = A.index(ai)         # O(n)
    A[i] = 0                # O(1)
    aj = max(A)             # O(n)

    A[i] = abs(ai - aj)     # O(1)
    j = A.index(aj)         # O(n)
    A[j] = 0                # O(1)
    if aj == 0:             # O(1)
        return ai           # O(1)
   return Algorithm(A)      # recursive call, called up to n times recursively

只要max(A) 不是0(即n 次),最后一次递归调用就会被调用,在最坏的情况下,如果所有都是肯定的。

所以,直到最后一行的所有内容都是O(n),最后一行使所有内容运行n次,所以它的总数是O(n^2)

【讨论】:

  • 但不是证明它在 O(n) 中的问题吗?为此,我们需要证明最后一次递归调用的频率与输入的大小无关。
  • +1 但是从我发布的分析来看,我认为您的说法是正确的 # recursive call, called up to n times recursively
【解决方案2】:

起初,我有点怀疑您的算法是否真的在 O(n) 中运行。还有下面的程序

import timeit, random
import matplotlib.pyplot as plt

code = """
def Algorithm(A):
    ai = max(A)             # find largest integer
    i = A.index(ai)
    A[i] = 0
    aj = max(A)             # finding second largest integer 

    A[i] = abs(ai - aj)     # update A[i]
    j = A.index(aj)
    A[j] = 0                # replace the A[j] by 0
    if aj == 0:             # if second largest item equals
        return ai       # to zero return the largest integer
    return Algorithm(A)     # call Algorithm(A) with updated A
Algorithm(%s)
"""

x, y = [], []
lst = [random.randint(-1000, 10000)]
for i in range(1000):
    lst.append(random.randint(-1000, 10000))
    time = timeit.timeit(stmt=code % lst, number=10)
    x.append(i)
    y.append(time)

plt.plot(x, y)
plt.show()

针对不同的随机生成列表测量算法的运行时间(并在之后绘制此图)。结果

显然支持非线性增长。所以说否则,因为该算法的复杂度为 O(n^2),因此无法证明它在 O(n) 内运行。

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 2019-11-21
    • 2016-12-23
    • 1970-01-01
    • 2017-08-13
    • 2011-05-13
    相关资源
    最近更新 更多