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

9 ビュー (過去 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 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