2012-02-29 68 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