Matlab加速嵌套for循环

时间:2011-06-18 22:22:28

标签: matlab

我有以下嵌套的for循环程序,它需要永远运行。是否有更好的方法(更有效)编码?

tic 
ndx = 0;
for i1 = 1 : 49 - 5
    for i2 = i1 + 1 : 49 - 4
        for i3 = i2 + 1 : 49 - 3
            for i4 = i3 + 1 : 49 - 2
                for i5 = i4 + 1 : 49 - 1
                    for i6 = i5 + 1 : 49 - 0
                        ndx = ndx +1;
                         number(ndx,1) = i1;
                         number(ndx,2) = i2;
                         number(ndx,3) = i3;
                         number(ndx,4) = i4;
                         number(ndx,5) = i5;
                         number(ndx,6) = i6;
                       %  display([int2str(number(ndx,1)), ' ',  int2str(number(ndx,2)), ...
                        %     ' ',  int2str(number(ndx,3)), ' ',  int2str(number(ndx,4)),...
                        %    ' ',  int2str(number(ndx,5)), ' ',  int2str(number(ndx,6)) ])
                    end
                end
            end
        end
    end
end
toc

1 个答案:

答案 0 :(得分:4)

这个答案是上述评论的摘要,如建议:

要在MATLAB中加速嵌套for循环,首先要考虑的事项包括: 数组/矩阵是否在循环内生长? 可以使用现有的MATLAB函数对整个计算进行矢量化吗?

第一个答案是肯定的,number在最里面的循环中一次增长一行。一旦第一个问题得到解决,第二个问题的答案就变得无关紧要了。

如果您在最里面的循环中仅使用ndx,而不是number分配上述代码,您会发现您将获得的总行数为13983816,并且这很快就算了。为了防止number在循环中增长,这需要相当昂贵的内存操作,您可以在代码之前使用: number = zeros(13983816,6);这将创建一个矩阵大小的double矩阵,但是只有0个条目。由于您知道所有条目都是1到49,因此数据类型不必是doubleuint8就足够了(对于0到255之间的值; HT:Amro)。

所以你的代码的第一行应该是:

number = zeros(13983816,6,'uint8');

然后执行整个代码只需几秒钟。

注意:关于上面的第二个问题,确实存在一个MATLAB函数来执行上面的代码所做的事情,即找到所有组合从49个中选择6个数字而不重复而不考虑订单(德国彩票?)但是它效率较低,因此仅适用于远小于49的nchoosek,对于两个标量输入,它计算元素的数量(即nchoosek(49,6)==13983816)和矢量(此处:{ {1}})和标量给出了一个包含实际组合的矩阵。