简体   繁体   English

java 中解谜器的递归回溯

[英]Recursive Backtracking for puzzle solver in java

Just get my hand on coding and it is very addicted.只要让我开始编码,它就会非常上瘾。 So I try new challenge in making puzzle solver.所以我尝试制作解谜者的新挑战。 I am getting so close to finish it but get stuck.我越来越接近完成它,但被卡住了。

There are 2 main methods: puzzleSolver and check有两种主要方法:puzzleSolver 和 check

I have tested check method with all cases and it is working very well.我已经测试了所有情况下的检查方法,并且效果很好。

So the only problem is solve method and I dont know whats wrong with it.所以唯一的问题是解决方法,我不知道它有什么问题。

Please look at my code and help me out.请查看我的代码并帮助我。

Very appreciate.非常感谢。

I will explain the rules below.我将在下面解释规则。

RULES:规则:

1.No 3 consecutive values (1 and 2) in each row and column. 1.每行和每列没有 3 个连续值(1 和 2)。

2.Each row and column contains the same amount of values. 2.每一行和每一列都包含相同数量的值。

If grid[6][6].如果网格[6][6]。 Each row and column will have 3 of 1s and 3 of 2s.每行和每列将有 3 个 1 和 3 个 2。

But cannot have 3 of 1s or 2s next each other.但不能有 3 个 1 或 2 彼此相邻。

Example:例子:

grid[2][2]
0 1
1 0
Solution:
2 1
1 2

grid[2][2]
1 1
0 0
Unsolvable
It violated rule number 2. 
grid[4][4]
[0, 2, 2, 1]
[0, 2, 1, 2]
[2, 1, 0, 1]
[2, 0, 0, 0]
solution: 
[1, 2, 2, 1]
[1, 2, 1, 2]
[2, 1, 2, 1]
[2, 1, 1, 2]

grid[4][4]
[0, 2, 2, 2] <- violated rule number 2
[0, 2, 1, 2]
[2, 1, 0, 1]
[2, 0, 0, 0]
Unsolvable

grid[6][6]
[0, 0, 1, 1, 1, 0] <- violated rule #1
[0, 0, 0, 1, 0, 0]
[2, 2, 2, 0, 0, 0] <-violated rule #1
[0, 0, 0, 1, 0, 0]
[0, 1, 2, 0, 0, 0]
[0, 2, 0, 1, 0, 0]
Unsolvable

This is my input grid:这是我的输入网格:

public static void main(String[] args) {
        int[][] grid = { { 0, 1 }, { 1, 0 } };
        int[][] grid1 = { { 0, 2, 2, 1 }, { 0, 2, 1, 2 }, { 2, 1, 0, 1 }, { 2, 0, 0, 0 } };
        int[][] grid2 = { { 0, 2, 2, 0 }, { 0, 0, 0, 0 }, { 0, 2, 0, 0 }, { 0, 0, 0, 1 } };
        int[][] grid3 = { { 0, 0, 1, 0, 2, 2 }, { 0, 0, 2, 0, 0, 0 }, { 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 2, 0, 0 },
                { 2, 0, 1, 0, 0, 0 }, { 0, 0, 2, 1, 2, 0 } };

It works in some cases but not all and I dont know why它在某些情况下有效,但不是全部,我不知道为什么

OUTPUT
Fail to find solution
[0, 2, 2, 0]
[0, 0, 0, 0]
[0, 2, 0, 0]
[0, 0, 0, 1]
false
Solution should have:
1, 2, 2, 1
2, 1, 1, 2
1, 2, 1, 2
2, 1, 2, 1

Here is my code这是我的代码

Solve method will run all row and column and uses check method to decide which value to be placed Solve 方法将运行所有行和列,并使用 check 方法来决定放置哪个值

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

        for (int row = 0; row < grid.length; row++) {
            // column start from 0 and increasing as going down
            for (int col = 0; col < grid.length; col++) {
                // start at 0, 0
                if (grid[row][col] == 0) { // if value =0, will be replaced with n
                    for (int n = 1; n < 3; n++) { // n =1 or n=2
                        grid[row][col] = n; // place n=1 then check condition
                        if (check(grid)) {
                            grid[row][col] = n;// if true, replace 0 with n

                            if (solve(grid)) { // check whole grid if violated rules
                                return true;
                            }
                        }
                    }
                    // System.out.println("No solution");
                    return false; // fail in replacing
                }
            }
        }
        // print out solved grid if succeed
        System.out.println("solution: ");
        for (int i = 0; i < grid.length; i++) {
            System.out.println(Arrays.toString(grid[i]));
        }
        return true; // success
    }
//end code

I have check method to detect any violations and it work well in any cases.我有检查方法来检测任何违规行为,并且在任何情况下都能正常工作。 I know there is something wrong in solve method but cannot find it.我知道解决方法有问题,但找不到。

In, pseudocode, your solution reads like:在伪代码中,您的解决方案如下所示:

for each cell with value zero
    for each allowed value
        place value in cell
        check if it's a solution

Walkthrough what happens if you have all zeroes in you cells.演练如果您的单元格中全为零会发生什么。 The first cell will be given value 1, then 2, neither of which solve the whole grid (because there are still zeroes).第一个单元格将被赋予值 1,然后是 2,这两者都不能解决整个网格(因为仍然存在零)。 So it moves the second cell and so on throughout the grid, leaving each cell with value 2. It obviously won't find a solution in that situation.所以它在整个网格中移动第二个单元格,依此类推,使每个单元格的值为 2。在这种情况下,它显然不会找到解决方案。

Your first issue here is that you actually aren't doing any recursion or backtracking.您的第一个问题是您实际上没有进行任何递归或回溯。

A correct solution will likely look like:正确的解决方案可能如下所示:

solve (grid, position):
    if position is past end and grid is solved
        yah!
    else
        for each allowed value
            place value in position on grid
            call solve(grid, next position)

That's recursive (because it calls itself) and backtracking because if it can't find a solution it returns to a previous position (above it in the call stack) and tries a new value.这是递归的(因为它调用自己)和回溯,因为如果它找不到解决方案,它会返回到以前的 position(在调用堆栈中的上方)并尝试一个新值。

So an actual solution might look something like:因此,实际的解决方案可能类似于:

private void findSolutions(int[][] grid, int col, int row) {
    if (row == grid.length && isSolved(grid)) {
        printSolution(grid);
    } else {
        for (int v = 1; v <= 2; v++) {
            grid[row][col] = v;
            if (col == grid[row].length) {
                findSolutions(grid, 0, row + 1);
            } else {
                findSolutions(grid, col + 1, row + 1);
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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