Random but unique values in matrix

Please help me! I want to generate random but unique row as given in code. I want generate complete 100*13 matrix. When this code run it stuck after around 29th iterations. Please help me and give suggestions. If my question is not understandable please let me know. I will explain more in detail.
j=1;
pop_size=100;
V=13;
while j:pop_size
y=randi([0 1],j,V);
y(:,2)=~y(:,1);
y(:,3)=~y(:,4);
y(:,5)=~y(:,6);
y(:,12)=~y(:,13);
y = unique(y, 'rows');
j=size(y,1)+1;
end

10 comentarios

Stephen23
Stephen23 el 29 de Ag. de 2016
Editada: Stephen23 el 29 de Ag. de 2016
This line is highly unusual, where you use a vector as the logical condition:
while j:pop_size
what is it supposed to do? The while documentation states, "An expression is true when its result is nonempty and contains only nonzero elements (logical or real numeric). Otherwise, the expression is false." Because you are constructing this vector with pop_size at the end it will only become false when the vector is empty. Is this what you need to achieve?
Or are you actually trying to loop from 1 to 100 ?
What does "it stuck after around 29th iterations" mean? How is the loop "stuck" ? Do you get an error, does the loop complete correctly, or something else ?
Asad Abbas
Asad Abbas el 29 de Ag. de 2016
Editada: Asad Abbas el 29 de Ag. de 2016
I am trying to loop 1 to 100. Not actually stuck. but it update unique values and running. if value in new row is not unique then it replace again and again. I am trying to get non-repetition rows thats why i mentioned 'unique'. It was running from last three hours but no any end result or error.
John D'Errico
John D'Errico el 29 de Ag. de 2016
that is a FOR loop, not a while.
Stephen23
Stephen23 el 29 de Ag. de 2016
Editada: Stephen23 el 29 de Ag. de 2016
What are these for?:
y(:,2)=~y(:,1);
y(:,3)=~y(:,4);
y(:,5)=~y(:,6);
y(:,12)=~y(:,13);
You compare some values, but never allocate their output to anything or use them for anything at all.
John D'Errico
John D'Errico el 29 de Ag. de 2016
I've looked at your code, and I have no idea what your goal is here. So I have no idea if you are doing something that is easy to do otherwise, but just doing it inefficiently.
Can you please explain your goal here?
Asad Abbas
Asad Abbas el 29 de Ag. de 2016
these are constraints. For example column 1 should not be equal column 2. means if column 1 is 0 then column 2 should be 1.
Asad Abbas
Asad Abbas el 29 de Ag. de 2016
Dear Sir John D'Errico, I tried with for loop but it not giving me complete 100*13 matrix. It giving me some times 91*13, 89*13, 92*13, 84*13 some thing like this. I want generate 100*13 unique value matrix
Asad Abbas
Asad Abbas el 29 de Ag. de 2016
Editada: Asad Abbas el 29 de Ag. de 2016
Sir, I want generate 100*13 random matrix with 0 or 1 value and each row should be unique means no repetition should occur. I have given so me constraints also. These constraints are. For example column 1 should not be equal column 2. means if column 1 is 0 then column 2 should be 1. y(:,2)=~y(:,1); y(:,3)=~y(:,4); y(:,5)=~y(:,6); y(:,12)=~y(:,13);
Steven Lord
Steven Lord el 29 de Ag. de 2016
So generate a random 100-by-8 matrix. Check if all its rows are unique using the unique function with the 'rows' flag. Once you have a suitable matrix, expand it to 12 columns. [Once columns 1, 3, 5, and 12 are fixed they determine columns 2, 4, 6, and 13.]
Stephen23
Stephen23 el 29 de Ag. de 2016
My answer exactly implements the concept that Steve Lord suggests.

Iniciar sesión para comentar.

 Respuesta aceptada

dpb
dpb el 29 de Ag. de 2016
>> z=randi([0 1],100,13); % Generate trial array
>> [u,ia,ib]=unique(z,'rows','stable'); % check for uniqueness between rows
>> length(ia) % dang!, one short...
ans =
99
>> find(ismember(z,z(setdiff([1:100],ia),:),'rows')) % locate which are the offending rows
ans =
34
92
>>
>> [z(34,:);z(92,:)] % indeed, they are identical...
ans =
0 0 1 0 0 1 1 0 1 0 1 0 0
0 0 1 0 0 1 1 0 1 0 1 0 0
>>
OK, NOW you can begin a loop looking to generate a new row that is different than z(34,:) and also not duplicate another already...

2 comentarios

