2

問題のコードの重要な部分は、次のように要約できます。

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は必然的にランダムに変化するため、適切なサイズの「ゼロ」を単純に事前に割り当てることはできません。hitlistaをリストの長さにすることを考えましたzerosが、余分なゼロをすべて削除する必要があり、同じ問題を起こさずにそれを行う方法がわかりません。

ランダムなサイズの配列を事前に割り当てるにはどうすればよいですか?

4

1 に答える 1

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適切なものを選択してください。を使用して使用可能な RAM の量に基づいて、memory後で余分な部分をトリミングすることもできます。これにより、ループ内のトリックをまったく実行する必要がなくなります。


余談ですが、MATLAB は列優先で動作するため、その方法で行列を実行する方が高速です。つまり、最初に最初の列、次に 2 番目、というように続きます。1D 配列の場合、これは重要ではありませんが、行列の場合は重要です。したがって、私はlist = rand(x,1)、つまり列として使用することを好みます。

この特定のケースでは、とにかくこのループ アプローチを使用せず、論理インデックスを使用します。

list = rand(x,1);
list = list(list<rand(size(list)));
于 2018-10-14T18:11:16.113 に答える