お世話になります。
2つの配列に入ったデータを別々にシャッフルして、2つの配列で異なる順序になるようにランダマイズしたいのですが、
2つの配列とも同じ順序でシャッフルされてしまい困っています。
解決法をご教示いただけますと幸いです。
背景を説明しますと、心理学実験で使うため、
画面の左右に1枚ずつ異なる写真をランダムに提示するプログラムを作成しています。
実験の流れは、各試行で、1.刺激呈示、2.反応入力、3.時間計測を行い、1.2.3.を任意の回数繰り返すものです。
1.刺激呈示では、画面の左右に異なる写真(お菓子や風景、人物など)を10枚ずつのリストのなかからランダムに提示させます。
(各刺激の呈示回数を同数にしたいため、実際にはランダムではなく、呈示順序をシャッフルしてランダマイズしたいです。)
そのために、
左に提示させる写真10枚を、PictureOfStimulusLArray[h]に
右に提示させる写真10枚を、PictureOfStimulusRArray[m]に番号で管理して、
後述するシャッフルのサブルーチンで、呈示順をランダマイズさせようと思っています。
刺激呈示のサブルーチンの中身は、以下のもので、PictureOfStimulusLArray[TrialCounter]で、各試行に設定された写真の番号を呼び出して呈示させることになっています。
Image1.Picture.Assign(nil);
Case PictureOfStimulusLArray[TrialCounter] of
0 : begin
ImageList1.Draw(Image1.Canvas,0,0,0); // 刺激に「中性0」を表示する
end;
1 : begin
ImageList1.Draw(Image1.Canvas,0,0,1); // 刺激に「中性1」を表示する
end;
刺激の呈示順をシャッフルさせるサブルーチンは以下のもので、左側の刺激の呈示順をシャッフルするサブルーチン(Procedure ShuffleLStimulus)と、右側の刺激の呈示をシャッフルするサブルーチン(Procedure ShuffleRStimulus)は、分けています。
しかし、左右の呈示順は同じになってしまい、目的通りに動いてくれません。
この2つのサブルーチンをどのようにしたら、目的通りに、左右で異なる順にシャッフルしてくれるか、ご教示ください。
以下に、シャッフルのサブルーチンと、刺激呈示順の結果を合わせて貼り付けておきます。
ーーーーー左右の刺激の呈示順をシャッフルするサブルーチンーーーーー
// 刺激をシャッフルする
// 左側をシャッフルする
Procedure ShuffleLStimulus;
Var h, j, k : Integer;
Begin
For h := NumberOfTrial Downto 2 do
Begin
Randomize;
j := Trunc(Random*h) + 1;
k := PictureOfStimulusLArray[h];
PictureOfStimulusLArray[h] := PictureOfStimulusLArray[j];
PictureOfStimulusLArray[j] := k;
k := PatternOfStimulusArray[h];
PatternOfStimulusArray[h] := PatternOfStimulusArray[j];
PatternOfStimulusArray[j] := k;
k := DirectionOfStimulusArray[h];
DirectionOfStimulusArray[h] := DirectionOfStimulusArray[j];
DirectionOfStimulusArray[j] := k;
End;
End;
// 右側をシャッフルする
Procedure ShuffleRStimulus;
Var m, n, o : Integer;
Begin
For m := NumberOfTrial Downto 2 do
Begin
Randomize;
n := Trunc(Random*m) + 1;
o := PictureOfStimulusRArray[m];
PictureOfStimulusRArray[m] := PictureOfStimulusRArray[n];
PictureOfStimulusRArray[n] := o;
End;
end;
ーーーーー実験実施の結果ーーーーー
実験条件
3
試行 反応時間 入力1:左、2:右 提示パターン 刺激の方向1:左、2:右 写真左 写真右 正誤-1:正解、0:誤り
1 1248.9155 1 0 1 5 5 -1
2 758.881 1 0 1 0 0 -1
3 498.7125 2 0 2 4 4 -1
4 639.5649 2 0 2 1 1 -1
5 629.5285 1 0 1 6 6 -1
6 615.6837 1 0 1 7 7 -1
7 579.0047 2 0 2 8 8 -1
8 578.2637 1 0 1 9 9 -1
9 694.1892 2 0 2 2 2 -1
10 598.8497 2 0 2 3 3 -1
RandomizeをShuffleLStimulusとShuffleRStimulusの中ではなく、外側で1回だけ呼ぶようにしてみたらどうでしょう?
https://docwiki.embarcadero.com/Libraries/Athens/ja/System.Randomize
> ループ内の Randomize 呼び出しと Random 関数の呼び出しを組み合わせないでください。通常,Randomize は,すべての Random の呼び出しの前に一度だけ呼び出されます。
公式にもループ内では呼ばないで下さいと書かれています
https://docwiki.embarcadero.com/Libraries/Athens/ja/System.Randomize
おそらく現在日時をシード値として初期化するのでループ内で使うとループが早すぎてシード値が変わらないのでしょう
HFUKUSHIさん vramさん
お世話になっております。
>RandomizeをShuffleLStimulusとShuffleRStimulusの中ではなく、外側で1回だけ呼ぶようにしてみたらどうでしょう?
>公式にもループ内では呼ばないで下さいと書かれています
ご教示の通りにしましたら、目的のように修正できました。
ありがとうございます。助かりました。
ツイート | ![]() |