Preventing repeated sequences in a matrix

I have a 192 x 3 matrix, order(192 x 3):
order(:, 1) and order(:, 2) both contain repeating values of 1 - 16, and order(:, 3) contains repeating values of 1 and 2. I need to shuffle the matrix, while preventing any repeats of more than three of the same value in the last column, so order(:, 3) should never show more than 3 repeats of 1 or 2.
This is what I have, which worked for a smaller version of the matrix just fine, but seems to get stuck with a slightly larger matrix:
not_good = true;
while not_good
not_good = false;
order = Shuffle(order);
% returns an array of 1s and 0s indexing the position of the values for 1 and 2
R1 = order(:, 3) == 1;
R2 = order(:, 3) == 2;
% checks for repeats, returns 1 if repeats are present
rep_test1 = any(diff([1; find(R1)])>3);
rep_test2 = any(diff([1; find(R2)])>3);
if rep_test1 > 0 || rep_test2 > 0
not_good = true;
end
end
Any comments much appreciated. Thanks.

댓글 수: 1

Matt Fig
Matt Fig 2012년 9월 21일
편집: Matt Fig 2012년 9월 21일
What is Shuffle?
>> help Shuffle
Shuffle not found.
And give the matrix order. Is this a good approximation of order?
order = cell2mat(arrayfun(@(x) randperm(x).',16*ones(12,2),'Un',0));
order = [order cell2mat(arrayfun(@(x) randperm(x).',2*ones(96,1),'Un',0))];

댓글을 달려면 로그인하십시오.

 채택된 답변

Matt Fig
Matt Fig 2012년 9월 21일
편집: Matt Fig 2012년 9월 21일

0 개 추천

I think I figured out that Shuffle is on the FEX.
Part of the problem is that you are just going to have more chance to get 3+ of a kind in a row the more numbers you add. This is faster, however. For this order array (or the more structured one I show above), it takes less than a minute.
order = [mod(randperm(192),16);mod(randperm(192),16);...
mod(randperm(192),2)].'+1;
T = true(1,4); % 3 in a row is o.k.
while true
order = Shuffle(order);
if isempty(strfind(order(:,3).'==2,T))
if isempty(strfind(order(:,3).'==1,T))
break
end
end
end
Another note: Your code will let pass an order that has 4 or more in a row as the end of the third column...

댓글 수: 2

I noticed the first code I posted used
T = ones(1,3);
When it should have been
T = ones(1,4);
Now fixed.
Lauren Shone
Lauren Shone 2012년 9월 25일
Thank you! This works.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Jan
Jan 2012년 9월 21일
편집: Jan 2012년 9월 21일

0 개 추천

It will be much cheaper to shuffle the index vector only and use an UINT8 as long as less than 255 elements are processed (based on Matt's code):
index = uint8(1):uint8(192);
data = [mod(randperm(192), 16); mod(randperm(192), 16)].';
crit = mod(randperm(192), 2) + 1; % Avoid repeated transposition
T = true(1,4);
while 1 % Cheaper than the function(!) TRUE
index = Shuffle(index);
test = crit(index);
if isempty(strfind(test == 2, T))
if isempty(strfind(test == 1, T))
break
end
end
end
% Create the full data once only after the calculations:
result = cat(2, data(index, :), double(crit(index).'));

카테고리

도움말 센터 및 File Exchange에서 Multidimensional Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by