Java 用随机数填充矩阵,不垂直或水平重复
这是一个更符合逻辑的问题。问题是: 我需要用数字(1-9)填充矩阵,以便:Java 用随机数填充矩阵,不垂直或水平重复,java,algorithm,sudoku,Java,Algorithm,Sudoku,这是一个更符合逻辑的问题。问题是: 我需要用数字(1-9)填充矩阵,以便: 第行中不应重复任何数字 列中不应重复任何数字 矩阵可以是3X3到8X8 矩阵应该包含非特定顺序的随机数 我不擅长逻辑,我试过的是: public class RandMatrix { static int max=8; static ArrayList<Integer> numbers=new ArrayList<>(); static int[][] arr=new int[max][max]
public class RandMatrix {
static int max=8;
static ArrayList<Integer> numbers=new ArrayList<>();
static int[][] arr=new int[max][max];
public static void main(String[] a){
// To fill number
for (int i = 1; i <=9; i++) {
numbers.add(i);
}
// Shuffle number
Collections.shuffle(numbers);
call();
}
public static void call(){
for (int i = 0; i < max; i++) {
for (int j = 0; j <max ; j++) {
for (int k = 0; k <max ; k++) {
int num=numbers.get(k);
if(!isExist(num,i,j)){
arr[i][j]=num;
break;
}
}
}
Collections.shuffle(numbers);
}
}
private static boolean isExist(int num,int row, int col){
for (int i = row; i >=0; i--) {
if(arr[i][col]==num){
return true;
}
}
for (int j = col; j >=0; j--) {
if(arr[row][j]==num){
return true;
}
}
return false;
}
}
公共类矩阵{
静态int max=8;
静态ArrayList编号=新ArrayList();
静态int[]arr=新int[max][max];
公共静态void main(字符串[]a){
//填
对于(inti=1;i给它一个疯狂的机会,不是写代码,而是思考:
开始按列填写数字,这样可以吗
mat[0][0]=1
mat[1][0]=2
...
mat[8][0]=9
然后,开始填充下一列时,请执行以下操作:
mat[1][1]=1
mat[2][1]=2
...
mat[8][1]=8
mat[0][1]=9
等等
因此,它精确地按顺序和对角线填充数字。使用纯随机填充矩阵,如果到达死角,则需要重做结果的最后一部分
public static void call(){
int repeats = 0;
for (int i = 0; i < max; i++) {
for (int j = 0; j <max ; j++) {
for (int k = 0; k <max ; k++) {
int num=numbers.get(k);
if(!isExist(num,i,j)){
arr[i][j]=num;
break;
}
}
}
if(containsZero(arr[i]){
i--;
repeats++;
if(repeats > 1000){
i = 0;
repeats = 0;
}
}
Collections.shuffle(numbers);
}
}
private static boolean containsZero(int[] array){
for(int i = 0; i < array.length; i++){
if(array[i] == 0){
return true;
}
}
return false;
}
publicstaticvoid调用(){
int repeats=0;
对于(int i=0;i 对于(int j=0;j在启动期间定义以下矩阵:
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8
需要创建n X n矩阵时,请执行以下操作:
随机选取0-8之间的N个数字(不重复)作为行号->R
为列编号->C随机选择0-8(无重复)之间的N个数字
最终矩阵的元素将是M[x][y]=O[R[x]][C[y]]
唯一的问题是结果仍然不是完全随机的。(它不能生成所有可能的解决方案。)尽管随机性仅在标题中提到,但在3个要求中没有提到…我认为最好的方法是使用随机回溯算法
矩阵的元素一个接一个地填充。对于每个矩阵元素,我们首先枚举所有可以使用的剩余整数(基于前面的元素)。然后以随机顺序尝试每个整数,直到找到第一个解
public static void main(String[] args) {
int[][] matrix = getMatrix(7, 0L);
if (matrix != null) {
for (int row = 0; row < 7; ++row) {
for (int column = 0; column < 7; ++column) {
System.out.print(matrix[row][column]);
}
System.out.println();
}
}
}
public static int[][] getMatrix(int size, long seed) {
int[][] matrix = new int[size][size];
Random random = new Random(seed);
if (!backtrack(matrix, size, 0, random))
return null;
return matrix;
}
// returns true when the backtracking could succesfully fill the matrix
private static boolean backtrack(int[][] matrix, int size, int index, Random random) {
if (index == size * size) {
// all elements are filled without conflict
return true;
} else {
// find the row and column of the next element which need to be filled
int column = index % size;
int row = index / size;
// an array which indicates whether the numbers in range [1 - 9] can be used
// canUse[x] encodes whether number (x+1) can be used
boolean[] canUse = new boolean[9];
Arrays.fill(canUse, true);
// check the previous rows and column elements
for (int c = 0; c < column; ++c)
canUse[matrix[row][c] - 1] = false;
for (int r = 0; r < row; ++r)
canUse[matrix[r][column] - 1] = false;
// generate the list of possible entries
List<Integer> possibilities = new ArrayList<Integer>();
for (int i = 1; i <= 9; ++i)
if (canUse[i - 1])
possibilities.add(i);
// backtrack if there are no possible entries
if (possibilities.isEmpty())
return false;
// shuffle the list (to randomly fill the matrix)
Collections.shuffle(possibilities, random);
// enter the number
for (int possiblity : possibilities) {
matrix[row][column] = possiblity;
if (backtrack(matrix, size, index + 1, random))
return true;
}
return false;
}
}
我刚才保存并修改了一些代码,以便在需要其他时间时使用。我想这是为您准备的;)
更简单的方法是首先编写一个明显满足要求的数组(例如[[1,2,3],[3,1,2],[2,3,1]]
)然后随机交换行,随机交换列。这显然满足了要求
这将是硬编码的。这种安排是一种数独游戏,所以我认为你的建议可能是正确的。因为只有一些解决方案可以按照你的方式使用。但我需要在运行时填充数组。那么我如何填充我不能满足要求?这是我的问题。我想不出一个办法。我需要一个数学天才给我一些指导,但我肯定不是。这几乎很好。但这样的数字不会是随机的。我列出的方法(最终)生成满足条件的所有数组,其“随机性”与尝试按数字填充数组一样。@HighPerformanceMark您的方法对我来说有意义。请尝试一下。建议使用Thx。我不认为先填充collum会有任何区别。无论如何,我会尝试一下。您测试过吗?关键在于此,因此,精确地按顺序和对角线填充数字
。按列或按行填充并不重要。用笔和纸就足够了:)是的,你说对了,死胡同是我的问题。我会试试你的解决方案。好吧。那太令人印象深刻了。我会深入研究你的代码。会马上回来。谢谢。@ADM我只是想知道数独和这个问题之间是否有关系??
4139562
1896375
2613857
9357124
6245931
3482619
8761493
import java.util.Arrays;
import java.util.Random;
class Test {
public static void main(String[] args){
int size = 9;
int[][] matrix= new int[size][];
matrix[0] = MatrixOps.createOrderedArray(size, 1);
for(int x=0; x < size; x++) {
matrix[x] = MatrixOps.createOrderedArray(size, 1);
do {
MatrixOps.shuffle(matrix[x]);
} while(! MatrixOps.compare2DArray(matrix[x], matrix, 0, x));
}
MatrixOps.print(matrix);
}
}
class MatrixOps {
public static void shuffle(int[] arr){
Random random = new Random();
for(int x = 0; x < arr.length; x++)
swap(arr, x, random.nextInt(arr.length));
}
public static int[] createOrderedArray(int size, int startValue) {
int[] num = new int[size];
for (int x = 0; x < num.length; x++)
num[x] = x + startValue;
return num;
}
public static boolean compare2DArray(int[] arr1, int[][] arr2, int begin, int end) {
for (int x = begin; x < end; x++)
if (!compareArray(arr1, arr2[x]))
return false;
return true;
}
// https://stackoverflow.com/questions/19648240/java-best-way-to-print-2d-array/41533179#41533179
public static void print(int[][] array) {
for (int[] x: array) {
for (int y: x) {
System.out.print(y + " ");
}
System.out.println();
}
}
private static boolean compareArray(int[] arr1, int[] arr2){
if(arr1.length != arr2.length)
return false;
for(int x=0; x<arr1.length; x++)
if(arr1[x] == arr2[x])
return false;
return true;
}
private static void swap(int[] arr, int a, int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
5 1 7 2 3 8 9 4 6
4 3 1 5 7 9 2 6 8
9 7 3 8 6 2 4 5 1
6 8 4 3 5 7 1 9 2
1 5 8 9 2 6 7 3 4
7 9 2 6 4 1 5 8 3
8 6 9 4 1 5 3 2 7
3 2 6 7 9 4 8 1 5
2 4 5 1 8 3 6 7 9