Generate random non-repeating integers from a smal

2019-02-10 05:12发布

问题:

What I'm trying to accomplish is the following:

I wish to create a vector of integers, from a relatively small range, and ensure that none of the integers will be followed by the same integer.

i.e., This is a "legal" vector: [ 1 3 4 2 5 3 2 3 5 4 ]

and this is an "illegal" vector (since 5 follows 5): [ 1 3 4 2 5 5 2 3 5 4 ]

I've experimented with randi, and all sorts of variations with randperm, and I always get stuck when i try to generate a vector of around 100 elements, from a small range (i.e., integers between 1 and 5).

The function just runs for too long.

Here's one of the attempts that i've made:

function result = nonRepeatingRand(top, count)

    result = randi(top, 1, count);

    while any(diff(result) == 0)
         result = randi(top, 1, count);    
    end

end

Any and all help will be much appreciated. Thanks !

回答1:

The kind of sequence you are looking for can be defined by generating differences from 1 to top - 1 and then computing the cumulative sum modulus top, starting from a random initial value:

function result = nonRepeatingRand(top, count)

    diff = randi(top - 1, 1, count);
    result = rem(cumsum(diff) + randi(1, 1, count) - 1, top) + 1;

end

On my machine, this generates a non-repeating sequence of 10 million numbers out of 1:5 in 0.58 seconds.



回答2:

you can use the following code for generate Non Repeating Random Numbers from 1 to M

randperm(M);

and for K Non Repeating Random Numbers from 1 to M

randperm(M, K);

enjoy



回答3:

Do not regenerate the sequence every time, but fix the repetitions. E.g.:

function result = nonRepeatingRand(top, count)

    result = randi(top, 1, count);

    ind = (diff(result) == 0);
    while any(ind)
        result(ind) = [];
        result(end + 1 : count) = randi(top, 1, count - numel(result));

        ind = (diff(result) == 0);
    end

end

On my machine, this generates a non-repeating sequence of 10 million numbers out of 1:5 in 1.6 seconds.



回答4:

How this?

top = 5;
count = 100;
n1 = nan;
out = [];
for t = 1: count 
    n2 = randi(top);
    while n1 == n2
        n2 = randi(top);
    end
    out = [out, n2];
    n1 = n2;
end


回答5:

Is there the possible option to create this "random" sequence without repetitions, so that all values are equally distributed (as with randperm)?

randperm seems to limited, and I can only think of calling the first functions in a while loop, until my "equal distribution critereon" is met.. but can it be done quicker?



标签: matlab random