Auto-fill matrix without row-repetitions

2019-07-30 03:24发布

I have a series of numbers:

test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5]

which I want to randomely fill into a 3x5 matrix without having the same number in the same row.

How can I do this in matlab? Potentially I could randomize the test vector and fill it into the 5x3 matrix but I don't know how to do this without getting the same number in the same row.

3条回答
男人必须洒脱
2楼-- · 2019-07-30 04:08

You can take the unique matrix of test and pick any three elements out of it and fill in the required 5X3 matrix.

test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5] ;
test_unique = unique(test) ;
A = zeros(5,3) ;
for i = 1:size(A,1)
    A(i,:) = randsample(test_unique,3) ;
end

randsample needs a statistics toolbox, if you doesn't have it, you may use randperm as shown below.

test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5] ;
test_unique = unique(test) ;

A = zeros(5,3) ;
for i = 1:size(A,1)
    A(i,:) = test_unique(randperm(length(test_unique),3)) ;
end

If you want 3X5 matrix:

test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5] ;
test_unique = unique(test) ;
A = zeros(3,5) ;
for i = 1:size(A,1)
    A(i,:) = randsample(test_unique,5) ;
end
查看更多
The star\"
3楼-- · 2019-07-30 04:10

If you want to fill a 3-by-5 matrix with all of the values in test, making sure each row has no repeated values, you can do this very succinctly by using toeplitz to first generate an index matrix, then randomly permute the dimensions with randperm:

index = toeplitz(1:3, [3 5:-1:2]);
index = index(randperm(3), randperm(5));

And a sample index:

index =

     1     5     4     2     3
     4     3     2     5     1
     5     4     3     1     2

If your values in test are the numbers 1 through 5, this should be all you need to do. If test could be any vector with with 5 different numbers, three of each, then you can get the unique values of your test vector and index them with index. This solution will generalize to any test vector:

test = [3 3 3 7 7 7 5 5 5 9 9 9 4 4 4];    % Sample data
uniqueValues = unique(test);               % Get the unique values [3 4 5 7 9]
M = uniqueValues(index);                   % Use index as generated above

And the result will be guaranteed to be a reordered version of what's in test:

M =

     3     9     7     4     5
     7     5     4     9     3
     9     7     5     3     4
查看更多
叛逆
4楼-- · 2019-07-30 04:12

Here is a brute-force way of doing it

% data
test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5];

% randomly permute the indices
indices = randperm(numel(test));

% create a random matrix
matrix = reshape(test(indices), 5, 3);

% while number of unique elements in any of the rows is other than 3
while any(arrayfun(@(x) numel(unique(matrix(x,:))), (1:size(matrix,1)).')~=3)
    % keep generating random matrices
    indices = randperm(numel(test));
    matrix = reshape(test(indices), 5, 3);   
end;

% here is the result
result=matrix;

EDIT : If you want 3x5 like you mentioned in your comment, it is a lot easier. Just one line below.

[~, result] = sort(rand(3,5),2);
查看更多
登录 后发表回答