pseudorandom sequence without consecutively repeating numbers

Hi everybody,
I'm struggling with the sequence of my trials. In one block I have to present 4 images 30 times (tot number of trials 120).  I want to randomly shuffle my images vector without repeating images, given that each images is repeated equally.  Moreover  I have a second condition that can  be 1 or 0 and I need that each image has the same number of 0 and 1. More specifically, I would like to repeat the matrix [1 2 3 4 1 2 3 4 ;1 1 1 1 0 0 0 0]times, so that 1, 2, 3 and 4 would all repeat 30 times without being consecutive.
Example :
cond_a = [1 2 3 4];
cond_b = [1 0];
ntrial = 15;
trial = CombVec(cond_a,cond_b)';

trial = repmat(trial,ntrial,1);
trial_shuffle=Shuffle(trial,2);

%Right pseudorandom
     1     1
     2     0
     3     1
     4     0
     1     0
     2     0
     1     1
     4     0
     3     1
     4     1
     3     0
     2     1
     1     0
     4     0
     3     1
     2     1

%wrong pseudorandom
     1     1
     2     0
     3     1
     4     0
     1     0
     2     0
     1     1
     4     0
     4     1
     4     1

     3     0
     2     1
     1     0
     3     0
     3     1

     2     1
Many thanks for any suggestions..
Alice





Mail priva di virus. www.avast.com
randomising with sequencing constraints is not something that you can do with a deterministic algorithm. unless i am mistaken, generating those kind of sequences always involves some trial and error. in other words, you need to write a function that randomly chooses items to add to a trial list, with the possibility that the sequence may not be valid, and may need to be discarded.

the simplest brute force way of doing this is to generate a full sequence and then verify it afterwards. this is inelegant but may be feasible if your constraints are not too strict.

past a certain constraint level, the simplest brute force method may be computationally too expensive and you may need to think of a more intelligent algorithm. for example, your algorithm might select items from a set of candidates that reduces as the building of the trial list progresses. at some point this sequence might fail, and need to be discarded, but it will be more likely to succeed than the simplest brute force method...


---In PSYCHTOOLBOX@yahoogroups.com, <alice.bollini@...> wrote :

Hi everybody,
I'm struggling with the sequence of my trials. In one block I have to present 4 images 30 times (tot number of trials 120).  I want to randomly shuffle my images vector without repeating images, given that each images is repeated equally.  Moreover  I have a second condition that can  be 1 or 0 and I need that each image has the same number of 0 and 1. More specifically, I would like to repeat the matrix [1 2 3 4 1 2 3 4 ;1 1 1 1 0 0 0 0]times, so that 1, 2, 3 and 4 would all repeat 30 times without being consecutive.
Example :
cond_a = [1 2 3 4];
cond_b = [1 0];
ntrial = 15;
trial = CombVec(cond_a,cond_b)';

trial = repmat(trial,ntrial,1);
trial_shuffle=Shuffle(trial,2);

%Right pseudorandom
     1     1
     2     0
     3     1
     4     0
     1     0
     2     0
     1     1
     4     0
     3     1
     4     1
     3     0
     2     1
     1     0
     4     0
     3     1
     2     1

%wrong pseudorandom
     1     1
     2     0
     3     1
     4     0
     1     0
     2     0
     1     1
     4     0
     4     1
     4     1

     3     0
     2     1
     1     0
     3     0
     3     1

     2     1
Many thanks for any suggestions..
Alice





Mail priva di virus. www.avast.com
What i do for this is simple:
for nTrial times:
- shuffle your sequence of 8 randomly
- verify it is ok
- check that first of this is not same as last of what is in output vector
- if both ok add to output vector, go to next.

Shuffling all at once will of course work too, this gives me some more flexibility. Also makes images very regularly distributed along the whole run, in case that matters.

Cheers,
Dee

On Tue, Oct 10, 2017 at 1:28 AM, microfish@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:


