Random number with no repeats in set matrix
Show older comments
Hello again.
I want to make a matrix with random numbers that do not repeat in each row in a k X p matrix
and can be modified depending on inputs.
So far i have a code:
clc
k=input('# rows ');
p=input('# columns')
S=randperm(p);
S=S(1:(k*p));
S=reshape(S,k,p)
This works some times but not all the times.
Please help?
4 Comments
Walter Roberson
on 14 Apr 2019
1:(k*p) is going to involve values greater than p unless k is 0 or 1, so S(1:(k*p)) would have index out of range.
Rainaire Hansford
on 19 Apr 2019
Walter Roberson
on 20 Apr 2019
Edited: Walter Roberson
on 20 Apr 2019
hasdup = any( sum(bsxfun(@eq, s, permute(unique(s), [2 3 1])),2) > 1, 3);
Now hasdup is true for the rows of s which contain duplicate values within the row (and so you will need to regenerate the row.)
It is not clear to me why you do not use the sort-based code that I posted: it is guaranteed that the rows of S will contain unique integers in the range 1 to p with no need to regenerate.
Rainaire Hansford
on 20 Apr 2019
Accepted Answer
More Answers (2)
Steven Lord
on 21 Jun 2019
You have a requirement that no row may contain the same number twice. Can different rows in the same matrix contain the same number? So in the example below, A would not be acceptable (the second row has two 3's) but B would be acceptable (the first and second rows each have 2)?
A = [1 2; 3 3];
B = [1 2; 2 3];
If so, call randperm once for each row, telling it to generate size(B, 2) numbers from 1 to your upper limit.
nrows = 10;
ncols = 7;
maxvalue = 100;
A = zeros(nrows, ncols);
for whichrow = 1:nrows
A(whichrow, :) = randperm(maxvalue, ncols);
end
If you call rng default immediately before calling that code the resulting matrix should have three rows that contain the number 4 and three rows that contain 89, but that neither 4 nor 89 repeat in the same row.
Rainaire Hansford
on 21 Jun 2019
0 votes
7 Comments
Walter Roberson
on 21 Jun 2019
Proceed row by row. At each row, ismember() to find the matching numbers, and sum() or nnz() to get the count.
Rainaire Hansford
on 25 Jun 2019
Walter Roberson
on 25 Jun 2019
k = 1;
s = 5;
w = 1;
p = 5;
S = randperm(s);
S = S(1:(k*5));
S = reshape(S,k,5);
[~, Stemp] = sort(rand(w, s), 2);
winner = Stemp(:, 1:p);
num_match = zeros(k, w);
for row = 1 : k
for winset = 1 : w
num_match(k, winset) = nnz( ismember(S(k,:), winner(winset,:)) );
end
end
This will have one row for each player entry, and one column for each winning number set, with the values being the number of matches of that player entry against that winning number set.
This assumes that there might be more than one set of winning numbers (your w parameter) and that the player might have entered multiple times (your k parameter.)
You can proceed from this to filter out such as num_match >= 3 to find 3 or more matches.
Rainaire Hansford
on 28 Jun 2019
Walter Roberson
on 28 Jun 2019
By the way, there are vectorized solutions that can work when the amount of data is not big.
Rainaire Hansford
on 28 Jun 2019
Walter Roberson
on 28 Jun 2019
You can use reshape and bsxfun to compare each member of one array to each member of another, resulting in a k by s by w by p array. You then any() along one of the dimensions and sum along a different dimension and squeeze to get a 2d array of results.
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!