Как псевдослучайных испытаний без повторения одного и того же условия более трех раз - PullRequest
0 голосов
/ 29 августа 2018

Я знаю, что есть много навыков псевдослучайности, но этот, я не мог найти его, поэтому я включил его здесь.

Я использую MATLAB 2018a. Я пытался организовать эксперимент поведения, который имеет 10 условий. Каждое условие имеет 50 испытаний. В результате получается 500 испытаний. Я хотел бы псевдослучайно определить последовательность испытаний таким образом, чтобы ни одно и то же условие не появлялось более трех раз подряд.

Я думал, что это будет не так сложно, так как у меня много условий, но у некоторых методов, которые я нашел при поиске, были небольшие проблемы. Одним из методов, которые я использовал, было извлечение индексов с использованием «unique (find (diff (seq) == 0))», повторное рандомизирование и замена на исходную избыточную последовательность. ( Ссылка ) Но этот метод имел проблему, состоящую в том, что он случайным образом изменял общее число условий. Если бы вы хотели 40 испытаний для каждого условия, это привело бы к 39 для некоторых условий и 41 для других ..

Мой вопрос заключается в том, как усовершенствовать этот метод, чтобы ограничения, состоящие в том, чтобы ни одно условие не повторялось три раза, решали проблему, упомянутую выше. Или есть ли лучшие способы?

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

отказ от ответственности: это решение не идеально.

Хорошо, поэтому мой итеративный подход заключается в создании перестановочного вектора из всех возможных испытаний и последующем добавлении каждого из них к другому вектору, если он не нарушает более 3 последовательных условий одного типа .

Сначала я настрою некоторые константы

N_CONDITIONS = 5;
TRIALS_PER_CONDITION = [10 10 10 7 9];
N_DUPS_ALLOWED = 3;

N_TOTAL = sum(TRIALS_PER_CONDITION);

Затем я создаю случайную перестановку всех испытаний:

randomInds = randperm(N_TOTAL);
% make vector containing all the replicates
conditionTrials = repelem(1:N_CONDITIONS, TRIALS_PER_CONDITION);

% permute the conditions
conditionTrials = conditionTrials(randomInds);

Затем я готовлюсь зациклить элемент вектора conditionTrials элементом

% initialize the random trials vector
randomizedTrials = zeros(N_TOTAL, 1);

% pre assign the first allowable possible duplications
randomizedTrials(1:N_DUPS_ALLOWED) = conditionTrials(1:N_DUPS_ALLOWED);
% drop the used values
conditionTrials(1:N_DUPS_ALLOWED) = [];

Затем я устанавливаю переменные / счетчики цикла и выполняю цикл:

% initialize counter
i = N_DUPS_ALLOWED + 1;
iterCounter = 1;
maxIter = 1000; % set me pretty low, but high enough for extra perms
while any(~randomizedTrials)
  iterCounter = iterCounter + 1;
  if iterCounter > maxIter 
    fprintf(2, '\nMaximum interations exceeded.\n');
    break
  end
  % get the value we want to test
  currentTrial = conditionTrials(1);
  % get the previes n_dups_allowed values
  previousConditions = randomizedTrials( i - (N_DUPS_ALLOWED:-1:1) );
  % check if they're the same
  if sum(previousConditions == currentTrial) == N_DUPS_ALLOWED
    % reject this value because last 3 values == currentValue
    % accepting would lead to > 3 consecutive trials
    % create a new shuffle
    newPermInds = randperm(length(conditionTrials));
    conditionTrials = conditionTrials(newPermInds);
    continue
  end
  % accept the random number, insert it in the trails vector
  randomizedTrials(i) = currentTrial;
  % now drop the value
  conditionTrials(1) = [];
  i = i+1;
end

Цикл по существу утверждает: %, хотя в векторе randomizedTrials присутствует хотя бы 1 ноль, проверьте, нарушает ли следующее значение N_DUPS_ALLOWED. Если нарушений нет, извлеките его из вектора conditionTrials и добавьте к вектору randomizedTrials. В противном случае повторно включите испытания и повторите попытку.

Я также написал в проверке, чтобы убедиться, что мы не зацикливаемся вечно ... как может быть, если мы подойдем к концу вектора и получим много повторов.

0 голосов
/ 29 августа 2018

Я собираюсь представить небольшую модификацию, которая потенциально дает «лучшую» рандомизацию. Допустим, вам нужно всего 300 пиков, и у вас есть индексы от 1 до 500, и каждые 50 являются новым условием. Вы можете настроить систему так, чтобы у вас было не более 2 последовательных условий, но каждые 10 условий были бы совершенно разными.

cond_num = [];

for ii = 1:30
    cond_num = [cond_num randperm(10)];
end
sample_num = (cond_num-1)*50+randi([0 9],size(cond_num));

В этом случае у вас очень мало последовательных условий при четных числах в каждом классе. Если вы не хотите иметь повторяющиеся сэмплы, это становится немного сложнее, но, вероятно, управляемым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...