我有一个遍历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
但这不是...
答案 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);