kotleta2007
kotleta2007

Reputation: 65

Efficient generation of permutation matrices in MATLAB

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

Answers (2)

Luis Mendo
Luis Mendo

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

Will
Will

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

Related Questions