java - 在 Java 中生成随机矩阵的最佳方法
问题描述
所以我在我的程序中使用了一个偏好矩阵(二维数组),其中每个人将其他成员从最有利到最不利排列。个人将自己排在数组的最后。
例如:
{[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]}
如何随机生成一个像上面那样的矩阵,其中最后一个元素代表用户的数字 0-n,其余 n-1 个元素是随机序列中的任意数字?
解决方案
您可以使用Collections.shuffle(list)
shuffle 任何列表,但奇怪的是,java API 没有 an Arrays.shuffle(arr)
,并且将 anint[]
转换为集合以便您可以将其提供给它Collections.shuffle
是相当低效的。
对于像你这样大的集合,这真的无关紧要。只有当我们谈论 100,000 个或更多数字时,这才会成为一个问题。
因此,简单易读的方法是列出除此人自己的索引之外的所有元素的列表,将其打乱,最后扔掉用户的索引,瞧:
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;
}
如果你真的需要一个尽可能高效运行的算法,你必须创建一个新的实例java.util.Random
,并使用它的.nextInt()
方法,这样你就可以自己应用Fisher-yates shuffle 算法,就地,在现有的int 数组列表,甚至可以在随机播放期间方便地跳过数组中的最后一个数字。那将是更多的代码,需要更多复杂的注释。无论如何,请随意,但我会将其作为练习留给读者。