Menu

Error in travercing of solutions in a loop

Help
Aigul
2016-11-04
2016-11-04
  • Aigul

    Aigul - 2016-11-04

    Hello! If it doesn't take much time, could you look at an error in my program?
    I've made a program, that solves sudoku puzzles. It solves correct. But the program raises an error when I try to traverse solutions in a loop (sudoku can have many solutions). Looks like the error is raised in line:

    for (int i=1; i<=search.getSolutionListener().solutionsNo(); i++){ ...
    

    If the puzzle has only one solution, then there is no errors.
    If it's interesting, I used the method of solving sudoku from this site: http://www.ma.utexas.edu/users/cwhite/sudoku.html

    The full souce code:

    import org.jacop.constraints.Constraint;
    import org.jacop.constraints.SumInt;
    import org.jacop.core.IntVar;
    import org.jacop.core.Store;
    import org.jacop.search.*;
    import java.util.ArrayList;
    
    public class Sudoku {
        public static void main(String[] args) {
            int[][] p = {
                    {6, 0, 0, 0, 0, 0, 0, 1, 0},
                    {0, 0, 0, 0, 0, 2, 0, 0, 3},
                    {0, 0, 0, 4, 0, 0, 0, 0, 0},
                    {0, 0, 0, 8, 4, 7, 5, 0, 0},
                    {4, 0, 1, 0, 2, 6, 0, 0, 0},
                    {0, 0, 7, 1, 3, 9, 0, 0, 0},
                    {0, 5, 0, 0, 0, 0, 2, 0, 0},
                    {0, 0, 0, 0, 8, 0, 0, 4, 0},
                    {2, 3, 0, 9, 1, 0, 0, 0, 0},
            };
    
            Store store = new Store();
            IntVar One = new IntVar(store, 1, 1);
            ArrayList<Constraint> ctrArr = new ArrayList<Constraint>();
            IntVar[][][] M = new IntVar[10][9][9];
            for (int n = 1; n < 10; n++)
                for (int i = 0; i < 9; i++)
                    for (int j = 0; j < 9; j++) {
                        if (p[i][j] == n)
                            M[n][i][j] = new IntVar(store, 1, 1);
                        else
                            M[n][i][j] = new IntVar(store, 0, 1);
                    }
            for (int n = 1; n < 10; n++)
                for (int i = 0; i < 9; i++)
                    ctrArr.add(new SumInt(store, M[n][i], "==", One));
            for (int n = 1; n < 10; n++)
                for (int j = 0; j < 9; j++) {
                    IntVar[] v = new IntVar[9];
                    for (int i = 0; i < 9; i++)
                        v[i] = M[n][i][j];
                    ctrArr.add(new SumInt(store, v, "==", One));
                }
            for (int i = 0; i < 9; i++)
                for (int j = 0; j < 9; j++) {
                    IntVar[] v = new IntVar[9];
                    for (int n = 1; n < 10; n++)
                        v[n - 1] = M[n][i][j];
                    ctrArr.add(new SumInt(store, v, "==", One));
                }
    
            for (int n = 1; n < 10; n++)
                for (int boxI = 0; boxI < 3; boxI++)
                    for (int boxJ = 0; boxJ < 3; boxJ++) {
                        IntVar[] v = new IntVar[9];
                        for (int i = 0; i < 3; i++)
                            for (int j = 0; j < 3; j++)
                                v[i*3+j] = M[n][boxI*3+i][boxJ*3+j];
                        ctrArr.add(new SumInt(store, v, "==", One));
                    }
    
            IntVar[] SolutionVector = new IntVar[9*9*9];
            for (int n = 1; n < 10; n++)
                for (int i = 0; i < 9; i++)
                    for (int j = 0; j < 9; j++)
                        SolutionVector[(n-1)*9*9 + i*9 +j] = M[n][i][j];
    
            for (Constraint ctr: ctrArr)
                store.impose(ctr);
            DepthFirstSearch<IntVar> search = new DepthFirstSearch<IntVar>();
            search.setSolutionListener(new PrintOutListener<IntVar>());
            search.getSolutionListener().searchAll(true);
            SelectChoicePoint<IntVar> select =
                    new RandomSelect<IntVar>(SolutionVector, new IndomainMin<IntVar>());
            search.labeling(store, select);
            for (int i=1; i<=search.getSolutionListener().solutionsNo(); i++){
                System.out.print("Solution " + i + ": ");
                for (int j=5; j<search.getSolution(i).length; j++) {
                    if (search.getSolution(i)[j].toString().equals("1"))
                    {
                        int col = j % 9;
                        int row = ((j - col) / 9)%9;
                        int num = ((j - col - row * 9) / 9) /9 +1;
                        p[row][col] = num;
                    }
                }
                for (int r = 0; r < 9; r++) {
                    System.out.println();
                    for (int c = 0; c < 9; c++) {
                        System.out.print(p[r][c] + " ");
                    }
                }
            }
        }
    }
    
     
  • kris

    kris - 2016-11-04

    Add

    search.getSolutionListener().recordSolutions(true);
    

    before startting search, that is before line

        search.labeling(store, select);
    

    Best,
    /Kris

     
  • Aigul

    Aigul - 2016-11-04

    Thank you! Now it works.

     

Log in to post a comment.