Generate a pseudo-random sequence of numbers with restrictions
2 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Michael
el 11 de Jul. de 2023
Comentada: Bruno Luong
el 11 de Jul. de 2023
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 comentarios
Ashutosh
el 11 de Jul. de 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.
Respuesta aceptada
Bruno Luong
el 11 de Jul. de 2023
Editada: Bruno Luong
el 11 de Jul. de 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 comentarios
Bruno Luong
el 11 de Jul. de 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)
Más respuestas (0)
Ver también
Categorías
Más información sobre Parallel Computing Fundamentals en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!