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!
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!
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
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 approachIf 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.
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
Are you looking to generate permutations of 10 items? In that case perms
function would be useful. Please refer: