遍历3D数组的算法复杂度

时间:2019-04-30 08:30:02

标签: arrays algorithm matrix time-complexity big-o

我有一个遍历3d数组的算法。对于数组中的每个值,我都会进行一些计算。我正在尝试找出算法的时间复杂度。就我而言,这不是一个完整的遍历,不考虑数组的某些值。

def process_matrix(k: int, V: int):
    import numpy as np
    sp_matrix = np.zeros((V, V, k))

    for e in range(k):
        for i in range(V):
            # Note that the range of index j decreases while index i is growing 
            for j in range(i, V):
                # Also the index a decreases acording to index i
                for a in range(i, V):

                    if (something):
                        sp_matrix[i][j][e] = set_some_value()

如您所见,我没有考虑每个索引e的值j

  

V *(1 + V)/ 2 * k

     
    

k->最外层循环

         
      

V *(1 + V)/ 2->对于第二和第三循环,我使用高斯公式来添加连续数字

    
  
     

通过一些近似,我认为这三个循环的复杂度是 O((((V ^ 2)/ 2)* k)

首先,我认为内循环以另一个(1 + V)/ 2促成 O 。结果为(V *(1 + V)/ 2 * k)*(1 + V)/ 2。但是后来我考虑了这种情况:
k = 1
V = 3
结果数组为:


        j=0  j=1  j=2
    i=0 | 3 | 3 | 3 |       
    i=1 | x | 2 | 2 | 
    i=2 | x | x | 1 |
    (the values in the matrix rapresents how many times the most inner loop.. loops)

总数是:3 + 3 + 3 + 2 + 2 + 1 = 14
我希望使用我的公式(V *(1 + V)/ 2 * k)*(1 + V)/ 2是相同的值,
(3 *(1 + 3)/ 2 * 1)*(1 + 3)/ 2 = 12
但这不是...

1 个答案:

答案 0 :(得分:0)

Big-O表示关于设置上限,而忽略常量因素。从这个意义上讲,考虑3个外部循环O(((V^2)/2)*k) = O(k * V^2),并且如果k是常数,则= O(V^2)

但是,如果您开始计算最里面的代码的执行次数,并将其与预期的执行次数进行比较,那么您将离开大O领域,因为常量因素不再被忽略。同样,对一条指令的执行进行计数虽然有用,但绝不如衡量实际性能那样精确(然而,这取决于实际的工作负载和对其进行测试的机器/环境)。

由于您的3个内环本质上是绘制四面体,因此您可以使用其公式获得复杂度的近似值:O(V ^ 3/3)。但是,如果您想获得准确的信息,我已经成功测试了以下JS代码:

let K=1, V=6, t=0;  // t is for counting totals; reset to 0 for each try
for (let k=0; k<K; k++)               // inside repeats K times
    for (let i=0; i<V; i++)           // inside repeats V*K times
        for (let j=i; j<V; j++)       // inside repeats (V+1)*(V) / 2 * K times
            for (let a=i; a<V; a++)   // inside repeats (V+1)*(V+.5)* V / 3 * K times
                console.log(k,i,j,a,++t, (V+1)*(V+.5)* V / 3 * K);