Можете ли вы предварительно выделить массив случайного размера?

Основная часть кода, о которой идет речь, может быть преобразована в:

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 ответ

Я не уверен в предварительном распределении "случайного размера", но вы можете предварительно выделить большие куски, например 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 и обрезать излишки после этого, таким образом, вам вообще не нужно делать трюк в цикле.


В качестве отступления: MATLAB работает в столбцах-мажорах, поэтому работа с матрицами выполняется быстрее. Т.е. сначала первый столбец, потом второй и тд. Для одномерного массива это не имеет значения, но для матриц это имеет значение. Поэтому я предпочитаю использовать list = rand(x,1) то есть как столбец.

Для этого конкретного случая не используйте этот циклический подход в любом случае, но используйте логическое индексирование:

list = rand(x,1);
list = list(list<rand(size(list)));
Другие вопросы по тегам