randomising with sequencing constraints is not something that you can do with a deterministic algorithm. unless i am mistaken, generating those kind of sequences always involves some trial and error. in other words, you need to write a function that randomly chooses items to add to a trial list, with the possibility that the sequence may not be valid, and may need to be discarded.

the simplest brute force way of doing this is to generate a full sequence and then verify it afterwards. this is inelegant but may be feasible if your constraints are not too strict.

past a certain constraint level, the simplest brute force method may be computationally too expensive and you may need to think of a more intelligent algorithm. for example, your algorithm might select items from a set of candidates that reduces as the building of the trial list progresses. at some point this sequence might fail, and need to be discarded, but it will be more likely to succeed than the simplest brute force method...


---In PSYCHTOOLBOX@yahoogroups.com, <alice.bollini@...> wrote :


Hi everybody,
I'm struggling with the sequence of my trials. In one block I have to present 4 images 30 times (tot number of trials 120). I want to randomly shuffle my images vector without repeating images, given that each images is repeated equally. Moreover I have a second condition that can be 1 or 0 and I need that each image has the same number of 0 and 1. More specifically, I would like to repeat the matrix [1 2 3 4 1 2 3 4 ;1 1 1 1 0 0 0 0]times, so that 1, 2, 3 and 4 would all repeat 30 times without being consecutive.
Example :
cond_a = [1 2 3 4];
cond_b = [1 0];
ntrial = 15;
trial = CombVec(cond_a,cond_b)';

trial = repmat(trial,ntrial,1);
trial_shuffle=Shuffle(trial,2) ;

%Right pseudorandom
1 1
2 0
3 1
4 0
1 0
2 0
1 1
4 0
3 1
4 1
3 0
2 1
1 0
4 0
3 1
2 1

%wrong pseudorandom
1 1
2 0
3 1
4 0
1 0
2 0
1 1
4 0
4 1
4 1

3 0
2 1
1 0
3 0
3 1

2 1
Many thanks for any suggestions..
Alice





Mail priva di virus. www.avast.com



'Diederick C. Niehorster' dcnieho@... [PSYCHTOOLBOX] wrote on 10.10.2017 3:17:
> What i do for this is simple:
> for nTrial times:
> - shuffle your sequence of 8 randomly
> - verify it is ok
> - check that first of this is not same as last of what is in output vector
> - if both ok add to output vector, go to next.
>
> Shuffling all at once will of course work too, this gives me some more flexibility. Also makes images very regularly distributed along the whole run, in case that matters.
>
> Cheers,
> Dee

Yes, that is also how I do it. Obviously, the chunk size can be multiples of the number of different trial conditions, but it needs to be small enough for being computationally feasible. Shuffling all at once wouldn't work in this particular case, as you just have to wait too long for a solution. Plus, it makes the distribution actually less regular (although more random), which can be seen as a downside of shuffling it all at once. If the chosen chunk size is still too high (or the constraint is too complex - e.g., one could also ask for not getting more than four '0's or '1's in a row, in addition), one can build the trial list one-by-one, which is still trial and error at some point, but runs way faster. I am not absolutely sure though in how far this iterative one-by-one approach results in a list that is as random as one generated with the brute-force approach.

Here some code to play with:

