如何在不重复相同条件超过三遍的情况下伪随机化试验

时间:2018-08-29 01:27:17

标签: matlab random

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

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

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

我的问题是在解决上述问题的同时,如何将这种方法改进为具有无条件重复三次的约束。 还是会有更好的方法?

2 个答案:

答案 0 :(得分:1)

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

好,所以我的迭代方法是创建一个所有可能试验的置换向量,然后在不违反相同类型的连续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向量中。否则,请重新排列试验,然后重试。

我也在检查中写道,以确保我们不会永远循环……如果我们接近向量的末端并且得到很多重复,可能就是这种情况。

答案 1 :(得分:0)

我将提交一个稍微的修改,以使“更好”的随机化成为可能。假设您想要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));

在这种情况下,您几乎没有连续条件,而每个班级都有偶数。如果您不希望有重复的样本,这会变得有些困难,但可能可以管理。