为什么我的嵌套for循环计算时间太长?

时间:2015-05-22 04:46:44

标签: algorithm matlab time big-o nested-loops

我有一个代码可以生成0到36之间4个整数的所有可能组合。

这将是37 ^ 4个数字= 1874161。

我的代码是用MATLAB编写的:

i=0;
for a = 0:36
    for b= 0:36
        for c = 0:36
            for d = 0:36
                i=i+1;
                combination(i,:) = [a,b,c,d];             
            end          
        end
    end
end

我已使用号码3代替号码36对此进行了测试,并且运行正常。

如果有1874161个组合,并且An过度警告猜测有100个时钟周期来进行添加并写入值,那么如果我有一个2.3GHz的PC,那就是:

1874161 *(1/2300000000)* 100 = 0.08148526086

几分之一秒。但它到目前为止已经运行了大约半个小时。

我确实收到combination changes size every loop iteration, consider predefining its size for speed的警告,但这不会影响它吗?

1 个答案:

答案 0 :(得分:7)

正如@horchler建议你需要预先分配目标数组

这是因为没有预分配,您的程序不是O(N^4)。每次向数组中添加新行时都需要调整大小,因此创建了更大的数组(因为matlab不知道它有多大的数组,它可能只增加1项)然后将旧数组复制到它中,最后旧数组被删除。因此,当你有10个数组并添加第11个项目时,则会在迭代中添加10个项目的复制...如果我没有弄错,那会导致类似O(N^12)更大的内容

  • 估算为(N^4)*(1+2+3+...+N^4)=((N^4)^3)/2

此外,重新分配过程的规模越来越大,违反CACHE障碍的速度越来越慢,而且每个CACHE规模障碍都会增加i

没有预分配的唯一解决方案是将结果存储在链接列表中

不确定Matlab是否有此选项,但每个项目需要一个/两个指针(32/64位值),这会使您的数组2+次更大。

如果您需要更快的速度,那么有很多方法(可能不适用于Matlab):

  1. 使用多线程进行数组填充是完全可并行的
  2. 使用内存块复制(rep movsd)或DMA数据定期重复
  3. 您还可以考虑在运行中计算i的值,而不是记住整个数组,具体取决于使用情况,在某些情况下可以更快...