Matlab: Array of random integers with no direct repetition

怎甘沉沦 提交于 2021-02-19 05:22:08

问题


For my experiment I have 20 categories which contain 9 pictures each. I want to show these pictures in a pseudo-random sequence where the only constraint to randomness is that one image may not be followed directly by one of the same category. So I need something similar to

r = randi([1 20],1,180);

just with an added constraint of two numbers not directly following each other. E.g.

14 8 15 15 7 16 6 4 1 8 is not legitimate, whereas

14 8 15 7 15 16 6 4 1 8 would be.

An alternative way I was thinking of was naming the categories A,B,C,...T, have them repeat 9 times and then shuffle the bunch. But there you run into the same problem I think? I am an absolute Matlab beginner, so any guidance will be welcome.


回答1:


The following uses modulo operations to make sure each value is different from the previous one:

m = 20; %// number of categories
n = 180; %// desired number of samples
x = [randi(m)-1 randi(m-1, [1 n-1])];
x = mod(cumsum(x), m) + 1;

How the code works

  • In the third line, the first entry of x is a random value between 0 and m-1. Each subsequent entry represents the change that, modulo m, will give the next value (this is done in the fourth line).
  • The key is to choose that change between 1 and m-1 (not between 0 and m-1), to assure consecutive values will be different. In other words, given a value, there are m-1 (not m) choices for the next value.
  • After the modulo operation, 1 is added to to transform the range of resulting values from 0,...,m-1 to 1,...,m.

Test

Take all (n-1) pairs of consecutive entries in the generated x vector and count occurrences of all (m^2) possible combinations of values:

count = accumarray([x(1:end-1); x(2:end)].', 1, [m m]);
imagesc(count)
axis square
colorbar

The following image has been obtained for m=20; n=1e6;. It is seen that all combinations are (more or less) equally likely, except for pairs with repeated values, which never occur.

enter image description here




回答2:


You could look for the repetitions in an iterative manner and put new set of integers from the same group [1 20] only into those places where repetitions have occurred. We continue to do so until there are no repetitions left -

interval = [1 20]; %// interval from where the random integers are to be chosen
r = randi(interval,1,180); %// create the first batch of numbers

idx = diff(r)==0; %// logical array, where 1s denote repetitions for first batch
while nnz(idx)~=0
    idx = diff(r)==0; %// logical array, where 1s denote repetitions for
                      %// subsequent batches
    rN = randi(interval,1,nnz(idx)); %// new set of random integers to be placed
                             %// at the positions where repetitions have occured
    r(find(idx)+1) = rN; %// place ramdom integers at their respective positions
end


来源:https://stackoverflow.com/questions/26844396/matlab-array-of-random-integers-with-no-direct-repetition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!