Generate a pseudo-random sequence of numbers with restrictions

조회 수: 2 (최근 30일)
Michael
Michael 2023년 7월 11일
댓글: Bruno Luong 2023년 7월 11일
Hello, I want to generate a random vector of numbers between 1 & 4 for use in a reaction time finger tapping task. The task uses the index and middle fingers of both hands (total, four fingers) and each finger has a designated button. The left-hand inputs to buttons 1 & 2, while the right-hand inputs to buttons 3 & 4. The vector must be 100 digits in length, contain no repeating elements (i.e., 1-1-2-1-1), and contain an equal number of inputs (25 presses per button). I am trying to pseudo-randomise the presentation of each button press, but limit repeating patterns such as 1-3-1-3-1-3 or 4-2-4-2-4-2 to a maximum of 4 elements (i.e., 1-3-1-3).
I have been attempting to do this using ‘while’ functions to iterate a sequence until it meets my criteria (below code as an example), but I am having no luck so far. Any help would be highly appreciated.
keys = [1 2 3 4]
randSeq = repmat(keys,1,25)
idx=randperm(100)
%Specify patterns to identify in vector
pat1 = [1 2 1 2 1]
while strfind(randSeq(idx), pat1) >1
any(diff(randSeq(idx))==0)
idx=randperm(100);
end
randSeq = randSeq(idx)
  댓글 수: 4
Ashutosh
Ashutosh 2023년 7월 11일
If the randomness of perms is good enough for you, this following code should do the job
k = 1:4;
mat = perms(k);
mat = reshape(mat',1,[]); % reshape transposed perms matrix into 1x96 matrix
rndm = [mat 1 2 3 4]; % append 4 more to make it 1x100, can be in any order
for i=4:96
if rndm(i) == rndm(i+1) % check for consecutive numbers
[rndm(i+1), rndm(i+2)] = deal(rndm(i+2),rndm(i+1)); % swap second number with number after
end
end
rndm
rndm = 1×100
4 3 2 1 4 3 1 2 4 2 3 1 4 2 1 3 4 1 3 2 4 1 2 3 4 3 2 1 3 4
'mat' has to be transposed before the reshape because reshape does the reshaping in a fashion that goes column by column. Credit to @KSSV for the perms idea.
Michael
Michael 2023년 7월 11일
Thank you both for your help so far! The problem is, there is an element of predictability here, as the base numbers (1 2 3 4) are simply repeated but in a slightly different order, meaning that every 4th button press can be predicted. Ideally, the sequence should go something like the following, but with each number represented 25 times within the string and without overt repeating patterns such as 1 2 1 2 1 2:
4 2 1 2 3 4 1 3 2 4 ...

댓글을 달려면 로그인하십시오.

채택된 답변

Bruno Luong
Bruno Luong 2023년 7월 11일
편집: Bruno Luong 2023년 7월 11일
Try this
succeed = false;
while ~succeed
c = repelem(25,1,4);
n = sum(c);
r = zeros(1,n);
for i=1:n
cn = c;
if i > 1
cn(x) = 0;
end
s = sum(cn);
succeed = s > 0;
if ~succeed
break
end
cn = cn / s;
cc = cumsum([0 cn]);
x = discretize(rand, cc);
r(i) = x;
c(x) = c(x)-1;
end
end
disp(r)
Columns 1 through 33 1 4 1 2 1 2 4 2 1 3 2 4 2 4 3 2 4 3 1 3 4 2 3 1 3 1 4 2 1 2 4 3 1 Columns 34 through 66 3 2 1 4 1 2 1 3 4 3 1 3 1 3 4 3 4 3 1 3 2 1 2 3 2 4 2 4 2 1 3 1 4 Columns 67 through 99 2 4 2 4 1 4 1 4 1 4 1 2 3 2 3 1 3 4 3 2 4 1 3 2 1 2 4 3 2 3 4 2 3 Column 100 4
% Check correctness
all(diff(r))
ans = logical
1
histc(r, 1:4)
ans = 1×4
25 25 25 25
You can add your check of pattern inthe while loop if you want.
The above just checks for non-repeated elements ans ensures there is 25 instances generated for each element from 1 to 4, which IMO is the hard part.
  댓글 수: 2
Michael
Michael 2023년 7월 11일
That’s it! Perfect, thank you! I will take some time to fully understand the code, but the end product appears to be exactly what we need. Thank you for your help, much appreciated.
Bruno Luong
Bruno Luong 2023년 7월 11일
A slighly shorter version
succeed = false;
while ~succeed
c = 25+zeros(1,4);
n = sum(c);
r = zeros(1,n);
x = [];
for i=1:n
cn = c;
cn(x) = 0;
cc = cumsum(cn);
s = cc(end);
succeed = s > 0;
if ~succeed
break
end
x = discretize(rand, [0 cc/s]);
r(i) = x;
c(x) = c(x)-1;
end
end
disp(r)
% Check correctness
all(diff(r))
histc(r, 1:4)

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Parallel Computing Fundamentals에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by