« "Make:"いいですね、とかつれづれ。 | 最新のページに戻る | VSS不参加となりました »

■ ランダムシャッフル関連

これまでpseudorandom sequenceが必要なときにはMATLABでrandpermを使っていたのだけれど、現在使用中の行動制御プログラム(C言語ライクでショボめな言語を持っている)でpseudorandom sequenceを作る必要が出てきたので探してたら、ちょうど結城氏のサイトでそのネタが扱われてました。

もとの話はたとえば1,2,3,,,,,9,10というsequenceがあったときにこれをかき混ぜてシャッフルしてやるときのアルゴリズムの問題です。わたしの場合はたとえば、条件Aと条件Bとがpseudorandomに混ざっているようにしたい、たとえば、n=10trialのブロックで8回条件Aが出て(p=0.8)、2回条件Bが出るようにして、その出現パターンには法則性がないようにしたい、というわけです。ですので、たとえば1,2,3,,,,,9,10の数列をシャッフルして作った数列のうち、1-8を条件Aに割り振って、9-10を条件Bに割り振ってやればいいわけです。

ということで、まずは結城氏のサイトにあった正しい例と良くない例とをMATLABで試しに作って確認してみました。

loopno=1000000;
data=1:10;
lengthdata=length(data);

%--正しくない例-----------------
randdata=zeros(loopno,lengthdata);randdata(:)=NaN;

tic;
for j=1:loopno

outdata=data;

for i=1:lengthdata

	% generate random number from [1 lengthdata]
	r=unidrnd(lengthdata);

	% swap outdata(i) with outdata(r)
	temp=outdata(i);
	outdata(i)=outdata(r);
	outdata(r)=temp;

end

randdata(j,:)=outdata;

end
toc;

histdata=zeros(lengthdata,lengthdata);histdata(:)=NaN;
for i=1:lengthdata
	histdata(i,:)=hist(randdata(:,i),data);
end

%--正しい例-----------------
randdata2=zeros(loopno,lengthdata);randdata(:)=NaN;

tic;
for j=1:loopno

outdata=data;

for i=1:lengthdata-1

	% generate random number from [i+1 lengthdata]
	r=i-1+unidrnd(lengthdata-i+1);

	% swap outdata(i) with outdata(r)
	temp=outdata(i);
	outdata(i)=outdata(r);
	outdata(r)=temp;

end

randdata2(j,:)=outdata;

end
toc;

histdata2=zeros(lengthdata,lengthdata);histdata2(:)=NaN;
for i=1:lengthdata
	histdata2(i,:)=hist(randdata2(:,i),data);
end

%--カラー表示でまとめ-----------------
mag1=min(histdata(:));
mag2=max(histdata(:));
cellmean=sum(histdata(:))/length(histdata(:));

figure
subplot(2,1,1)
imagesc(histdata, [mag1 mag2])
axis square
subplot(2,1,2)
imagesc(histdata2,[mag1 mag2])
axis square

お勧めエントリ


月別過去ログ