Random but unique values in matrix

13 ビュー (過去 30 日間)
Asad Abbas
Asad Abbas 2016 年 8 月 29 日
編集済み: antlhem 2019 年 4 月 28 日
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 件のコメント
Steven Lord
Steven Lord 2016 年 8 月 29 日
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 2016 年 8 月 29 日
My answer exactly implements the concept that Steve Lord suggests.

サインインしてコメントする。

採用された回答

dpb
dpb 2016 年 8 月 29 日
>> 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 件のコメント
Thorsten
Thorsten 2016 年 8 月 29 日
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 2016 年 8 月 29 日
Thank you so much Sir, Its working. I am so happy.

サインインしてコメントする。

その他の回答 (3 件)

Stephen23
Stephen23 2016 年 8 月 29 日
編集済み: Stephen23 2016 年 8 月 29 日
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 件のコメント
Stephen23
Stephen23 2016 年 8 月 29 日
編集済み: Stephen23 2016 年 8 月 29 日
@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 2019 年 4 月 28 日
編集済み: antlhem 2019 年 4 月 28 日
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?

サインインしてコメントする。


Ori Golani
Ori Golani 2018 年 10 月 9 日
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 件のコメント
Stephen23
Stephen23 2018 年 10 月 9 日
+1 neat idea.
antlhem
antlhem 2019 年 4 月 28 日
編集済み: antlhem 2019 年 4 月 28 日
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?

サインインしてコメントする。


Thorsten
Thorsten 2016 年 8 月 29 日
編集済み: Thorsten 2016 年 8 月 29 日
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 件のコメント
Asad Abbas
Asad Abbas 2016 年 8 月 29 日
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 2016 年 8 月 29 日
You're right. I corrected the code.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCreating and Concatenating Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by