« "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