Random rows in matrix so no element from the first column occur twice in a row

3 ビュー (過去 30 日間)
Måns
Måns 2023 年 3 月 22 日
編集済み: Adam Danz 2023 年 3 月 23 日
Hi,
I have a matrix of x rows and 8 columns and need to random the rows so no element from the first column occur twice in a row.
It is a x times 8 double.
I know how to random the first coulumn but end up with a x times 1 array instad.
Thank you in advance

採用された回答

Adam Danz
Adam Danz 2023 年 3 月 22 日
編集済み: Adam Danz 2023 年 3 月 23 日
There is no general solution since the values in column 1 may not sufficiently vary. For example, what if all of the values in column 1 were identical? Or what if the values in column 1 were [1;1;1;2]?
Assuming the data in column 1 sufficiently varies, you can use randperm to randomly permute the rows of the matrix. But that doesn't guarantee a lack of consecutive identical values. You could pemute the rows within a while-loop that continues to apply random permutations until the condition is satisfied or until all possibilities are exhausted, though this approach challenges the notion of randomness.
Here's a demo. If there are no permutations that satisfy the constraints, a warning is thrown (you can change that however you'd like).
rng default % for demo purposes
M = randi(3,8,3)
M = 8×3
3 3 2 3 3 3 1 1 3 3 3 3 2 3 2 1 2 1 1 3 3 2 1 3
accepted = false;
nrows = height(M);
nPossibilities = factorial(nrows); % number of possible permutations
count = 0;
while ~accepted
% If there are still consecutive identical values or
% if we ran out of possible permutations
if any(diff(M(:,1))==0) && count <= nPossibilities
pidx = randperm(nrows);
M = M(pidx,:);
count = count+1;
else
accepted = true;
% Final check: throw warning if no permutations worked.
if any(diff(M(:,1))==0)
warning('No permutations result in non-consecutive values.')
end
end
end
disp(M)
3 3 3 1 2 1 3 3 3 2 1 3 1 3 3 3 3 2 2 3 2 1 1 3
Replace the demo matrix with M = randi(2,8,3) to see the warning.
Note, if the matrix has many rows and the values in column 1 do not sufficiently vary, this could run a very long time. For example, a matrix with 10 rows has 3,628,800 possible permutations. If you expect to have this issue, you'll need a smarter solution that initially determines whether a permutation is possible.
  2 件のコメント
Måns
Måns 2023 年 3 月 23 日
Hi, Thank you for your reply. Yes the list can become fairly long, at the moment I was working on a 49 rows long matrix but it can be up towards ~800 rows long. The values will generally be in the range of 70-230.
I tried it out and it took about 10 seconds but it seems to work. Thank you very much!
Adam Danz
Adam Danz 2023 年 3 月 23 日
If the values sufficiently vary, a permutation that satisfies the constraints should be found quickly. For example, if all values are unique, the first permutation will be accepted.

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

その他の回答 (1 件)

Cameron
Cameron 2023 年 3 月 22 日
A = randi(100,5,8);
A
A = 5×8
53 42 74 79 12 36 34 40 67 49 33 93 83 60 86 45 48 93 26 6 31 41 66 64 18 12 64 87 4 30 59 36 76 96 71 46 28 97 40 42
[~,randrow] = sort(rand(size(A,1),1));
RandA = A(randrow,:)
RandA = 5×8
18 12 64 87 4 30 59 36 76 96 71 46 28 97 40 42 53 42 74 79 12 36 34 40 48 93 26 6 31 41 66 64 67 49 33 93 83 60 86 45

カテゴリ

Help Center および File ExchangeParallel Computing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by