您可以预分配随机大小的数组吗?

时间:2018-10-14 17:41:17

标签: arrays matlab pre-allocation

有问题的代码的基本部分可以归纳为:

list=rand(1,x); % where x is some arbitrarily large integer
hitlist=[];
for n=1:1:x
    if rand(1) < list(n)
        hitlist=[hitlist n];
    end
end
list(hitlist)=[];

该程序运行非常缓慢,我怀疑这是为什么,但是我不知道如何修复它。 hitlist的长度必然会以随机方式变化,因此我不能简单地预分配适当大小的“零”。我曾考虑将hitlist设为zeros的长度,但随后我将不得不删除所有多余的零,而且我不知道如何解决这个问题。

如何预分配随机大小的数组?

1 个答案:

答案 0 :(得分:3)

我不确定是否要预分配“随机大小”,但是您可以按较大的块进行预分配,例如1e3,但对您的用例有用:

list=rand(1,x); % where x is some arbitrarily large integer
a = 1e3; % Increment of preallocation
hitlist=zeros(1,a);
k=1; % counter
for n=1:1:x
    if rand(1) < list(n)
        hitlist(k) = n;
        k=k+1;
    end
    if mod(k-1,a)==0 % if a has been reached
        hitlist = [hitlist zeros(1,a)]; % extend
    end
end
hitlist = hitlist(1:k-1); % trim excess
% hitlist(k:end) = []; % alternative trim, but might error
list(hitlist)=[];

这不会是最快的,但是至少比增加每次迭代快很多。确保选择a合适;您甚至可以使用memory以某种方式将其基于可用的RAM量,然后减少多余的部分,从而完全不必执行循环技巧。


顺便说一句:MATLAB的工作原理是列优先的,因此以这种方式运行矩阵更快。即首先是第一列,然后是第二列,依此类推。对于一维数组,这无关紧要,但对于矩阵而言,这无关紧要。因此,我更喜欢使用list = rand(x,1),即作为列。

对于这种特定情况,无论如何都不要使用这种循环方法,而要使用logical indexing

list = rand(x,1);
list = list(list<rand(size(list)));