Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生成一个3x3幻方_Java_Magic Square - Fatal编程技术网

Java 生成一个3x3幻方

Java 生成一个3x3幻方,java,magic-square,Java,Magic Square,我正在使用的3x3魔方中充满了数字1-9。每行、每列和每对角线中的值必须相加到15。我必须遵循以下伪代码: recursive_funtion(position) { for number from 1 to 9, not used elsewhere already { put this number on this position, make it unavailable if solution valid {

我正在使用的3x3魔方中充满了数字1-9。每行、每列和每对角线中的值必须相加到15。我必须遵循以下伪代码:

recursive_funtion(position) {  
    for number from 1 to 9, not used elsewhere already {  
        put this number on this position, make it unavailable  
        if solution valid {  
            if solution complete {  
                done, show solution  
            }else{  
                recursive_function(next_position)  
            }  
        }  
        (make this space blank again, and the number available)  
    }  
} 
我让它一直工作,直到它通过第一行,并意识到在左上角点添加1,在中上角点添加2后,无法在该行中添加15。有人能看到我在哪里犯了错误,或者能填写我遗漏的任何逻辑吗?谢谢

public class MagicSquare {

    private int[][] magicSquare;
    private boolean[] available;

    public MagicSquare() {
        magicSquare = new int[3][3];
        available = new boolean[9];
        for (int i = 0; i < available.length; i++) {
            available[i] = true;
        }
    }

    public void run() {
        System.out.println("Magic Square Puzzle");
        solve(0, 0);
    }

    public boolean solve(int row, int col) {
    for (int i = 1; i <= 9; i++) {
        if (isAvailable(i)) {
            System.out.println("placing " + i + " at (" + row + ", " + col + ")");
            magicSquare[row][col] = i;
            available[i - 1] = false;
            //solution is valid so far
            if (isFilledRow(row)) {
                if (isValidRow(row) && isValidCol(col)) {
                    if (solve(row, col)) {
                        return true;
                    } else {
                        magicSquare[row][col] = 0;
                        magicSquare[row][col - 1] = 0;
                        col = col - 1;
                        available[magicSquare[row][col] - 1] = false;
                        solve(row, col);
                    }
                }
            }
            if (!isFilledRow(row)) { //check logic here!
                if (isValidSolution()) {
                    System.out.println("You found a correct solution!");
                    printSolution();
                } else {
                    //new row
                    if (col == 2 && row != 2) {
                        row = row + 1;
                        System.out.println("new row and solve(" + row + ", " + col + ")");
                        solve(row, 0);
                        //new col    
                    } else if (col != 2) {
                        col = col + 1;
                        System.out.println("new col and solve(" + row + ", " + col + ")");
                        solve(row, col);
                    } else if (row == 2 && col == 2) {
                        //check logic here!

                    }
                }
            } 
            magicSquare[row][col] = 0;
            available[i - 1] = true;
        }
    }
    return false;
}

    public boolean isAvailable(int value) {
        if (available[value - 1] == true) {
            System.out.println(value + " is available to be placed");
            return true;
        } else {
            System.out.println(value + " is not available to be placed");
            return false;
        }
    }

    public boolean isFilledRow(int row) {
        if (magicSquare[row][0] != 0 && magicSquare[row][1] != 0 && magicSquare[row][2] != 0) {
            System.out.println("row " + row + " is filled");
            return true;
        } else {
            //System.out.println("row " + row + " is not filled");
            return false;
        }

    }

    public boolean isValidRow(int row) {
        if (magicSquare[row][0] + magicSquare[row][1] + magicSquare[row][2] == 15) {
            System.out.println("row " + row + " adds to 15");
            return true;
        } else {
            System.out.println("row " + row + " does not add to 15");
            return false;
        }
    }

    public boolean isValidCol(int col) {
        if (magicSquare[0][col] + magicSquare[1][col] + magicSquare[2][col] == 15) {
            System.out.println("col " + col + " adds to 15");
            return true;
        } else {
            //System.out.println("col " + col + " does not add to 15");
            return false;
        }
    }

    public boolean isValidOnDiagonals() {
        if ((magicSquare[0][0] + magicSquare[1][1] + magicSquare[2][2] == 15) && (magicSquare[2][0] + magicSquare[1][1] + magicSquare[0][2] == 15)) {
            System.out.println("diagonals add to 15");
            return true;
        } else {
            //System.out.println("diagonals don't add to 15");
            return false;
        }
    }

    public boolean isValidSolution() {
        for (int i = 0; i < magicSquare.length; i++) {
            if (isValidRow(i) && isValidCol(i) && isValidOnDiagonals()) {
                System.out.println("solution is valid");
                return true;
            }
        }
        //System.out.println("solution is not valid");
        return false;
    }

    public void printSolution() {
        for (int i = 0; i < magicSquare.length; i++) {
            for (int j = 0; j < magicSquare[i].length; j++) {
                System.out.print(magicSquare[i][j] + " ");
            }
            System.out.println();
        }
    }
}
公共类MagicSquare{
私人int[][]magicSquare;
私有布尔[]可用;
公共魔法广场(){
magicSquare=新整数[3][3];
可用=新布尔值[9];
for(int i=0;i
  • isValidSolution()
    可以返回
    true
    ,即使平方无效
  • 您的
    solve()
    方法的逻辑有点太复杂了。我试图简化它
  • 有这么多的
    System.out.println
    语句实际上对算法的执行时间有很大的影响。所以我注释掉了其中的大部分
我相信你可以不断改进,目前,它在找到第一个解决方案后不会停止。它实际上会打印出所有的解决方案

希望您能利用此功能更接近最终/完善的算法:

public class MagicSquare {

    private int[][] magicSquare;
    private boolean[] available;

    public MagicSquare() {
        magicSquare = new int[3][3];
        available = new boolean[9];
        for (int i = 0; i < available.length; i++) {
            available[i] = true;
        }
    }

    public void run() {
        System.out.println("Magic Square Puzzle");
        solve(0, 0);
    }

    public void solve(int row, int col) {
    for (int i = 1; i <= 9; i++) {
        if (isAvailable(i)) {
            //System.out.println("placing " + i + " at (" + row + ", " + col + ")");
            magicSquare[row][col] = i;
            available[i - 1] = false;
            //solution is valid so far
            if (isFilled()) {
                if (isValidSolution()) {
                    System.out.println("You found a correct solution!");
                    printSolution();
                }
            } else {
                if (col != 2) {
                    //System.out.println("new col and solve(" + row + ", " + col + ")");
                    solve(row, col + 1);
                } else if (row != 2) {
                    //System.out.println("new row and solve(" + row + ", " + col + ")");
                    solve(row + 1, 0);
                    //new col    
                }
            }
            magicSquare[row][col] = 0;
            available[i - 1] = true;
        }
    }
}

    public boolean isAvailable(int value) {
        if (available[value - 1] == true) {
            //System.out.println(value + " is available to be placed");
            return true;
        } else {
            //System.out.println(value + " is not available to be placed");
            return false;
        }
    }

    public boolean isValidRow(int row) {
        if (magicSquare[row][0] + magicSquare[row][1] + magicSquare[row][2] == 15) {
            //System.out.println("row " + row + " adds to 15");
            return true;
        } else {
            //System.out.println("row " + row + " does not add to 15");
            return false;
        }
    }

    public boolean isValidCol(int col) {
        if (magicSquare[0][col] + magicSquare[1][col] + magicSquare[2][col] == 15) {
            //System.out.println("col " + col + " adds to 15");
            return true;
        } else {
            //System.out.println("col " + col + " does not add to 15");
            return false;
        }
    }

    public boolean isValidOnDiagonals() {
        if ((magicSquare[0][0] + magicSquare[1][1] + magicSquare[2][2] == 15) && (magicSquare[2][0] + magicSquare[1][1] + magicSquare[0][2] == 15)) {
            //System.out.println("diagonals add to 15");
            return true;
        } else {
            //System.out.println("diagonals don't add to 15");
            return false;
        }
    }

    public boolean isValidSolution() {
        for (int i = 0; i < magicSquare.length; i++) {
            if (!isValidRow(i) || !isValidCol(i)) {
                //System.out.println("solution is valid");
                return false;
            }
        }
        //System.out.println("solution is not valid");
        return isValidOnDiagonals();
    }

    public boolean isFilled() {
        for (int i = 0; i < available.length; i++) {
            if (available[i]) {
                return false;
            }
        }
        return true;
    }

    public void printSolution() {
        for (int i = 0; i < magicSquare.length; i++) {
            for (int j = 0; j < magicSquare[i].length; j++) {
                System.out.print(magicSquare[i][j] + " ");
            }
            System.out.println();
        }
    }
}
公共类MagicSquare{
私人int[][]magicSquare;
私有布尔[]可用;
公共魔法广场(){
magicSquare=新整数[3][3];
可用=新布尔值[9];
for(int i=0;i对于(int i=1;i对于给定的填充正方形,您必须测试a/它是否填充任何行/列,如果是,它是否符合约束条件;如果使用该值,您能够完成问题,即,您的递归是否产生有效的解决方案。如果不是,您需要清空正方形并尝试下一个值。如果您尝试了所有值,则返回错误。基本上,在解决问题之前,您需要能够回溯您的步骤。例如,您可能结束的一个点是
[[1,5,9],[4,8,3],[0,0,0]]
。此时,您需要回溯3个步骤才能到达
[[1,5,9],[6,0,0]]
这将为您提供solution@njzk2我编辑了我的solve方法,试图按照上面的步骤a进行操作。我在哪里实现回溯?你能给我一个回溯可能是什么样子的例子吗?通常它涉及到让你的
solve
方法在到达死胡同时返回布尔值,false(当您尝试了单元格的所有可用值时)或当问题解决时为真。要使用它,您必须做的是,当您有一个不矛盾的值时(无效的填充行或列)也不是解决方案,测试调用递归函数的结果。如果为true,则返回true,如果为false,则尝试使用另一个值。在第一个示例中,一旦您有
[1,2,9]
,则返回false,因为您测试了
[3,4,5,6,7,8,9]
,这意味着对于调用方法,2无效,请尝试3。