首页 > 解决方案 > 如何在不重复相同条件超过 3 次的情况下对试验进行伪随机化

问题描述

我知道有很多伪随机化技能,但是这个,我无法搜索,所以我把它放在这里。

我正在使用 MATLAB 2018a。我一直在尝试建立一个有 10 个条件的行为实验。每个条件有 50 次试验。这导致总共 500 次试验。我想对试验序列进行伪随机化,以使相同的条件不会连续出现超过 3 次。

我认为这不会那么困难,因为我有很多条件,但是我通过谷歌搜索找到的一些方法存在小问题。我使用的一种方法是使用'unique(find(diff(seq)==0))'提取索引,重新随机化并用原始冗余序列替换它。(链接) 但是这个方法有个问题,它会随机改变一个条件的总数。如果您想为每个条件进行 40 次试验,那么某些条件会导致 39 次,而其他条件会导致 41 次。

我的问题是如何改进这种方法以限制没有一个条件重复三次,同时解决上述问题。或者有没有更好的方法?

标签: matlabrandom

解决方案


免责声明:此解决方案并不完美。

好的,所以我的迭代方法是创建所有可能试验的置换向量,然后如果它不违反超过 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

循环本质上是:%while 至少 1 个零存在于随机试验向量中,检查下一个值是否违反N_DUPS_ALLOWED。如果没有违规,则将其从向量中弹出conditionTrials并将其附加到randomizedTrials向量中。否则,重新排列试验并重试。

我还写了一个检查以确保我们不会永远循环......如果我们接近向量的末端并且我们得到许多复制,可能就是这种情况。


推荐阅读