Skip to content

Instantly share code, notes, and snippets.

@Commoble
Last active June 30, 2020 15:39
Show Gist options
  • Save Commoble/ddcf3c2a7674e85ea6a8567e75d76b93 to your computer and use it in GitHub Desktop.
Save Commoble/ddcf3c2a7674e85ea6a8567e75d76b93 to your computer and use it in GitHub Desktop.
Random Permutation Generator
/**
* 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;
}
@lilypuree
Copy link

Shouldn't it be possibillities instead of permutationsize inside the if statement inside the first for loop?

@Commoble
Copy link
Author

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