【问题标题】:Matlab speed up nested for loopsMatlab加速嵌套for循环
【发布时间】:2011-06-18 22:22:27
【问题描述】:

我有以下嵌套的 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

【问题讨论】:

  • 当然有。您可以像这样预分配numbersn=49;number=zeros((n-5)*(n-4)*(n-3)*(n-2)*(n-1)*n/(1*2*3*4*5*6),6);(另请参阅this question)。这将使您的评估速度提高几个数量级。要真正有效地实现你想要的,告诉我们你想要什么会更有帮助,而不是让我们猜测并只告诉你为了实现它做了什么。
  • @user804903:天哪!那是你到达那里的一组相当混乱的循环......如果你用文字解释(数学会更好)你正在尝试做什么,它可能会有所帮助。我认为这里没有人有时间涉足循环并遵循逻辑。
  • @arne.b:如果使用无符号整数,您甚至可以将空间需求减少八倍:number=zeros(13983816,6,'uint8');
  • @yoda:他想要的是nchoosek(1:n,6)(根据其文档,“仅适用于 N 小于约 15 的情况”)对于 n=49。 (我发现这是为了运行足够小的 n 的代码,而不是阅读它)。
  • @arne.b:一旦预先分配了矩阵,循环似乎相当快。整个事情只花了一秒钟多一点。您应该将其发布为答案。

标签: matlab


【解决方案1】:

按照建议,此答案是上述 cmets 的摘要:

要加快 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 的 n:nchoosek,它针对两个标量输入计算元素数(即 nchoosek(49,6)==13983816)和向量(此处为:1:49)和标量给出实际组合的矩阵。

【讨论】:

  • 谢谢大家!这真的帮助我完成了这项工作
猜你喜欢
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 2016-04-14
  • 2014-06-10
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多