How can I generate a Matrix with Boolean elements, but the sum of each row is equal to a certain constant number.
2
votes
I think that you could try to generate a matrix of random elements. Then do a rowwise sort and set the largest n elements to true and the others to false. That would give each row a sum n.
– patrik
@RTL similar question but the linked question doesn't have an accepted answer and this one is "easier" because you have no column specific restraint.
– The Minion
@Shai I don't know if this should be marked as a duplicate because the answer provided on that extremely similar question currently doesn't work...
– Dan
2 Answers
1
votes
Lets say you want to have 20 columns (n=20
) and your vector a
contains the number of ones you want in each row:
n=20;
a= [5 6 1 9 4];
X= zeros(numel(a),n);
for k=1:numel(a)
rand_order=randperm(n);
row_entries=[ones(1,a(k)),zeros(1,n-a(k))];
row_entries=row_entries(rand_order);
X(k,:)=row_entries;
end
X=boolean(X);
What I do is generate me a random ordered index array rand_order
then getting an array which contains the wanted number of ones filled with zero. Reorder those elements according to rand_order
saving it and converting it to logical. And because of the use of a for loop rand_order
is all the time computed again, so giving you different locations for your output:
1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0
0 0 0 1 0 0 0 1 1 0 1 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 0 1 1 0 0
1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0
6
votes
Is each row the same one number?
k = 5;
m = 10;
n = 10;
[~, I] = sort(rand(m,n), 2)
M = I <= k
If you don't want the same number of 1
s in each row, but rather have a vector that specifies per row how many 1
s you want then you need to use bsxfun
as well:
K = (1:10)'; %//'
m = 10;
n = 10;
[~, I] = sort(rand(m,n), 2)
M = bsxfun(@ge, K,I)