在Matlab中使用约束(特定数量的2-back重复)对向量进行 Shuffle

crcmnpdw  于 8个月前  发布在  Matlab
关注(0)|答案(1)|浏览(90)

我正在设置一个Matlab程序,人们将看到一系列15个单词(例如,“狗”,“猫”,“鱼”,“山羊”等)。每次试验将呈现一个单词,并且整个单词系列将重复40次(总共= 600次试验; 15个单词中的每一个都有40个独特的外观)。
我想把试订单安排成伪随机的:在50%的试验中(从试验3开始),该词应与 * 前两次试验 * 中出现的词相同。例如,有效的试订单(规模小得多)将是:

  • 试验1:狗(太早是一个2回重复)
  • 试验2:猫(太早是一个2回重复)
  • 试验3:犬(重复2次)
  • 试验4:鱼(不是2回重复)
  • 试验5:山羊(非2-back重复)
  • 试验6:鱼(2-背部重复)
  • 试验7:山羊(2-背部重复)
  • 试验8:猫(不是2-back重复)

以上是有效的,因为4个单词中的每一个出现的频率相等(这里,每个两次),从试验3开始,2-back重复和不重复的次数相等。
我也可以接受2-back重复的数量不等于50%,但它应该接近(例如,在40%和60%之间)。但是,我不知道如何保持这种约束,同时仍然确保15个单词中的每一个在整个试验集(600次试验)中重复相同的次数(40次)。
任何帮助都非常感谢!先谢了。
我尝试过用蛮力方法重新排列整个试验集,直到偶然遇到约束,但这需要太长的时间来处理。

snz8szmq

snz8szmq1#

这应该能满足你的要求shuffle_vector_2_back_repetitions返回一个大小为600 x 1的向量,其中包含15个元素的单词单元数组的索引。要测试函数的正确性,请使用以下命令:

idx = shuffle_vector_2_back_repetitions;
nnz(idx(1:end-2)==idx(3:end))

它应该返回一个接近300的数字。

function out = shuffle_vector_2_back_repetitions
    out = zeros(600, 1);
    a = repmat(15, 40, 1);
    r = randi([1 15], 2, 1);
    out (1:2) = r;
    a(r(1)) = a(r(1)) - 1;
    a(r(2)) = a(r(2)) - 1;

    for k = 3:600
        if randi([0 1])
            if a(out(k-2))
                out(k) = out(k-2);
                a(out(k)) = a(out(k)) - 1;      
            else
                f = find(a);
                idx = randi(numel(f));
                out(k) = f(idx);
                a(f(idx)) = a(f(idx)) - 1;
            end
        else
            tmp = a(out(k-2));
            if tmp
                a(out(k-2)) = 0;
            end
            f = find(a);
            if isempty(f)
                f = out(k-2);
                out(k) = f;
                a(f) = tmp - 1;
                return
            end
            idx = randi(numel(f));
            out(k) = f(idx);
            a(f(idx)) = a(f(idx)) - 1;
            if tmp
                a(out(k-2)) = tmp;
            end
        end
    end
end

相关问题