So let's say I want to generate an array a[] of n random integers between 0 and n (exclusive) which do not repeat. But I also want to ensures that abs(a[i]-a[i+1]) < maxRange. Wrap around should be permitted so that
abs(a[i]-(a[i+1]+a.length)) < maxRange || abs((a[i]+a.length)-a[i+1]) || abs(a[i]-a[i+1]) < maxRange.
is always true. For example if n=6, and maxRange =2 then the array a={1,3,2,4,0,5} is valid because 3-1 = 2, 3-2 = 1, 4-2 = 2, (0+n)-4 = 2, and (0+n)-5 = 1.
But a={0,3,2,4,1,5} is not valid because 3-0=3 and 4-1=3.
The distribution of differences abs(a[i]-(a[i+1]+a.length)) should be uniform and within the range 1 to maxRange
I feel like there must already be an algorithm out there that does this but I can't seem to find it by googling (perhaps I'm using incorrect terminology). The only way I can think to implement this is to brute force search every possible permutation and checking if the criteria is met to determine valid permutations and then choosing one of those at random. However for longer arrays this could become extremely computationally expensive. Perhaps it is better to think of this as a non-repeating random walk or something. But I'm not sure how it could be implemented as such. Any ideas? A language-agnostic solution would be great.
To give a little extra information I want to use this to perform tournament selection in a genetic algorithm with trivial geography or demes. So for example individuals a[0] and a[1] will undergo a tournament (chooses winner based on fitness) and the loser will get crossed-over/replaced. Then a[2] and a[3] etc. The reason I want to do it like this is so that I can evaluate all individuals in one go, then do the crossover stage in one go, then repeat these stages until finish. The reason I want to do it like this is so I can guarantee every individual has been evaluated at every generation, unlike a typical steady-state genetic algorithm.
Aucun commentaire:
Enregistrer un commentaire