Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smoother way to exit a void recursive Java function

Tags:

java

recursion

So I wrote this function that behaves like Knuth's Algorithm X. Just for illustration - the function requires a large matrix of possible rows among which it tries to select the combination of the ones that make up for a legitimate solution.

The thing is, once we found the solution, since its void, the function doesn't return anything and instead just backtracks up (which consequently means it prints out sudoku for every level in the recursion depth).

Any suggestions on how to end the function the moment the solution is found? I am currently using System.exit(0) but that isn't nice since the program then ends the moment you find the solution (so anything you want to do afterwards is impossible - for example run the function on array of sudokus and solve each one).

The code is here:

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);
            }
        }
    }
}
like image 285
Traumy Avatar asked Sep 27 '26 02:09

Traumy


1 Answers

If I understand you correctly, you want to end recursion when you got the first solution. You can achieve this by having boolean return type for the method, and return true when you get first solution :.

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

}

like image 145
Mrinal Avatar answered Sep 29 '26 14:09

Mrinal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!