Last active
June 30, 2020 15:39
-
-
Save Commoble/ddcf3c2a7674e85ea6a8567e75d76b93 to your computer and use it in GitHub Desktop.
Random Permutation Generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Returns an array of numbers [a0, a1, a2 ... a(n-1)] | |
* Where each number aX is unique, | |
* n is given by permutationSize, | |
* and the different possible numbers returnable are in the range [0, possibilities). | |
* | |
* Implements the algorithms given here | |
* https://stackoverflow.com/questions/158716/how-do-you-efficiently-generate-a-list-of-k-non-repeating-integers-between-0-and-n | |
* https://www.geeksforgeeks.org/generate-a-random-permutation-of-1-to-n/ | |
* | |
* Time efficiency is O(possibilities + permutationSize) | |
* Memory efficiency: Creates one array of size permutationSize and returns it | |
* | |
* @param possibilities The number of different numbers returnable. Must be greater than or equal to permutationSize. | |
* @param permutationSize The size of the array returned. Must be less than or equal to possibilities. | |
* @param rand A Random instance (a new Random() can be used if one is not already available) | |
* @return An array as described above. | |
*/ | |
public static int[] randomPermutation(final int possibilities, final int permutationSize, final Random rand) | |
{ | |
int[] permutation = new int[permutationSize]; | |
int resultSlotToFind=0; | |
int possibleResult=0; | |
// create an orderered combination | |
for (int i=0; i<possibilities; i++) | |
{ | |
possibleResult = rand.nextInt(possibilities-i); | |
if (possibleResult < permutationSize - resultSlotToFind) | |
{ | |
permutation[resultSlotToFind] = i; | |
resultSlotToFind++; | |
} | |
} | |
// shuffle it to form a permutation | |
// for each slot in the array, swap it with a random slot further ahead in the array (including itself) | |
for (int i=0; i<permutationSize; i++) | |
{ | |
int secondSlot = rand.nextInt(permutationSize - i) + i; | |
int swap = permutation[i]; | |
permutation[i] = permutation[secondSlot]; | |
permutation[secondSlot] = swap; | |
} | |
return permutation; | |
} |
Shouldn't it be possibillities instead of permutationsize inside the if statement inside the first for loop?
No, the first loop iterates over all possibilities to pick a random ordered subset from them (the "combination").
The combination is the correct size, but we want it to be in a random order; the second loop shuffles it to randomize the order (forming the permutation, which is what we want)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Shouldn't it be possibillities instead of permutationsize inside the if statement inside the first for loop?