arraysmatlabshufflepsychtoolbox

Shuffle an array of unequally repeating entries, so they do not repeat


I am writing an experiment in Matlab Psychtoolbox and my conditions are stored in an array like this

Cond = ["VM" "VM" "VN" "VS" "AM" "AM" "AN" "AS" "CM" "CM" "CN" "CS"...
"VM" "VM" "VN" "VS" "AM" "AM" "AN" "AS" "CM" "CM" "CN" "CS"];

I now want to shuffle the array in a way that I don't have repeating conditions.

There are a lot of treats regarding this problem e.g.this one, but they always have every condition equally often.

Some suggested a brute force method, shuffling so often until this criteria is reached. But since I have tree of this condition arrays and I have to shuffle them several times per experimental run I don't think that is a good solution.

Hope someone can help


Solution

  • I devised an algorithm that should do what you're asking for. Given a sequence, it will randomly reorder it such that no value repeats. However, it does appear to have a tendency to create repeated sub-sequences (e.g. ..."A" "B" "C" "A" "B" "C"...). I wrapped it in a function reorder_no_reps:

    function seq = reorder_no_reps(seq)
    
      % Find unique values and counts:
      N = numel(seq);
      [vals, ~, index] = unique(seq(:), 'stable');
      counts = accumarray(index, 1);
      [maxCount, maxIndex] = max(counts);
    
      % Check the maximum number of occurrences:
      if (2*maxCount-1 > N)
        error('Can''t produce sequence without repeats!');
      end
    
      % Fill cell array column-wise with permuted and replicated set of values:
      C = cell(maxCount, ceil(N/maxCount));
      if (3*maxCount-1 > N)
        permIndex = [maxIndex(1) ...
                     setdiff(randperm(numel(vals)), maxIndex(1), 'stable')];
      else
        permIndex = randperm(numel(vals));
      end
      C(1:N) = num2cell(repelem(vals(permIndex), counts(permIndex)));
    
      % Transpose cell array and extract non-empty entries:
      C = C.';
      seq = reshape([C{~cellfun('isempty', C)}], size(seq));
    
    end
    

    A description of the steps for the algorithm: