我有以下嵌套的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
答案 0 :(得分:4)
这个答案是上述评论的摘要,如建议:
要在MATLAB中加速嵌套for
循环,首先要考虑的事项包括:
数组/矩阵是否在循环内生长?
可以使用现有的MATLAB函数对整个计算进行矢量化吗?
第一个答案是肯定的,number
在最里面的循环中一次增长一行。一旦第一个问题得到解决,第二个问题的答案就变得无关紧要了。
如果您在最里面的循环中仅使用ndx
,而不是number
分配上述代码,您会发现您将获得的总行数为13983816,并且这很快就算了。为了防止number
在循环中增长,这需要相当昂贵的内存操作,您可以在代码之前使用:
number = zeros(13983816,6);
这将创建一个矩阵大小的double
矩阵,但是只有0
个条目。由于您知道所有条目都是1到49,因此数据类型不必是double
,uint8
就足够了(对于0到255之间的值; HT:Amro)。
所以你的代码的第一行应该是:
number = zeros(13983816,6,'uint8');
然后执行整个代码只需几秒钟。
注意:关于上面的第二个问题,确实存在一个MATLAB函数来执行上面的代码所做的事情,即找到所有组合从49个中选择6个数字而不重复而不考虑订单(德国彩票?)但是它效率较低,因此仅适用于远小于49的nchoosek
,对于两个标量输入,它计算元素的数量(即nchoosek(49,6)==13983816
)和矢量(此处:{ {1}})和标量给出了一个包含实际组合的矩阵。