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

2 vues (au cours des 30 derniers jours)
Måns le 22 Mar 2023
Modifié(e) : Adam Danz le 23 Mar 2023
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.
0 commentairesAfficher -2 commentaires plus anciensMasquer -2 commentaires plus anciens

Connectez-vous pour commenter.

Réponse acceptée

Adam Danz le 22 Mar 2023
Modifié(e) : Adam Danz le 23 Mar 2023
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 commentairesAfficher AucuneMasquer Aucune
Måns le 23 Mar 2023
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 le 23 Mar 2023
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.

Connectez-vous pour commenter.

Plus de réponses (1)

Cameron le 22 Mar 2023
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
0 commentairesAfficher -2 commentaires plus anciensMasquer -2 commentaires plus anciens

Connectez-vous pour commenter.

Catégories

En savoir plus sur Mathematics dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by