Or you generate a trial array with many more rows than actually needed and hope that you'll end up with more than 100 unique rows. See my answer below.
BTW: You forgot the ensure the four constraints
y(:,2)=~y(:,1);
y(:,3)=~y(:,4);
y(:,5)=~y(:,6);
y(:,12)=~y(:,13);
Asad Abbas
Asad Abbas el 29 de Ag. de 2016
Thank you so much Sir, Its working. I am so happy.

Iniciar sesión para comentar.

Más respuestas (3)

Stephen23
Stephen23 el 29 de Ag. de 2016
Editada: Stephen23 el 29 de Ag. de 2016
A complete working example:
X = randi([0,1],100,9);
chk = true;
while chk
[~,idx] = unique(X,'rows');
idy = setdiff(1:100,idx);
X(idy,:) = randi([0,1],numel(idy),9);
chk = numel(idy)>0;
end
Y = X(:,[1,1,2,2,3,3,4:end,end]);
idz = [1,3,5,12];
Y(:,idz) = ~Y(:,1+idz);
and tested:
>> size(unique(Y,'rows'))
ans =
100 13
>> Y(:,1:2) % check that two columns are always different
ans =
0 1
1 0
1 0
1 0
0 1
1 0
1 0
1 0
0 1
1 0
1 0
etc
>> Y(:,12:13)
ans =
1 0
1 0
0 1
1 0
1 0
0 1
1 0
1 0
1 0
0 1
0 1
0 1
1 0
0 1
etc

3 comentarios

Asad Abbas
Asad Abbas el 29 de Ag. de 2016
Sir Its working exactly. thank you much.
Stephen23
Stephen23 el 29 de Ag. de 2016
Editada: Stephen23 el 29 de Ag. de 2016
@Asad Abbas: you can also vote for my answer, if it solves your task. That is an easy way for you to say "thank you" to us volunteers.
antlhem
antlhem el 28 de Abr. de 2019
Editada: antlhem el 28 de Abr. de 2019
Hi Stephen Cobeldick, how would you suggest me to use this method in order to create a bigger array (1500x1500). With all the rows unique among each other?

Iniciar sesión para comentar.

Ori Golani
Ori Golani el 9 de Oct. de 2018
Hi all, I know that this is an old thread, but I found an efficient non-iterative solution for this.
Complete working example:
I= 2; % maximal integer in the matrix (values will be [0...I-1])
M= 3; % Matrix rows
N= 10; % matrix columns
word_indices= randperm(I^N,M);
matrix_in_char= dec2base(word_indices,I);
random_matrix= reshape(base2dec(matrix_in_char(:),I),M,N);
Tested:
random_matrix =
1 1 1 0 1 1 1 0 1 0
0 0 1 1 0 1 0 0 0 1
0 0 1 0 1 0 1 1 1 0

2 comentarios

Stephen23
Stephen23 el 9 de Oct. de 2018
+1 neat idea.
antlhem
antlhem el 28 de Abr. de 2019
Editada: antlhem el 28 de Abr. de 2019
Hi Ori Golani, do you know how to create a bigger matrix with this method? I tested with M=N=1500, but is not passing this test. There is an error from MATLAB saying:
Error using randperm
N must be less than 2^53.
Any suggestions, to be able to create bigger random-unique matrix?

Iniciar sesión para comentar.

Thorsten
Thorsten el 29 de Ag. de 2016
Editada: Thorsten el 29 de Ag. de 2016
The trick is to get more rows then actually needed, like 2*pop_size. Then you'll get your y almost always in the first trial:
pop_size=100;
V=13;
trials = 1;
while 1
y = randi([0 1], 2*pop_size, V);
y(:,2)= 1- y(:,1);
y(:,3)= 1- y(:,4);
y(:,5)= 1- y(:,6);
y(:,12)= 1- y(:,13);
[yu, xi] = unique(y, 'rows');
if size(yu, 1) >= pop_size
y = y(xi(1:pop_size),:);
break;
else
trials = trials + 1;
end
end
% check
size(unique(y, 'rows'), 1)

2 comentarios

Asad Abbas
Asad Abbas el 29 de Ag. de 2016
Thank you so much for your response. But when I run this command at the end of your given code y=unique(y,'rows'); It is not giving 100*13 unique rows, It giving 89*13, 92*13 something like this.
Thorsten
Thorsten el 29 de Ag. de 2016
You're right. I corrected the code.

Iniciar sesión para comentar.

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Preguntada:

el 29 de Ag. de 2016

Editada:

el 28 de Abr. de 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by