Tricky randomization issue - help needed!

5 views (last 30 days)
Dear Matlab folks,
I am struggling with the following issue:
I created 80 parings of numbers. These pairings should stay the same but the order of the pairings should be randomized.
So, I have a variable containing these pairings: sequence = [pairing_1 pairing_2 pairing_3 and so forth].
How can I randomize the order of these pairings? For example, it would look like this then: randomized_sequence = [pairing_2 pairing_3 pairing_1 .....]
And now for the tricky part:
The numbers of the pairings reach from 1 to 40. Every number from 1 to 40 is combined with one random even number between 1 and 40 and one random uneven number between 1 and 40. For 1, I could have the pairings 1 & 18 and 1 & 9 for example. But 1 must not be paired with 1! No number can be matched with itself. Furthermore, 1 must not be paired with 2 and 2 must not be paired with 1, the sequence doesn't matter. 3 must not be paired with 4, 5 must not be paired with 6 and so forth until 39 must not be paired with 40 and every time, the sequence doesn't matter. So, 39 and 40 is not possible as well as 40 and 39.
The numbers that must not be paired are:
1 2 | 3 4 | 5 6 | 7 8 | 9 10 | 11 12 | 13 14 | 15 16 | 17 18 | 19 20 | 21 22 | 23 24 | 25 26 | 27 28 | 29 30 | 31 32 | 33 34 | 35 36 | 37 38 | 39 40
So 2 and 3 can be paired, for example!
Now the problem is, if I have these 2 pairings 14 16 and 16 9 and after the shuffling of the pairings 14 16 lands before 16 9 then I have a 16 16 pairing as well which must not happen. Such unwanted pairings can happen a lot through the shuffling. For example, the 14 of 14 16 must not be preceeded by 14 or 13 and the 16 of 14 16 must not be followed by 16 or 15.
I was thinking about maybe coding something like: "If 1 is followed/preceded by 1 or 2 then shuffle again. If 2 is followed/preceded by 1 or 2 then shuffle again. If 3 is followed/preceded by 3 or 4 then shuffle again...." and so forth until "If 40 is followed/preceded by 40 or 39 then shuffle again."
What do you think, is there a way to do it like that? Or even a way easier solution, I did not think about?
I very much appreciate any help, this is bothering me since quite some time now.
Thanks in advance,
Rupert
  7 Comments
Rupert Steinmeier
Rupert Steinmeier on 26 Aug 2020
No, the bars were just there to make it easier to see which numbers are meant as pairs!
My idea was to let Matlab check If 1 is followed/preceded by 1 or 2. If so, then shuffle again. If 2 is followed/preceded by 1 or 2 then shuffle again. If 3 is followed/preceded by 3 or 4 then shuffle again....and so forth until if 40 is followed/preceded by 40 or 39 then shuffle again.
This way Matlab would shuffle the sequence until it's valid. Of course, if there are only 6 numbers this might take a while. But with 40 numbers, there are many possibilities. What do you think of it?
Rik
Rik on 26 Aug 2020
It does take a while: 20370 tries if you shuffle the list, 884 tries if you don't.

Sign in to comment.

Accepted Answer

Rik
Rik on 26 Aug 2020
Edited: Rik on 10 Sep 2020
Because we now have a proper definition of the problem we can start writing the code for the solution:
rng(1)%set a random seed so the results are repeatable
N=6;%define the problem size here
all_ids=(1:N)';
odd=1:2:N;even=2:2:N;
% %these are the steps in the while condition:
% step1=sequence+mod(sequence,2);%'round' to an even number: [1 2 3] --> [2 2 4]
% step2=diff(step1);%find delta between each successive number
% step3=step2==0;%if the delta was zero, that means either [1 2] (or [2 1]) or [2 2]
% sequence_is_invalid=any(step3);%any invalid pair makes the whole sequence invalid
n=0;
sequence=[1 1];%enter loop by using an invalid sequence
while any(diff(sequence+mod(sequence,2))==0)
n=n+1;
pair_with_even=even(randi(end,N,1)).';
pair_with_odd=odd(randi(end,N,1)).';
list_of_pairs=[all_ids pair_with_odd;all_ids pair_with_even];
list_of_pairs([1:2:end 2:2:end],:)=list_of_pairs;
sequence=reshape(list_of_pairs.',1,[]);
end
clc,fprintf('generating the sequence below took %d tries\n',n),fprintf('%d ',sequence);fprintf('\n')
You can also shuffle the order of list_of_pairs:
shuffled=list_of_pairs(randperm(end),:);
  27 Comments
Rupert Steinmeier
Rupert Steinmeier on 22 Sep 2020
Just read your latest answer, thank you for your input!
Rupert Steinmeier
Rupert Steinmeier on 23 Sep 2020
I opened a new question!
Here's the link:
https://de.mathworks.com/matlabcentral/answers/598429-tricky-randomization-issue-who-can-help

Sign in to comment.

More Answers (1)

Mohammad Sami
Mohammad Sami on 25 Aug 2020
Edited: Rik on 25 Aug 2020
One option can be to generate a sequence longer then you need and then eliminate values until the sequence is valid. Thereafter you can take desired length of sequence. If it's shorter generate again and concatenate it.
DesiredLength = 200;
N = 2 * DesiredLength;
Seq = randi([1 40],N,1);
while(any(abs(diff(Seq))<=1))
I = [false;abs(diff(Seq)) <= 1];
Seq(I) = [];
if(length(Seq)<DesiredLength)
Seq = [Seq;randi([1 40],N,1)];
end
end
Final = Seq(1:DesiredLength);
  5 Comments
Mohammad Sami
Mohammad Sami on 26 Aug 2020
Based on your description I assumed that the sequence is valid if the absolute difference between two consecutive number is > 1. So the code is essentially checking if the sequence is valid in the while loop. If there is any value where the absolute difference is less then or equal to 1 it is removed. The if statement just checks if the sequence is longer then the length you need after removing invalid values. In that case it generates and append more data. The while loop will terminate once there is no invalid pairing left.
Rupert Steinmeier
Rupert Steinmeier on 26 Aug 2020
That is a very good idea, but the sequence can also be valid if the absolute difference between two numbers is 1. For example 2 can follow or precede 3, 4 can follow or precede 5, 6 can follow or precede 7 and so forth.
The numbers that must not be paired are:
1 2 | 3 4 | 5 6 | 7 8 | 9 10 | 11 12 | 13 14 | 15 16 | 17 18 | 19 20 | 21 22 | 23 24 | 25 26 | 27 28 | 29 30 | 31 32 | 33 34 | 35 36 | 37 38 | 39 40

Sign in to comment.

Categories

Find more on MATLAB Mobile Fundamentals in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!