I want to create a list of n random integers from 1 to m, where all integers have to be at least a certain distance min apart (i.e. 3 integers out of Range[10], keeping a minimum distance of 2)
This is the module I created to fullfill that purpose:
StartGen[MinimalDistance_] := Module[{nCells, min,test,i,j,r}, min = MinimalDistance; (*Just create a Random Sample from Range[m] if min=0 is chosen*) If[min == 0, nCells = Sort[RandomSample[Range[m], n]]; Return[nCells] , nCells = Table[0, n]; nCells[[1]] = RandomInteger[m]; i = 1; j = 1; (*Only execute if n integers out of m actually can keep a minimum distance of min*) If[m/(n (min + 1)) >= 1, While[i <= n, (*Generate random integers from Range[m] until one fits with the already assigned Integers*) r = RandomInteger[m]; test = True; Do[If[Abs[nCells[[j]] - r] <= min, test = False; Break[], test = True], {j, i} ]; If[test == True, nCells[[i]] = r; i++, Null]; ]; nCells = Sort[nCells]; Return[nCells]; , Print["Impossible figuration for m n and min"]; ]; ]; ];
Now the performance problem this creates is quite obvious: If the number of possible integers m and the minimum distance min are too big, as the While loop goes on fewer and fewer generated integers will fit the requirements and it gets harder and harder to hit those few integers through generating random numbers out of Range[m]. (For me this module couldn't produce lists for n=100,m=1000,min=8.)
I think the solution to this problem lies in reducing the number of Integers to choose from as the calculation go on, i.e. eliminate integers that dont fit the requirements anymore.
I tried implementing this with some variants of the DeleteCases[] function but I always ended up just creating more iterative calculations that would worsen the performance once again.
Is there an elegant way to do this?