数独求解算法没有按预期工作

时间:2014-04-04 02:46:52

标签: java algorithm sudoku backtracking

我试图编写一个解决Sudokus的程序。 我正在使用回溯来解决难题。

据我所知,我的代码应该可行,但显然它并没有。 我在代码的不同阶段查看了这个难题,它根本没有变化。 我不知道该怎么做。

这里是代码:

public class main {

    public static int[][] originalGrid;

    public static void main(String[] args){
        int[][] grid = {{5, 3, 0, 0, 7, 0, 0, 0, 0},
                        {6, 0, 0, 1, 9, 5, 0, 0, 0}, 
                        {0, 9, 8, 0, 0, 0, 0, 6, 0}, 
                        {8, 0, 0, 0, 6, 0, 0, 0, 3}, 
                        {4, 0, 0, 8, 0, 3, 0, 0, 1}, 
                        {7, 0, 0, 0, 2, 0, 0, 0, 6}, 
                        {0, 6, 0, 0, 0, 0, 2, 8, 0}, 
                        {0, 0, 0, 4, 1, 9, 0, 0, 5}, 
                        {0, 0, 0, 0, 8, 0, 0, 7, 9}};
        originalGrid = grid;
        solveSudoku(grid, 0, 0);
        System.out.println("Done!");
    }

    public static boolean solveSudoku(int[][] grid, int row, int col) {

        //base case
        if (noUnassignedLocation(grid)){
            printGrid(grid);
            return true;
        }

        for (int i = 0; i < 9; i++) {
            if (noConflict(grid)) {

                if (originalGrid[row][col] == 0)
                    grid[row][col] = i;

                printGrid(grid);

                col++;
                if (col == 9) {
                    col = 0;
                    if (row != 8)
                        row++;
                }
                if (solveSudoku(grid, row, col))
                    return true;
                grid[row][col] = 0;
                col--;
                if (col == 0) {
                    col = 9;
                    row--;
                }
            }
        }
        printGrid(grid);
        return false;
    }

    public static boolean noConflict(int[][] grid) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0 ; j < 9; j++) {
                int current = grid[i][j];

                //System.out.println("i: " + i + " j: " + j);

                for (int k = 0; k < 9; k++) {
                    if (current == grid[k][j] && k != i && current != 0 && grid[k][j] != 0) {
                        return false;
                    }
                }
                for (int k = 0; k < 9; k++) {
                    if (current == grid[i][k] && k != j && current != 0 && grid[i][k] != 0) {
                        return false;
                    }
                }
                //check block
            }
        }
        return true;
    }

    public static boolean noUnassignedLocation(int[][] grid) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (grid[i][j] == 0) {
                    return false;
                }
            }
        }
        return true;
    }

    private static void printGrid(int[][] grid) {
        System.out.println("###########");
        for (int i = 0; i < 9; i++) {
            String line = new String();
            for (int j = 0; j < 9; j++) {
                line = line + grid[i][j];
            }
            System.out.println("#" + line + "#");
        }
        System.out.println("###########");
    }
}

2 个答案:

答案 0 :(得分:2)

希望这有助于您或将来的任何人!

程序中有很多错误。重写了solveSudoku()并完成了noConflict()方法。

public class Sudoku {
public static void main(String[] args) {
    int[][] grid = { 
            { 5, 3, 0, 0, 7, 0, 0, 0, 0 },
            { 6, 0, 0, 1, 9, 5, 0, 0, 0 }, 
            { 0, 9, 8, 0, 0, 0, 0, 6, 0 },
            { 8, 0, 0, 0, 6, 0, 0, 0, 3 }, 
            { 4, 0, 0, 8, 0, 3, 0, 0, 1 },
            { 7, 0, 0, 0, 2, 0, 0, 0, 6 }, 
            { 0, 6, 0, 0, 0, 0, 2, 8, 0 },
            { 0, 0, 0, 4, 1, 9, 0, 0, 5 }, 
            { 0, 0, 0, 0, 8, 0, 0, 7, 9 } 
        };

    //originalGrid = grid;
    solveSudoku(grid);
    System.out.println("Done!");
    printGrid(grid);
}

public static boolean solveSudoku(int[][] grid) {

    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (grid[i][j] != 0) {
                continue;
            }
            for (int num = 1; num <= 9; num++) {
                if (noConflict(grid)) {
                    grid[i][j] = num;
                    if (solveSudoku(grid)) {
                        return true;
                    } else {
                        grid[i][j] = 0;
                    }
                }
            }
            return false;
        }
    }
    return true;
}

/** 
 * Checks row, column and box have unique values.
 * 
 * @param grid
 * @return
 */
public static boolean noConflict(int[][] grid) {
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            //int current = grid[i][j];

            // check row unique
            for (int k = 0; k < 9; k++) {
                if (grid[i][j] == grid[k][j] && k != i && grid[i][j] != 0
                        && grid[k][j] != 0) {
                    return false;
                }
            }

            //check column unique
            for (int k = 0; k < 9; k++) {
                if (grid[i][j] == grid[i][k] && k != j && grid[i][j] != 0
                        && grid[i][k] != 0) {
                    return false;
                }
            }

            // check block
            for (int row = (i/3)*3; row < (i/3)*3+3; row++) {
                for (int col = (j/3)*3; col < (j/3)*3+3; col++) {
                    if(row != i && col!=j && grid[row][col]==grid[i][j] && grid[i][j] != 0) {
                        return false;
                    }
                }
            }

        }
    }
    return true;
}

public static boolean noUnassignedLocation(int[][] grid) {
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (grid[i][j] == 0) {
                return false;
            }
        }
    }
    return true;
}

private static void printGrid(int[][] grid) {
    System.out.println();
    for (int i = 0; i < 9; i++) {
        String line = new String();
        for (int j = 0; j < 9; j++) {
            line = line + grid[i][j];
        }
        System.out.println(line);
    }
    System.out.println();
}
}

答案 1 :(得分:1)

我能看到的一个问题就是这里

if (originalGrid[row][col] == 0)
    grid[row][col] = i;

您似乎假设gridoriginalGrid是不同的二维数组。实际上,由于您初始化它们的方式,它们是相同的数组。这样:

originalGrid = grid;

是一个简单的参考作业。它不会复制grid数组。