random choice of elements for n times, without choosing the same element more than once

4 ビュー (過去 30 日間)
Maria K
Maria K 2017 年 10 月 12 日
コメント済み: Maria K 2017 年 10 月 12 日
Hello! I am trying to randomly choose one element from a string for a predifined number of times but I don't know how I can avoid getting the same element more than once.. Beneath is the code I wrote (my question may be more comprehensible through the comment in the code).
%% ************************************ *******************************************
letters = 'ABCD';
ntrials = 3;
nletters = 4;
for i = 2: ntrials
for j = 1: nletters
*% it needs to display a random letter from letters but the same
% letter must NOT appear more than once in this nested loop.*
end
end
% ******************************* end of code ************************************************
output example: BCAD ADCB
Thanks a lot!

採用された回答

Jan
Jan 2017 年 10 月 12 日
編集済み: Jan 2017 年 10 月 12 日
Perhaps you mean:
for i = 2: ntrials
C = letters(randperm(length(letters), nletters))
end
Do you want to store the different outputs?

その他の回答 (3 件)

Cam Salzberger
Cam Salzberger 2017 年 10 月 12 日
Hello Maria,
There are typically two ways to do this in programming. One would be to remove each element from the original array as it is selected. The other would be to track the new elements, and see if one already exists before allowing the new selection. The former is faster in general, though the latter may be necessary if you have repeat elements in the input array, and don't want repeats in your output array.
If you don't have any repeats in the original array, you can do this quite easily in MATLAB. You use randperm to randomize the original array, then just pick the first n entries:
str = 'abcd';
newStr = str(randperm(numel(str)));
outStr = newStr(1:nletters);
Put that all inside the first loop, and you're good to go.
-Cam
  3 件のコメント
Cam Salzberger
Cam Salzberger 2017 年 10 月 12 日
Good point. I'll upvote your answer then, since it's more efficient, but leave mine here to help future searchers.
Thanks!
Jan
Jan 2017 年 10 月 12 日
And I upvote your answer, because it contains the better explanations.

サインインしてコメントする。


Maria K
Maria K 2017 年 10 月 12 日
編集済み: Maria K 2017 年 10 月 12 日
Hello again. Both the above replies give me the same result. Thanks for your time!! But I dont want to get all the letters of the string for every execution of the smaller loop, I just want * one* letter and it must be never the same. I think I need to know which letter it chose in the last instance of the (nested)loop so it will not be chosen again...
E.g. I get the output:
BACD
BDAC
DBAC
BCAD
ACBD
BDCA
ACBD
ACDB
What i really want is something like that:
B
D
A
C
A
C
B
D
  2 件のコメント
Image Analyst
Image Analyst 2017 年 10 月 12 日
Looks like a Latin Square. Are you wanting code to generate a Latin Square (used in statistical design of experiments)? https://en.wikipedia.org/wiki/Latin_square
James Tursa
James Tursa 2017 年 10 月 12 日
編集済み: James Tursa 2017 年 10 月 12 日
"... I just want one letter and it must be never the same ..."
But in your example above you do repeat the same letter. So what is it you really want? To cycle through all of the letters in a random fashion, and then start over? In that case, use the randperm( ) method that has already been suggested. Call randperm( ) once, use the letters from the result one-by-one until they are exhausted, then call it again etc.

サインインしてコメントする。


Maria K
Maria K 2017 年 10 月 12 日
編集済み: Maria K 2017 年 10 月 12 日
I am attaching the whole code the way I altered it even though it also uses psychtoolbox... I have 4 trials and in every trial I want to show a series of letters on the screen (e.g. 'ABCD') one by one (e.g. B then C then D then A), in random order ... In my nested for loop I cant avoid repetitions of some letters, for example in the 1st trial I might get : C then C then D then A, thus missing B and repeating C... The for loops go like this now:
for i = 1: ntrials
for j = 1: nLetters
msize = numel(p.letter);
a = p.letter(randperm(msize, 1)); %gets a random letter from p.letter= 'ABCD'
disp(a);
Screen( 'DrawText' , window, a, x1, y1,...
1);
t0 = Screen( 'Flip' , window, t0 + blankDur);% letter on
t0 = Screen( 'Flip' , window, t0 + stimDur);% letter off
end
end
Sorry for the post getting so long!!
  6 件のコメント
James Tursa
James Tursa 2017 年 10 月 12 日
編集済み: James Tursa 2017 年 10 月 12 日
My last response was intentionally posted as a comment since it was just tweaking your latest code. This site will not allow you to accept comments as answers. But my comment simply built upon the suggestions that were already made by others, who correctly had already pointed out that using randperm( ) was probably what you needed to use for your problem. If you look closely at the code I posted, it uses essentially the same basic logic as Cam's and Jan's posts. Hence my suggestion that you accept their answers.
Maria K
Maria K 2017 年 10 月 12 日
Anyway, again thank you for the clarification!

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeTiming and presenting 2D and 3D stimuli についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by