使用特定方法进行Java递归回溯(数独)

时间:2016-11-02 07:16:13

标签: java recursion backtracking

我正在为一项任务开发一个Java程序而且我一直坚持实现,并且不知道在哪里寻求帮助。任务是创建一个Backtracking Java程序,它将使用一些必需的方法来解决给定的Sudoku板:

必填方法:

isFullSolution ,一种接受部分解决方案的方法,如果它是完整有效的解决方案,则返回true。

拒绝,这是一种接受部分解决方案的方法,如果应该被拒绝则返回true,因为它永远不会扩展为完整的解决方案。

扩展,这是一种接受部分解决方案的方法,并返回另一个包含一个附加选项的部分解决方案。如果没有更多选择要添加到解决方案,则此方法将返回null。它还应该确保创建一个新的部分解决方案,而不是修改原始对象

next ,一种接受部分解决方案的方法,并返回另一个部分解决方案,其中最新选择的选项已更改为下一个选项。如果没有更多选项用于最近的选择,则此方法将返回null。

我们还在这里提供了 Solve 方法:

 static int[][] solve(int[][] board) {
    if (reject(board)) return null; 
    if (isFullSolution(board)) return board; 
    int[][] attempt = extend(board);
    while (attempt != null) {
        int[][] solution = solve(attempt);
        if (solution != null) return solution;
        attempt = next(attempt);
    }
    return null;
}

我有3个与实施此问题有关的主要问题。

我可以轻松解决这个问题,而无需处理扩展下一步和预制的解决方法。

1。 扩展只是找到第一个0(0用作空格)并将其替换为1;所以下一个方法可以比较使用方法来比较行,列和框?即使我正确地假设 Solve 方法在我的任何测试中都没有达到 Next 方法,而且我不知道如何解决它。

我的扩展方法:

static int[][] extend(int[][] board) {
  // Initialize the new partial solution
  int[][] temp = new int[9][9];
  for (int i = 0; i < 9; i++) {
    for(int j = 0; j < 9; j++){
      temp[i][j] = board[i][j];
    }
  }
  for (int i = 0; i < 9; i++) {
    for(int j = 0; j < 9; j++){
      if(temp[i][j] == 0){
        temp[i][j] = 1;
        return temp;
      }
    }
  }
  //If we reach this, can no longer extend
   return null;
}

2。除非我在 Extend 方法中明确调用,否则永远不会达到 Next 方法。我为此编写了许多不同的方法,但没有一种方法可以用于不同的原因。我已经比较了行,列和框的方法来检查可以放置哪个值,如果没有工作则设置为0. 但是,通过我的所有测试它从未改变任何1的由扩展方法设置。老实说,在这一点上我感到非常困惑和迷失,任何指导都会很棒。

3。最后,我如何知道哪些案例要拒绝拒绝方法?我觉得当任何一块木板都可以投入时,数独板的角落数量就会无穷无尽。

我只是迷失了,不知道该怎么办。欢迎任何和所有帮助。

1 个答案:

答案 0 :(得分:1)

摘要 - 我的意见;请参阅下面的警告。

  1. 实际上,扩展可以只用'1'代替'0' - 或者可能需要首先检查RCB(行列框)是否存在冲突。您将通过检查节省一些执行时间。
  2. 您的第一句话不正确。请参阅下面的概述。至于整体混乱,没有代码和症状,我们无法帮助你。如果您仍有问题,请发布MCVE
  3. 我希望你能检查一下RCB的即时冲突。设置逻辑流程以通过递归搜索处理更复杂的情况。
  4. <强>概述

    我觉得你在这里混淆了两套问题:(1)规格问题,你需要与导师澄清; (2)编码问题,需要为Stack Overflow正确指定。

    在(1)下是每种方法完成的工作范围。首先,您关于调用 next 的假设是不正确的;当特定电路板无法提供解决方案时,解决的主循环将调用 next

    顶级逻辑

    在英语(伪代码)中,您给出的求解例程的工作方式如下:

    If the board has no solution, return null.
    If the board *is* a solution, return it.
    If neither of those ...
        attempt = extend the board one guess
        while there's still a valid attempt ...
            if there is a solution for this attempt, return it.
            else alter attempt to the next guess.
    

    最后一行是定期调用下一个的地方。

    问题分区

    用我的意见打开问题(如果我将这个问题分配给我的学生):

    • 扩展检查新猜测的一阶有效性(检查RCB - 行,列,框 - 与现有数字冲突)?如果没有,那么用1替换0就可以了。
    • 拒绝仅检查一阶有效性,还是必须确定解决方案是否存在?考虑到你发布的逻辑流程,我怀疑这是简单的检查。