所以我写了这个函数,其行为类似于Knuth的算法X.仅仅是为了说明 - 该函数需要一个可能行的大矩阵,其中它试图选择构成合法解决方案的组合。 。
问题是,一旦我们找到了解决方案,由于它的空白,该函数不会返回任何内容而只是回溯(这意味着它会在递归深度中的每个级别打印出数独的数据)。
有关如何在找到解决方案时结束功能的任何建议?我目前正在使用System.exit(0),但这不是很好,因为程序会在你找到解决方案的那一刻结束(所以你想要做的任何事情都是不可能的 - 例如在sudokus数组上运行函数和解决每一个问题。)
代码在这里:
public static void solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
System.exit(0);
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
solve(solution, coverMatrix);
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
}
}
答案 0 :(得分:0)
如果我理解正确,您希望在获得第一个解决方案时结束递归。您可以通过为方法设置布尔返回类型来实现此目的,并在获得第一个解决方案时返回true:。
public static boolean solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
return true;
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
boolean result = solve(solution, coverMatrix);
if(result == true) return result;//else continue
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
return false;
}
}
答案 1 :(得分:0)
您可以将AtomicReference
类与Boolean
:
public static void solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix, AtomicReference<Boolean> test) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
test.set(true);//System.exit(0);
}
solve(solution, coverMatrix, test);
if(!test.get())
{
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
您可以像这样调用您的方法(只需将Boolean
初始化为false
):
public static void main(String[] args)
{
AtomicReference<Boolean> test1 = new AtomicReference<Boolean>();
test1.set(false);
solve(***, ***, test1);
}
答案 2 :(得分:0)
你可能会滥用异常的概念,虽然我不推荐它。
首先定义一个自定义异常类。
public class SuccessException extends Exception {}
在成功时抛出一个实例。
if (Arrays.equals(solvedCase, workCase)) {
drawSudoku(testOutput);
throw new SuccessException();
}
最初在try
块中调用该函数。
try {
solve(solution, coverMatrix);
} catch(SuccessException e) {
/* Solution found! */
}