So I'm using a preference matrix (2d array) within my program, in which each person ranks the other members from most favorable to least favorable. The individual ranks themselves last in the array.
For example:
{[1, 2, 3, 4, 5, 0],
[2, 3, 4, 5, 0, 1],
[3, 4, 5, 0, 1, 2],
[4, 5, 0, 1, 2, 3],
[5, 0, 1, 2, 3, 4],
[0, 1, 2, 3, 4, 5]}
How can I randomly generate a matrix like the one above, where the last element represents the user's number 0-n and the remaining n-1 elements are arbitrary numbers in a random sequence?
You can use Collections.shuffle(list)
to shuffle any list, but bizarrely, the java API does not have an Arrays.shuffle(arr)
, and turning an int[]
into a collection so you can feed it to Collections.shuffle
is rather inefficient.
For sets as large as you have, that really doesn't matter; that only becomes an issue once we're talking about 100,000 numbers or more.
So, the easy, readable way, is to make a list of all elements except the person's own index, shuffle that, toss the user's index at the very end, and voila:
public int[][] makeRandom(int n) {
int[][] out = new int[n][];
for (int i = 0; i < n; i++) { // for each person
// make a list of their preferences
List<Integer> list = new ArrayList<Integer>();
for (int j = 0; j < n; j++) {
// add everybody except yourself
if (j != i) list.add(j);
}
Collections.shuffle(list); // randomize
list.add(i); // add yourself
// turn into an int array
int[] arr = list.stream().mapToInt(Integer::intValue).toArray();
// set the int array, representing person i's prefs.
out[i] = arr;
}
return out;
}
If you really do need an algorithm that runs as efficient as can be, you'd have to make a new instance of java.util.Random
, and use its .nextInt()
method so that you can apply the Fisher-yates shuffle algorithm yourself, in-place, on an existing int array list, even conveniently skipping the very last number in the array during your shuffle. That'd be a lot more code that requires a lot more convoluted comments. By all means, feel free, but I'll leave that as an exercise to the reader.