>我试图找到曼德布洛特集合的简单实现的时间复杂度。 使用以下代码
int main(){
int rows, columns, iterations;
rows = 22;
columns = 72;
iterations = 28;
char matrix[max_rows][max_columns];
for(int r = 0; r < rows; ++r){
for(int c = 0; c < columns; ++c){
complex<float> z;
int itr = 0;
while(abs(z) < 2 && ++itr < iterations)
z = pow(z, 2) + decltype(z)((float)c * 2 / columns - 1.5,
(float)r * 2 / rows - 1);
matrix[r][c]=(itr== iterations ? '*' : '.');
}
}
现在查看上面的代码,我根据大 O 表示法对时间复杂度进行了一些估计,并想知道它是否正确
因此,我们正在创建一个通过嵌套循环遍历它的 2d 数组,并且在每个元素上我们执行一个操作并设置该元素的值,如果我们以 n 作为输入大小,我们可以说输入越大,复杂性就越大,因此 rowsxcolumns 的时间复杂度将是 O(rxc),然后我们再次遍历它以进行打印输出, 那么时间复杂度是多少?是O(rxc)+O(rxc)吗?当我们对行和列进行乘法和减法时,函数本身对时间复杂度有一定影响吗?如果是,那又如何呢?
几乎,给定r
行、c
列和i
迭代,则运行时间为O(r*c*i)
。这应该是微不足道的,看看abs(z)<2
是否不存在。但是有了这个额外的条件,不清楚内部while
循环总共会运行多少次。是的,它会少于r*c*i
倍,所以O(r*c*i)
仍然是上限。但也许我们可以做得更好。假设对于任何r,c
,您在同一域上以不同的分辨率计算曼德布洛特集,那么 while 循环将运行k*r*c*i
次,以实现一些常量k
介于曼德布罗特面积和 1 --> 代码的运行时间Θ(r*c*i)
,O(r*c*i)
无法改进。
如果您以固定分辨率计算[-c,c]x[-r,r]
域上的集合,那么对于任何|z|>2
,abs(z)<2
在第一次迭代后都会中断。然后O(r*c*i)
就不会受到严格限制,如果要准确估计,应考虑此条件(作为所有循环条件)。
请不要使用malloc
,std::vector
更安全。
在 big-O 表示法中,O(rxc)+O(rxc) 折叠为 O(rxc)。
由于最大迭代计数也是一个输入变量,因此它也会影响复杂性。特别是,内部循环最多运行 n 次迭代,因此,复杂度为 O(rxcxn)。
所有其他运算都是常数,特别是complex<float>
的乘法和加法。这些操作本身始终是 O(1),这不会增加整体复杂性。