matlab 我如何随机化两个相似的二进制向量,同时确保所有可能的组合都被考虑?

xwmevbvl  于 2022-12-19  发布在  Matlab
关注(0)|答案(2)|浏览(148)

一直试图解决这个简单的问题有一段时间,但就是找不到解决办法为我的生活...
我正在用PsychToolbox编写一个实验,但我不想告诉你细节,基本上我有两个大小相等的向量A和B,它们有相同数量的1和0:

A = [0 0 1 1]
B = [0 0 1 1]

向量A和B都必须是独立随机的,但是要保证两个向量之间的一个组合永远不会重复,也就是说,我必须这样结束

A = [1 1 0 0]
B = [1 0 0 1]

或者这个:

A = [0 0 1 1]
B = [0 1 0 1]

但我不应该以这个结尾

A = [1 1 0 0]
B = [1 1 0 0]

或者这个

A = [0 1 0 1]
B = [0 1 0 1]

确定这一点的一种方式是检查两个向量A+B之间的项的和,其应当总是仅包含一个2或仅包含一个0:

A = [1 1 0 0]
B = [1 0 0 1]

A+B = 2 1 0 1

我试着在while循环中设置这个条件(例如,只要A+B得到的向量中零的个数上级1,就继续随机化A和B),但是要么它仍然会产生重复的组合,要么它永远不会停止循环。我知道这是一个小问题,但我就是无法理解它。有人愿意帮忙吗?
这是我得到的脚本的简化版本:

A = [1 1 0 0];
B = A;
ARand = randperm(length(A));
A = A(ARand);
BRand = randperm(length(B));
B = B(BRand);

while nnz(~(A+B)) > 1
    ARand = randperm(length(A));
    A = A(ARand);
    BRand = randperm(length(B));
    B = B(BRand);
end

尽管如此,我最终还是得到了重复的组合。

j5fpnvbx

j5fpnvbx1#

% If you are only looking for an answer to this scenario the easiest way is
% as follows:

A = [0 0 1 1];
B = [0 0 1 1];
nn = length(A);

keepset = [0 0 1 1;0 1 0 1];
keepset = keepset(:,randperm(nn))

% If you want a more general solution for arbitrary A & B (for example)
A = [0 0 0 1 1 1 2 2 2];
B = [0 0 0 1 1 1 2 2 2];
nn = length(A);

Ai = A(randperm(nn));
Bi = B(randperm(nn));

% initialize keepset with the first combination of A & B
keepset = [Ai(1);Bi(1)];

loopcnt = 0;
while (size(keepset,2) < nn) 

    % randomize the elements in A and B independently
    Ai = A(randperm(nn));
    Bi = B(randperm(nn));
    % test each combination of Ai and Bi to see if it is already in the
    % keepset
    for ii = 1:nn
        tstcombo = [Ai(ii);Bi(ii)];
        matchtest = bsxfun(@eq,tstcombo,keepset);
        matchind = find((matchtest(1,:) & matchtest(2,:)));
        if isempty(matchind)
            keepset = [keepset tstcombo];
        end
    end
    loopcnt = loopcnt + 1;
    
    if loopcnt > 1000
        disp('Execution halted after 1000 attempts')
        break
    elseif (size(keepset,2) >= nn)
        disp(sprintf('Completed in %0.f iterations',loopcnt))
    end
        
end
keepset
ndh0cuux

ndh0cuux2#

下面是一个可能的解决方案:

A = [0 0 1 1];
B = [0 0 1 1];

% Randomize A and B independently
ARand = randperm(length(A));
A = A(ARand);
BRand = randperm(length(B));
B = B(BRand);

% Keep randomizing A and B until the condition is met
while sum(A+B) ~= 1 && sum(A+B) ~= length(A)
    ARand = randperm(length(A));
    A = A(ARand);
    BRand = randperm(length(B));
    B = B(BRand);
end

此解决方案检查A+B中的元素之和是否为1或A的长度,这表示A+B中只有一个元素分别为0或2。如果不满足这两个条件中的任何一个,则再次随机化向量A和B。

相关问题