Matlab 0和1的矩阵,其中后续行中的赋值取决于前一行
我想在MATLAB中创建一个矩阵,其中: 第一行由0和1的随机排列组成,均匀分割(即50-50) 第二行随机将0分配给第一行中0和1的50%,将1分配给剩余的50% 第三行随机将0分配给第二行中0和1的50%,将1分配给剩余的50% 非随机化示例:Matlab 0和1的矩阵,其中后续行中的赋值取决于前一行,matlab,psychtoolbox,Matlab,Psychtoolbox,我想在MATLAB中创建一个矩阵,其中: 第一行由0和1的随机排列组成,均匀分割(即50-50) 第二行随机将0分配给第一行中0和1的50%,将1分配给剩余的50% 第三行随机将0分配给第二行中0和1的50%,将1分配给剩余的50% 非随机化示例: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 有什么建议吗?使用randperm的解决方案:
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
有什么建议吗?使用
randperm
的解决方案:
nrows = 3;
ncols = 16;
M = zeros(nrows,ncols);
%// seed the first row
M(1,1:ncols/2) = 1;
M(1,:) = M(1,randperm(ncols));
for r = 2:nrows
%// Find ncols/4 random between 1 and ncols/2. These will be used to index half of the previous rows 1 elements and set them to one
idx = randperm(ncols/2);
idx1 = idx(1:ncols/4);
%// Do the same thing again, but this time it will be used for the 0 elements of the previous row
idx = randperm(ncols/2);
idx0 = idx(1:ncols/4);
idx_prev1 = find(M(r-1,:)); %// Find where the 1 elements were in the last row
idx_prev0 = find(~M(r-1,:)); %// Find where the 0 elements were in the last row
M(r,idx_prev1(idx1))=1; %// Set half of the previous rows 1 elements in this row to 1
M(r,idx_prev0(idx0))=1; %// Set half of the previous rows 0 elements in this row to 1
end
基于检查数字是否大于或小于中值的解决方案。只要测试的列数是偶数,一组随机双精度数据中正好有一半将大于中值,而另一半将更小。这保证了正好有50%的位被翻转
nRows = 3;
nCols = 16; %# divisible by 4
%# seed the array
%# assume that the numbers in each row are unique (very, very likely)
array = rand(nRows,nCols);
out = false(nRows,nCols);
%# first row is special
out(1,:) = array(1,:) > median(array(1,:));
%# for the rest of the row, check median for the zeros/ones in the previous row
for iRow = 2:nRows
zeroIdx = out(iRow-1,:) == 0;
%# > or < do not matter, both will replace zeros/ones
%# and replace with exactly half zeros and half ones
out(iRow,zeroIdx) = array(iRow,zeroIdx) > median(array(iRow,zeroIdx));
out(iRow,~zeroIdx) = array(iRow,~zeroIdx) > median(array(iRow,~zeroIdx));
end
nRows=3;
nCols=16;%#可被4整除的
%#为阵列添加种子
%#假设每行中的数字都是唯一的(非常可能)
数组=兰德(nRows,nCols);
out=假(nRows、nCols);
%#第一排是特别的
out(1,:)=数组(1,:)>中值(数组(1,:));
%#对于该行的其余部分,检查前一行中0/1的中值
对于iRow=2:nrow
zeroIdx=out(iRow-1,:)=0;
%#>或<无所谓,两者都将替换0/1
%#并替换为半个零和半个一
out(iRow,zeroIdx)=数组(iRow,zeroIdx)>中值(数组(iRow,zeroIdx));
out(iRow,~zeroIdx)=数组(iRow,~zeroIdx)>中值(数组(iRow,~zeroIdx));
结束
我想提供一个简短的bsxfun
解决方案:
%// number of divisions
n = 4;
%// unshuffled matrix like in your example
unshuffled = bsxfun(@(a,b) mod(a,2*b) > b-1, meshgrid(1:n^2,1:n) - 1, (2.^((n-1):-1:0)).') %'
%// shuffle columns
shuffled = unshuffled(:,randperm(n^2))
首先,您需要创建非缓冲矩阵,这可以通过将
meshgrid(1:n^2,1:n)
生成的矩阵与依赖于行的模数进行比较来完成。最后,您只需对列进行无序排列。如果您有统计工具箱,您可以使用以下工具轻松完成此操作:
示例结果:
result =
0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1
1 1 0 0 0 1 1 1 0 1 0 1 0 0 0 1
1 0 0 0 1 0 0 1 0 1 1 0 1 1 0 1
这不就是洗牌非随机示例的列吗?如果是这样的话,只需使用
randperm
@Dan:我不这么认为,如果我理解正确的描述,第三行可能看起来像第一行。置换,你不能做到这一点。正如在对问题的评论中指出的,洗牌完美非随机矩阵的列可能是不够的。由于问题的措辞不恰当,因此没有理由不能有两列,例如只有1
s。这种方法有效地考虑了每一步前面的所有行,而不仅仅是前一行。@Dan无论我怎么扭曲我的想法,我都不能这样解释这个问题。我们必须等待OP猜测。OP状态“第三行随机地将零点分配给第二行中的50%和50%,剩下的第三行,所以第三行根本不考虑第一行,因此事实上可以与第一行相同……我不认为这是正确的。我的理解是,对于第2行中的8个1
s,第3行中对应的元素中正好有4个应该是1
。在您的示例结果中
只有2个是1
@Dan感谢您指出这一点。缺少一行,无法将每一行初始化为上一行。更正!
M = 3; %// number of rows
N = 16; %// number of columns. Should be multiple of 4, according to problem definition
result = zeros(M,N); %// preallocate and initiallize to zeros
result(1, randsample(1:N,N/2)) = 1; %// first row: half values set to one, half to zero
for m = 2:M
result(m, :) = result(m-1, :); %// initiallize row m equal to row m-1
result(m, randsample(find(result(m-1,:)), N/4)) = 0; %// change half of ones
result(m, randsample(find(~result(m-1,:)), N/4)) = 1; %// change half of zeros
end
result =
0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1
1 1 0 0 0 1 1 1 0 1 0 1 0 0 0 1
1 0 0 0 1 0 0 1 0 1 1 0 1 1 0 1