首页 > 解决方案 > 在 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 个元素是随机序列中的任意数字?

标签: javaarraysmatrixrandomgenerate

解决方案


您可以使用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 数组列表,甚至可以在随机播放期间方便地跳过数组中的最后一个数字。那将是更多的代码,需要更多复杂的注释。无论如何,请随意,但我会将其作为练习留给读者。


推荐阅读