Reputation: 65
I'm trying to generate a 100-by-5 matrix where every line is a permutation of 1..100 (that is, every line is 5 random numbers from [1..100] without repetitions).
So far I've only been able to do it iteratively with a for-loop. Is there a way to do it more efficiently (using fewer lines of code), without loops?
N = 100;
T = zeros(N, 5);
for i = 1:N
T(i, :) = randperm(100, 5);
end
Upvotes: 3
Views: 125
Reputation: 112659
Let
N = 100; % desired number of rows
K = 5; % desired number of columns
M = 100; % size of population to sample from
Here's an approach that's probably fast; but memory-expensive, as it generates an intermediate M
×N
matrix and then discards N
-K
rows:
[~, result] = sort(rand(N, M), 2);
result = result(:, 1:K);
Upvotes: 1
Reputation: 1880
There is very little downside to using a loop here, at least in this minimal example. Indeed, it may well be the best-performing solution for MATLAB's execution engine. But perhaps you don't like assigning the temporary variable i
or there are other advantages to vectorization in your non-minimal implementation. Consider this carefully before blindly implementing a solution.
You need to call randperm
N
times, but each call has no dependency on its position in the output. Without a loop index you will need something else to regulate the number of calls, but this can be just N
empty cells cell(N,1)
. You can use this cell array to evaluate a function that calls randperm
but ignores the contents (or, rather, lack of contents) of the cells, and then reassemble the function outputs into one matrix with cell2mat
:
T = cell2mat(cellfun(@(~) {randperm(100,5)}, cell(N,1)));
Upvotes: 1