2

I've created a backtracking algorithm for solving Sudoku puzzles which basicly walks through all the empty fields from left to right, top down respectively. Now I need to make an extended version in which the order in which the algorithm walks through the fields is defined by the amount of possibilities (calculated once, at initialization) for each of the fields. E.g. empty fields which initially have the fewest amount of possible values should be visited first, and only the initially possible values should be checked (both to reduce the amount of iterations needed). Now I'm not sure how to go on implementing this without increasing the amount of iterations needed to actually define these values for each field and then obtain the next field with the fewest possibilities.

For my backtracking algorithm I have a nextPosition method which determines the next empty field in the sudoku to visit. Right now it looks like this:

protected virtual int[] nextPosition(int[] position)
{
    int[] nextPosition = new int[2];
    if (position[1] == (n * n) - 1)
    {
        nextPosition[0] = position[0]+1;
        nextPosition[1] = 0;
    }
    else
    {
        nextPosition[0] = position[0];
        nextPosition[1] = position[1]+1;
    }
    return nextPosition;
}

So it basicly walks through the sudoku left-right, top-down respectively. Now I need to alter this for my new version to walk through the fields ordered by the fewest amount of possible values for the fields (and only trying the possible values for each field in my backtracking algorithm). I figured I'd try to keep a list of invalid values for each field:

    public void getInvalidValues(int x, int y)
    {
        for (int i = 0; i < n * n; i++)
            if (grid[y, i] != 0)
                this.invalidValues[y, i].Add(grid[y, i]);

        for (int i = 0; i < n * n; i++)
            if (grid[i, x] == 0)
                this.invalidValues[i, x].Add(grid[i, x]);

        int nX = (int)Math.Floor((double)x / n);
        int nY = (int)Math.Floor((double)y / n);

        for (int x = 0; x < n; x++)
            for (int y = 0; y < n; y++)
                if (grid[nY * n + y, nX * n + x] != 0)
                    this.invalidValues[y, x].Add(grid[y, x]);
    }

Calling this method for every empty field in the sudoku (represented in this.grid as 2D array [nn,nn]). However this causes even more iterations since in order to determine the amount of different invalid values for each field it'll have to walk through each list again.

So my question is whether someone knows a way to efficiently walk through the fields of the sudoku ordered by the amount of possible values for each field (at the same time keeping track of these possible values for each field since they are needed for the backtracking algorithm). If anyone could help me out on this it'd be much appreciated.

Thanks in advance!

user2999349
  • 859
  • 8
  • 21
  • 1
    My soduku solver worked not on the premise of what couldnt I pick, more on what options I still had. Then, on setting of a square to a value, you remove it from any unset options in the column, row, and 3x3 grid it lived in. Any square where you were down to 1 option auto gets completed.. as there are no choices left. – BugFinder May 20 '16 at 10:49
  • 1
    I wrote similar program over 5 years ago. The probability of of getting a solution doesn't change based on the number of possibilities. The recursive backtrack algorithm should have a FOR loop that goes through each possible number for each empty box. So you have a List>. I would make a class EmptyBox which contains a List possibleNumbers. Then make an array EmptyBox[9,9] emptyboxes. At beginning of application fill the array with possible numbers. If you want to order the List then make List and include in class the row and column of the EmptyBox. – jdweng May 20 '16 at 10:54
  • @jdweng Thank you for the input, how would you go about determining the next field to visit? Because I will still have to go through each list of values for each field to determine the amount of different values and compare these amounts of each field, wouldn't that be a lot of extra iterations needed? – user2999349 May 20 '16 at 11:29
  • @BugFinder Thank you that would be a better way to go reconsidering now, how would you go about determining the next field to visit though? – user2999349 May 20 '16 at 11:30
  • 1
    When I do a backtracking code I pass the level (starting at 0) in the parameter list increasing the level every time you call the recursive algorithm. If you use the 2nd method using a List the index to the array is the level. – jdweng May 20 '16 at 11:32
  • @jdweng That sounds plausible, the level being the amount of possible values? (e.g. walking through the fields with level 1 to 9 respectively) EDIT: Ah I see you meant the index of the field within the array of empty fields, but how can you make sure a higher index contains a field with more possibilities? – user2999349 May 20 '16 at 11:35
  • Normally with backtracking if you have an array you don't have to try 4 + 5 = 9 and 5 + 4 = 9 (associated property of math) when they give same results. So as you go down levels the number of tries will decrease 9,8,7,6,5,4,3,2,1. With my example you can sort the array of EmptyBoxes before you start the recursive function so the order of attempts. My sudoku code at level one changed 1st box through all possible number, level 2 change 2nd empty box, level 3 change 3rd empty box. If there was 20 empty boxes then at beginning the recursive algorithm is call 20 times so you have 20 levels. – jdweng May 20 '16 at 12:10

0 Answers0