Ordered random numbers in Matlab

2019-07-22 19:00发布

问题:

I am trying to generate random numbers between 1 and 5 using Matlab's randperm and calling randperm = 5.

Each time this gives me a different array let's say for example:

x = randperm(5)
x = [3 2 4 1 5]

I need the vector to be arranged such that 4 and 5 are always next to each other and 2 is always between 1 and 3... so for e.g. [3 2 1 4 5] or [4 5 1 2 3].

So essentially I have two "blocks" of unequal length - 1 2 3 and 4 5. The order of the blocks is not so important, just that 4 & 5 end up together and 2 in between 1 and 3.

I can basically only have 4 possible combinations:

[1 2 3 4 5]

[3 2 1 4 5]

[4 5 1 2 3]

[4 5 3 2 1]

Does anyone know how I can do this?

Thanks

回答1:

You can generate each block and shuffle each one then and set them as members of a cell array and shuffle the cell array and finally convert the cell array to a vector.

b45=[4 5];                                        % block 1
b13=[1 3];                                        % block 2
r45 = randperm(2);                                % indices for shuffling block 1
r13 = randperm(2);                                % indices for shuffling block 2
r15 = randperm(2);                                % indices for shuffling the cell
blocks = {b45(r45) [b13(r13(1)) 2 b13(r13(2))]};  % shuffle each block and set them a members of a cell array
result = [blocks{r15}]                            % shuffle the cell and convert to a vector


回答2:

I'm not sure if you want a solution that would somehow generalize to a larger problem, but based on how you've described your problem above it looks like you are only going to have 8 possible combinations that satisfy your constraints:

possible = [1 2 3 4 5; ...
            1 2 3 5 4; ...
            3 2 1 4 5; ...
            3 2 1 5 4; ...
            4 5 1 2 3; ...
            5 4 1 2 3; ...
            4 5 3 2 1; ...
            5 4 3 2 1];

You can now randomly select one or more of these rows using randi, and can even create an anonymous function to do it for you:

randPattern = @(n) possible(randi(size(possible, 1), [1 n]), :)

This allows you to select, for example, 5 patterns at random (one per row):

>> patternMat = randPattern(5)

patternMat =

     4     5     3     2     1
     3     2     1     4     5
     4     5     3     2     1
     1     2     3     5     4
     5     4     3     2     1