如何找到以下程序的复杂性?

时间:2015-01-04 22:00:38

标签: python big-o code-complexity

所以我不是CS专业,并且很难回答有关程序大(O)复杂性的问题。

我编写了以下例程来输出数组中的数字对,总和为0:

asd=[-3,-2,-3,2,3,2,4,5,8,-8,9,10,-4]

def sum_zero(asd):
    for i in range(len(asd)):
        for j in range(i,len(asd)):
            if asd[i]+asd[j]==0:
                print asd[i],asd[j]

现在,如果有人问这个方法的复杂性,我知道,因为第一个循环会彻底解决所有n个项目(除非我错了),但有人可以解释如何找到正确的复杂性吗?

如果有更好的解决方法吗?

2 个答案:

答案 0 :(得分:3)

我不会给你一个完整的解决方案,但会尽力指导你。

你应该拿一支铅笔和一张纸,然后问问自己:

语句print asd[i], asd[j]执行了多少次? (在最坏的情况下,意味着你不应该真正关心那里的状况)
你会发现它真的取决于它上面的循环,它被执行len(asd)(用n表示)次。

你唯一需要知道的是,内部循环执行了多少次,外部循环有n次迭代? (i从0到n

如果您仍然不确定结果,只需采用真实的示例,比如n=20,并计算执行最低语句的次数,这会给你一个非常好的关于答案的说明。

答案 1 :(得分:1)

def sum_zero(asd):
    for i in range(len(asd)):       # len called once =  o(1), range called once = o(1)
        for j in range(i,len(asd)): # len called once per i times = O(n), range called once per i times = O(n)
            if asd[i]+asd[j]==0:    # asd[i] called twice per j =  o(2*n²) 
                                    # adding is called once per j =  O(n²)
                                    # comparing with 0 is called once per j = O(n²)

                print asd[i],asd[j] # asd[i] is called twice per j = O(2*n²)

sum_zero(asd) # called once, o(1)

假设最坏的情况(if-condition始终为真):

Total:
O(1) * 3
O(n) * 2
O(n²) * 6

O(6n² + 2n + 3) 

一个展示复杂性的简单程序:

target= []
quadraditc = []
linear = []
for x in xrange(1,100):
    linear.append(x)
    target.append(6*(x**2) + 2*x + 3)
    quadraditc.append(x**2)

import matplotlib.pyplot as plt
plt.plot(linear,label="Linear")
plt.plot(target,label="Target Function")
plt.plot(quadraditc,label="Quadratic")
plt.ylabel('Complexity')
plt.xlabel('Time')
plt.legend(loc=2)
plt.show()

Program Complexity

编辑:

正如@Micah Smith所指出的,上面的答案是最坏情况操作 Big-O实际上是O(n ^ 2),因为常数和低阶项被省略。