MATLAB Answers

0

Create a 20x24 matrix with each individual column with random integers without duplicate

Asked by Hyunjae Jeon on 16 Apr 2019
Latest activity Edited by Jan
on 17 Apr 2019
Accepted Answer by KSSV
Hello,
I am trying to create a 20x24 matrix with each individual column containing random integers without duplicate.
(I just made this number but the size will become bigger)
So far, I could make a 20x1 column named "randomcolumn" containing random numbers by using following codes.
random=randperm(20,20);
randomcolumn=random.';
I am stuck with making this to run with for loop function so that individual columns will add up 24 times.
n=24;
for i=1:n
randomcolumn
end
Any help will be very appreciated. Thank you

  0 Comments

Sign in to comment.

2 Answers

Answer by KSSV
on 16 Apr 2019
 Accepted Answer

iwant = zeros(20,24) ;
for i = 1:24
iwant(:,i) = randperm(20,20);
end

  1 Comment

Sign in to comment.


Answer by Stephen Cobeldick on 16 Apr 2019
Edited by Stephen Cobeldick on 16 Apr 2019

You do not need a loop, here is a much simpler solution in just one line:
>> [~,M] = sort(rand(20,24),1)
M =
16 20 17 10 15 10 13 6 16 13 11 18 12 16 4 17 20 4 1 7 8 12 16 14
10 10 19 14 12 7 1 11 12 16 2 5 8 15 15 14 17 3 19 6 19 2 13 17
20 12 10 8 14 19 14 12 20 9 19 9 1 10 9 9 6 17 10 12 17 20 7 11
17 8 9 5 3 12 18 19 2 17 8 2 11 8 12 2 16 16 15 11 1 18 8 12
4 5 16 7 2 6 2 10 17 14 17 19 10 3 18 16 11 13 7 2 16 6 20 9
3 11 3 20 4 13 12 5 8 11 14 6 3 13 16 3 4 7 12 14 7 5 11 20
15 9 13 2 8 17 16 17 19 7 7 7 9 19 2 4 15 2 13 1 10 9 2 18
11 17 20 9 11 18 6 20 4 8 5 12 18 1 5 8 5 6 14 8 18 15 9 16
5 6 7 4 20 14 5 15 9 3 4 17 15 2 7 18 2 19 8 18 9 14 4 2
6 19 11 15 13 9 7 16 15 12 1 14 6 9 13 11 8 9 3 4 11 8 6 13
12 16 2 17 18 16 15 4 7 4 10 3 17 14 14 7 7 18 6 17 4 16 12 6
14 3 1 13 6 5 4 7 11 15 20 13 19 17 19 1 18 11 11 13 14 7 14 8
19 15 14 11 10 20 3 1 6 10 15 20 14 7 11 12 12 14 17 9 2 11 5 15
1 14 6 3 5 8 19 13 10 18 6 8 16 6 8 20 9 1 16 16 3 17 17 4
8 2 12 19 7 1 8 8 1 1 16 15 7 4 20 5 19 8 5 10 5 3 10 10
18 7 15 12 16 2 20 9 14 20 3 10 2 12 1 15 1 15 18 19 15 10 1 1
2 18 5 6 19 15 9 18 13 19 9 4 20 20 10 13 3 20 20 15 12 19 19 5
9 4 4 18 9 4 17 2 18 2 13 16 4 11 17 19 13 10 9 5 13 13 18 7
13 1 18 1 17 11 10 3 3 5 18 1 5 5 3 6 14 12 2 20 20 1 3 19
7 13 8 16 1 3 11 14 5 6 12 11 13 18 6 10 10 5 4 3 6 4 15 3

  5 Comments

@Stephen: Simpler, but flawed. Modern randperm implementations use the efficient and not flawed Fisher-Yates-Shuffle (also called Knuth-Shuffle), while sorting random numbers has the (tiny) problem, that Matlab's sorting is stable, so if rand replies 2 equal numbers, their order is kept. rand can reply 2^53 different numbers, and the probability to get 2 equal elements is:
m = 2^53;
n = 20;
P = 1 - (m * (m-1) * . . . * (m-n+1)) / m^n
% See: birthday paradoxon
It is tiny, but not vanishing.
"...so if rand replies 2 equal numbers.."
I would be interested to know what is the actual probabilty of that occuring, to know exactly how "tiny" it is. Would a numeric calculation be robust enough?
According to the randperm documentation "randperm uses the same random number generator as rand, randi, and randn": if they use the same random number generator, why are there more different numbers available for randperm ? Given that they use the same random number generator, the only way randperm could be more random than sort(rand(..)) is if it detected identical values and called that random number generator again for them, repeating until no duplicate values exist. Is this documented somewhere?
@Stephen: I've posted the function to determine the probability in my comment already.
randperm was a simple sort(rand()) call in older Matlab versions. To obtain much more speed and to avoid the mentioned problem, I've implemented the Fisher-Yates shuffle: FEX: Shuffle as C-Mex function. One of the implementations in Matlab:
for i = 2:numel(X) % Shuffle in forward direction:
w = ceil(rand * i); % 1 <= w <= i
t = X(w);
X(w) = X(i);
X(i) = t;
end
See https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. Although this algorithm uses the same pseudo random number generators as randperm, it does not suffer from the problem of equal numbers and the stable sorting.
Note that this is biased also: ceil(rand * i) is not perfectly equally distributed: rand replies values equally distributed in (0,1) with 53 bit resolution. If this range is multiplied by 2, 3, 4, 5, ... you get different numbers of elements for the different integers. Better (if MathWorks has implemented randi carfully!):
w = randi([1, i]);
See the "modulo bias" on the Wikipedia page.
By the way, randi is massivly slower than rand. Actually the RNGs provide random 32 bit numbers. Picking the required bits and avoiding the modulo problem should not be more work that obtaining 2 random uint32 values and apply a multiplication to get a double.
Notes: The algorithms of rand, randi and randperm are not documented in public. I've sent an enhancement request to let randperm(n) run with the same speed as randperm(n,n).

Sign in to comment.