function TestTrialRandimization
clear all
chunk = repmat(1:4,1,10);
chunkLen = length(chunk);
for i=1:100
tic
trialList = [];
for j=1:3
if 1
%--- Chunk-wise randomization.
while 1
chunk = chunk(randperm(chunkLen));
if all(diff(chunk)~=0) && (j==1 || chunk(1)~=trialList(end))
break
end
end
else
%--- Trial-wise randomization (within chunk).
if j==1
k = randi(chunkLen);
else
kk = find(chunk~=trialList(end));
k = kk(randi(length(kk)));
end
chunk([1,k]) = chunk([k,1]);
while 1
for m=2:length(chunk)
kk = find(chunk(m:end)~=chunk(m-1));
if isempty(kk)
break
end
k = m-1 + kk(randi(length(kk)));
chunk([m,k]) = chunk([k,m]);
end
if ~isempty(kk)
break
end
end
end
trialList = [trialList, chunk];
end
elapsed(i) = toc;
fprintf('%d: Max elapsed so far: %.3fs\n', i, max(elapsed));
if i>20
hist(elapsed);
drawnow
end
%--- Consistency check
for j=1:4
if sum(trialList==j)~=length(trialList)/4
error('Inconsistency in trial condition counts.');
end
end
if any(diff(trialList)==0)
error('Constraint violated.');
end
end
end
Yeah, I actually made a function to do this. At the moment what it does is makes a big matrix of all the numbers, scrambles them using randperm, and then transfers each row of the matrix into a new matrix after checking that it satisfies the condition (we actually wanted to check the face hadn’t been seen in the last n trials). The way it’s set up at the moment only does it for two image number lists, but you could easily adapt it to any number. 

Sorry if the code is a bit clunky. 

Cheers!

Deborah.

Dr. Deborah Apthorp
Research Fellow
Research School of Psychology
Research School of Computer Science

ph. +61 412 441 123






On 10 Oct 2017, at 12:17 pm, 'Diederick C. Niehorster' dcnieho@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:


What i do for this is simple:
for nTrial times:
 - shuffle your sequence of 8 randomly
 - verify it is ok
 - check that first of this is not same as last of what is in output vector
 - if both ok add to output vector, go to next.

Shuffling all at once will of course work too, this gives me some more flexibility. Also makes images very regularly distributed along the whole run, in case that matters.

Cheers,
Dee

On Tue, Oct 10, 2017 at 1:28 AM, microfish@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:


randomising with sequencing constraints is not something that you can do with a deterministic algorithm. unless i am mistaken, generating those kind of sequences always involves some trial and error. in other words, you need to write a function that randomly chooses items to add to a trial list, with the possibility that the sequence may not be valid, and may need to be discarded.

the simplest brute force way of doing this is to generate a full sequence and then verify it afterwards. this is inelegant but may be feasible if your constraints are not too strict.

past a certain constraint level, the simplest brute force method may be computationally too expensive and you may need to think of a more intelligent algorithm. for example, your algorithm might select items from a set of candidates that reduces as the building of the trial list progresses. at some point this sequence might fail, and need to be discarded, but it will be more likely to succeed than the simplest brute force method...


---In PSYCHTOOLBOX@yahoogroups.com, <alice.bollini@...> wrote :


Hi everybody,
I'm struggling with the sequence of my trials. In one block I have to present 4 images 30 times (tot number of trials 120).  I want to randomly shuffle my images vector without repeating images, given that each images is repeated equally.  Moreover  I have a second condition that can  be 1 or 0 and I need that each image has the same number of 0 and 1. More specifically, I would like to repeat the matrix [1 2 3 4 1 2 3 4 ;1 1 1 1 0 0 0 0]times, so that 1, 2, 3 and 4 would all repeat 30 times without being consecutive.
Example :
cond_a = [1 2 3 4]; 
cond_b = [1 0]; 
ntrial = 15;
trial = CombVec(cond_a,cond_b)';

trial = repmat(trial,ntrial,1);
trial_shuffle=Shuffle(trial,2) ; 

%Right pseudorandom
     1     1
     2     0
     3     1
     4     0
     1     0
     2     0
     1     1
     4     0
     3     1
     4     1
     3     0
     2     1
     1     0
     4     0
     3     1
     2     1

%wrong pseudorandom
     1     1
     2     0
     3     1
     4     0
     1     0
     2     0
     1     1
     4     0
     4     1
     4     1

     3     0
     2     1
     1     0
     3     0
     3     1

     2     1
Many thanks for any suggestions..
Alice





Mail priva di virus. www.avast.com