Generate a pseudo-random sequence of numbers with restrictions
2 views (last 30 days)
Show older comments
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 Comments
Ashutosh
on 11 Jul 2023
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
'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.
Accepted Answer
Bruno Luong
on 11 Jul 2023
Edited: Bruno Luong
on 11 Jul 2023
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)
% Check correctness
all(diff(r))
histc(r, 1:4)
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 Comments
Bruno Luong
on 11 Jul 2023
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)
More Answers (0)
See Also
Categories
Find more on Parallel Computing Fundamentals in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!