I know that it is not a good idea to just provide the code, but I was intrigued by this question. Here's how I do it:
$d = 0.3; $random = array(); // Populate the original array for ($n=1; $n <= 10; $n++) { $arr[] = $n; } $count = count($arr); // Loop through array foreach (array_keys($arr) as $key) { if (!isset($prev_key)) { $prev_key = array_rand($arr); } $possibles = array(); // This stores the possible values echo "Trying: $prev_key"; echo ":\n"; // Loop through the array again and populate $possibles with all possible // values based on the previous values foreach (array_keys($arr) as $n) { if ($arr[$n] < $prev_key - $count * $d || $arr[$n] > $prev_key + $count * $d) { $possibles[] = $n; echo $arr[$n]." is valid\n"; } else { echo $arr[$n]; echo " outside range\n"; } } // If there is nothing outside that range, just return the remaining values if (count($possibles) == 0) { $possibles = array_keys($arr); echo "Nothing within range so just returning whole array\n"; } echo "\n"; // Choose random value from the possible values array $rand_key = $possibles[array_rand($possibles)]; $random[] = $arr[$rand_key]; $prev_key = $arr[$rand_key]; // Unset this value from the original array since we can only use the // values once unset($arr[$rand_key]); } print_r($random);
This will create the following form:
Trying: 8: 1 is valid 2 is valid 3 is valid 4 is valid 5 outside range 6 outside range 7 outside range 8 outside range 9 outside range 10 outside range Trying: 2: 1 outside range 3 outside range 4 outside range 5 outside range 6 is valid 7 is valid 8 is valid 9 is valid 10 is valid Trying: 9: 1 is valid 3 is valid 4 is valid 5 is valid 6 outside range 7 outside range 8 outside range 10 outside range Trying: 5: 1 is valid 3 outside range 4 outside range 6 outside range 7 outside range 8 outside range 10 is valid Trying: 10: 1 is valid 3 is valid 4 is valid 6 is valid 7 outside range 8 outside range Trying: 4: 1 outside range 3 outside range 6 outside range 7 outside range 8 is valid Trying: 8: 1 is valid 3 is valid 6 outside range 7 outside range Trying: 3: 1 outside range 6 outside range 7 is valid Trying: 7: 1 is valid 6 outside range Trying: 1: 6 is valid Array ( [0] => 2 [1] => 9 [2] => 5 [3] => 10 [4] => 4 [5] => 8 [6] => 3 [7] => 7 [8] => 1 [9] => 6 )
The only drawback is that since it randomly receives strings, there is a possibility that the values near the end may not be outside the given range. According to my tests, this happens by about 4%, using the above values of $d = 0.25 and 1000. One way to get around this is to simply paste these values into random places, and not add them as I did.
Also note: this method is not so efficient. It should go through the count($arr) ^ 2 array count($arr) ^ 2 times. So for 1000 values you are looking at 1,000,000 iterations. Fortunately, the array is getting smaller.
source share