简体   繁体   中英

Sudoku solving algorithm isn't working as expected

I'm trying to write a programm that solves Sudokus. I'm using backtracking to solve the puzzle.

As far as I can see, my code should work, but apparently it doesn't. I looked at the puzzle at different stages in my code and it is not changing at all. I don't know what to do.

Here the code:

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("###########");
    }
}

Hope this helps you or anyone in future!

There were lots of bugs in the program. Rewrote solveSudoku() and completed the noConflict() method.

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();
}
}

One problem I can see is that here

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

you seem to be assuming that grid and originalGrid are different 2-D arrays. In fact, they are the same array because of the way that you are initializing them. This:

originalGrid = grid;

is a simple reference assignment. It does not make a copy of the grid array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM