-1

I need to create several random sequences containing all digits from 0 through 9. The sequence needs to be random with no repetition and needs to include 0 and 9. I need to do this using MATLAB.

Help please!

rayryeng
  • 102,964
  • 22
  • 184
  • 193
Tanya
  • 13
  • 2
  • Also related (amongst many others): [Can randperm() generate several random permutations?](http://stackoverflow.com/questions/15684928/can-randperm-generate-several-random-permutations) – horchler Aug 10 '14 at 16:41

3 Answers3

7

Use randperm to do this for you. You specify an input number N (like 10 in your example), and it returns a vector of size N of randomly placed elements from 1 to N, such that it performs selection without replacement (a.k.a. a permutation). As such, do this in MATLAB:

rng(123); %// Set seed for reproducibility - 
          %// Not required... doing it so you can repeat my results
out = randperm(10) - 1;

This is what I get:

out =

 2     1     9     5     8     3     7     0     4     6

Take note that I had to subtract 1 from the output. The reason why is because randperm generates a vector from 1 to N, while you want values going from 0 to N-1.


If you want to create several random sequences, create a matrix where the number of rows is as long as the amount of sequences you want, and the number of columns is as long as how many numbers you want in a single sequence (10 in our case). After, run a for loop to generate each sequence and store this into a separate row in the matrix.

You could also achieve this using arrayfun, then convert the results back using cell2mat. This is required because arrayfun will output a cell array of results each time we run randperm, so we need to convert all of these individual cell arrays back into a single matrix. Also, these sequences will be in a cell array of a single row of columns, and so we need to transpose this prior to converting using cell2mat. In other words, try doing this:

rng(123);
numSequences = 5; %// Choose how many sequences you want here
out = arrayfun(@(x) randperm(10) - 1, 1:numSequences, 'uni', 0);
out = cell2mat(out.');

I thus get:

out = 

 2     1     9     5     8     3     7     0     4     6
 3     7     6     0     4     2     8     9     1     5
 7     8     5     6     3     9     0     4     2     1
 0     5     4     6     2     1     3     9     7     8
 1     5     2     3     6     8     9     0     4     7

Edit

You would like generate 10 random numbers from 0 - 9, but only select a subset (like 5) from this randomly generated set. If you look at randperm, there is a second parameter you specify where you tell it how many numbers you ultimately want to select. If you omit this parameter, it defaults to the first parameter you specified N. As such, simply change the code to include this additional parameter. As such:

rng(123);
numSequences = 5; %// Choose how many sequences you want here
maxNumber = 10; %// Specify how many numbers to possibly generate from
subsetNumber = 5; %// How many numbers you want to select from the list of numbers
out = arrayfun(@(x) randperm(maxNumber, subsetNumber) - 1, 1:numSequences, 'uni', 0);
out = cell2mat(out.');

The above says that I want to generate numbers from [0,9], but only choose 5 numbers from this list. As such, I get the following output:

out =

 1     9     8     2     5
 4     0     7     1     3
 6     3     1     7     5
 3     0     9     5     1
 5     1     2     8     6

for loop approach

If you're more of a beginner to MATLAB, you could do this the for loop way as I stated before. Jon Skeet, the StackOverflow ninja in one of his posts recommends that you write code for readability first, then optimize after (if you can). I agree with this, and the for loop approach is definitely more readable. It is essentially producing what arrayfun combined with cellmat are doing. As such, you would do it the for loop way like so:

rng(123);
numSequences = 5; %// Choose how many sequences you want here
maxNumber = 10; %// Specify how many numbers to possibly generate from
subsetNumber = 5; %// How many numbers you want to select from the list of numbers
out = zeros(numSequences, subsetNumber); %// Pre-allocate a numSequences x 10 matrix of zeroes
for idx = 1 : numSequences
    out(idx,:) = randperm(maxNumber, subsetNumber) - 1;
end

You will get the same results as doing it the first approach that I showed you above, so I won't repeat them here.


Take note that we have a single random sequence per row. To access the ith sequence, simply do:

out(idx,:)

idx would be the row you want to access. This will return a random permutation corresponding to that row you want.

Community
  • 1
  • 1
rayryeng
  • 102,964
  • 22
  • 184
  • 193
3

Rayryeng's answer is the way to go, and provides some nice explanations.

If you need to generate several sequences at once, the following code (which is a generalization of randperm's code) may be faster:

M = 9; %// maximum value. Values from 0 to M will be generated
N = 5; %// number of random sequences you want to generate
[~, result] = sort(rand(N,M+1),2); %// generalization of randperm to several rows
result = result - 1; %// subtract 1 to match desired range

Example result:

result =
     6     8     3     9     7     4     0     2     5     1
     3     4     9     6     2     8     1     7     0     5
     3     5     8     0     1     6     9     2     7     4
     8     3     5     0     9     7     2     4     1     6
     0     7     3     6     1     5     9     8     4     2
Community
  • 1
  • 1
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • 1
    @rayryeng Thanks! (+1 for you too already). It's weird that `randperm` is limited to outputting only one row. The generalization is straightforward – Luis Mendo Aug 10 '14 at 21:00
0

Are you looking to generate permutations of 10 items? In that case perms function would be useful. Please refer:

http://www.mathworks.com/help/matlab/ref/perms.html

RandomGuy
  • 91
  • 4
  • 1
    `perms` may not work in this case because this will generate **all possible** permutations for a single vector. As such, if you were to provide the vector `0:9`, this would generate a 10! x 10 = 3628800 x 10 matrix. I believe the OP only wants a few sequences instead of all possible sequences. What you could possibly do is generate this matrix, then randomly subsample this matrix but that huge matrix to be allocated to begin with isn't pretty IMHO. – rayryeng Aug 10 '14 at 16:24