Preventing repeated sequences in a matrix

6 ビュー (過去 30 日間)
Lauren Shone
Lauren Shone 2012 年 9 月 21 日
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 日
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 件のコメント
Matt Fig
Matt Fig 2012 年 9 月 21 日
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 日
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).'));

カテゴリ

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