我正试图找到一种方法来填充长度为n的2d数组,其中布尔值是随机的。如果n是偶数,则数组必须具有相等数量的每个值,并且如果n是奇数,则额外值必须每次都是相同的布尔值(无关紧要)。有关如何在Java中执行此操作的任何提示?我目前正在使用相同数量的两个值来改变阵列,但这并不是真正随机的,因为总是有n / 2(或n / 2 + 1和n / 2-1,奇数ns)每个值。
有什么建议吗?
答案 0 :(得分:1)
根据您的要求,使用您需要的数量填充阵列,然后将其洗牌,这是一个很好的解决方案。
确保使用真正随机的混洗算法,例如Fisher-Yates shuffle,而不是“多次交换随机对”方法。如果您使用Collections.shuffle
或类似内容,则无需担心此问题。
答案 1 :(得分:0)
将Fisher-Yates shuffle调整为2D数组可能是最简单的方法。
boolean[][] array = new boolean[rows][cols];
boolean alternating = false;
Random random = new Random();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int k = random.nextInt(i * cols + j + 1);
int swapRow = k / cols;
int swapCol = k % cols;
boolean tmp = array[swapRow][swapCol];
array[swapRow][swapCol] = alternating;
array[i][j] = tmp;
alternating = !alternating;
}
}
这几乎是http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_.22inside-out.22_algorithm的逐字实现,除了我们在愚蠢和真实地填充数组时。
答案 2 :(得分:0)
另一种方法可能是将您放置下一个值而不是值本身的位置随机化。您提前知道您正在放置的每个值中有多少。
类似的东西:
List<Integer> indicesList = IntStream.range(0, n * n).collect(Collectors.toList());
Collections.shuffle(indicesList);
indicesList.stream().forEach(n -> array[n % size][n / size] = (n % 2 == 0));
根据我的理解,应该让您完全随意放置您的值和相同数量的每个。
答案 3 :(得分:0)
这是一个同事想出的真正简单的解决方案。在我看来它会起作用并且是真正的随机(如果没有,请告诉我,我对这种事情有可怕的直觉),尽管它绝对是丑陋的。与我想象的洗牌相比,效率会非常高。
public boolean[][] generateRandom2dBooleanArray(int length) {
int numFalses = (length*length)/2;
int numTrues = (length*length)/2;
if ((length*length)%2!=0) numTrues++;
boolean[][] array = new boolean[length][length];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (Math.random() > 0.5) {//Or is it >= 0.5?
if (numTrues >= 0) {
array[i][j] = true;
numTrues--;
} else {
//Since boolean arrays are false by default, you could probably just break here to get the right anser, but...
array[i][j] = false;
numFalses--;
}
} else {
if (numFalses >= 0) {
array[i][j] = false;
numFalses--;
} else {
array[i][j] = true;
numTrues--;
}
}
}
}
}
return array;
}