2012-02-29 67 views
1

我有一个32×3矩阵,如下所示:排序和随机化矩阵根据特定约束

A =

[1 1 1;

1 1 2;

1 1 3;

1 1 4;

1 1 5;

1 1 6;

1 1 7;

1 1 8;

1 2 1;

1 2 2;

1 2 3;

1 2 4;

1 2 5;

1 2 6;

1 2 7;

1 2 8;

2 1 1;

2 1 2;

2 1 3;

2 1 4;

2 1 5;

2 1 6;

2 1 7;

2 1 8;

2 2 1;

2 2 2;

2 2 3;

2 2 4;

2 2 5;

2 2 6;

2 2 7;

2 2 8]

我需要做的是随机化行的顺序,同时保持行值一起,然而,这需要被约束,使得对于A(:,4),每8行仅包含数字1 - 8。因此,例如,可以有这样的:

A(1:8,:) =

[1 2 4;

1 1 5;

2 1 6;

1 1 8;

2 2 1;

2 1 2;

2 1 7;

1 1 3]

的1和2中的前两列的发生需为无规,1 - 8需要进行随机化将第三列的每8个值。最初我尝试在一个带有约束的循环中使用函数randswap,但这只会导致无限循环。同样重要的是,行必须保持在一起,因为前两列中的1和2需要与最后一列同时出现相同的次数。有人建议以下,但它完全不是那么回事了..

m = size(A,1); 

    n = 1:8; 

    out = 1; 

    i2 = 1; 

    while ~all(ismember(1:8,out)) && i2 < 100 

    i1 = randperm(m); 

    out = A(i1(n),:); 

    i2 = i2 + 1; 

    end 

回答

1

如果你需要的是得到一组8行了,你可以构建的结果是这样的:

out = [randi([1,2],[8,2]),randperm(8)'] 

out = 
    2  1  5 
    2  1  2 
    2  1  1 
    1  2  7 
    2  2  6 
    1  1  8 
    2  2  3 
    1  1  4 

如果你需要的所有随机化的A,你可以做到以下几点:

%# calculate index for the 1's and 2's 
r = rand(8,4); 
[~,idx12] = sort(r,2); 

%# calculate index for the 1's through 8's 
[~,idx8] = sort(r,1); 

%# use idx8 to shuffle idx12 
idx8into12 = bsxfun(@plus,idx8,[0 8 16 24]); 

%# now we can construct the output matrix 
B = [1 1;1 2;2 1;2 2]; 
out = [B(idx12(idx8into12),:),idx8(:)]; 

out = 
    1  1  7 
    1  2  3 
    1  2  1 
    2  1  8 
    2  1  5 
    2  2  4 
    2  2  2 
    2  1  6 
    1  1  3 
    1  2  7 
    1  1  1 
    1  2  8 
    1  2  4 
    1  1  5 
    2  2  6 
    2  1  2 
    1  1  8 
    2  1  7 
    1  2  5 
    2  1  1 
    1  2  6 
    2  1  3 
    1  1  2 
    1  1  4 
    2  1  4 
    2  2  7 
    2  2  8 
    2  2  3 
    1  2  2 
    1  1  6 
    2  2  5 
    2  2  1 

如果你这样做unique(out,'rows'),你会看到,确实有32个唯一行。 out中的每8行在第三列中都有数字1至8。

+0

非常感谢!这完美地解决了这个问题。 – Lau 2012-02-29 03:52:47