Reputation: 39
I have a 32 x 3 matrix as follows:
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]
What I need to do is randomise the order of the rows, while keeping the row values together, however, this needs to be constrained such that for A(:, 4), every 8 rows contain only the numbers 1 - 8. So for example, you could have something like:
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]
The occurrence of 1 and 2 in the first two columns needs to be random, 1 - 8 needs to be randomised for every 8 values of the third column. Initially I tried to use the function randswap within a loop with an added constraint, but this has only led to an infinite loop. Also important that the rows stay together as the 1s and 2s in the first two columns need to appear alongside the last column an equal number of times. Someone suggested the following, but it doesn't quite work out..
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
Upvotes: 1
Views: 194
Reputation: 74940
If all you need is to get one set of 8 rows out of A, you can construct the result like this:
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
If you need to randomize all of A
, you can do the following:
%# 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
If you do unique(out,'rows')
, you'll see that there are indeed 32 unique rows. Every 8 rows in out
have the numbers 1 through 8 in the third column.
Upvotes: 1