Двухмерные ограничения массива: судоку - PullRequest
6 голосов
/ 10 октября 2011

Я пытаюсь решить судоку как проблему удовлетворения ограничений для домашнего задания.Я уже построил ограничения для всех элементов в отдельной строке, а также для столбцов.Я пытаюсь построить ограничения для отдельных элементов в подобласти, и у меня возникают некоторые проблемы.

Общая идея моего текущего алгоритма состоит в том, чтобы добавить все переменные, которые находятся всубрегион (например, блок 3x3 для сетки 9x9) в список, а затем перестановка всех значений в этом списке для создания NotEqualConstraints между каждой переменной.Приведенный ниже код работает правильно для 1-го субрегиона сетки NxN, но я не уверен, как мне следует изменить это, чтобы перебирать всю остальную сетку.руководство о том, как я могу изменить код для каждого субрегиона, а не только в верхнем левом?

редактировать: я также готов попробовать любой алгоритм, который работает, нет необходимости добавлять всезначения в ArrayList для каждого субрегиона.Если вы видите лучший способ, пожалуйста, поделитесь пониманием

Ответы [ 4 ]

3 голосов
/ 14 октября 2011

Вот рабочее решение, которое я придумал, для тех, кто заинтересован:

for (int ofs = 0; ofs < svars.length; ofs++) {
    int col = (ofs % incSize) * incSize;
    int row = ((int)(ofs / incSize)) * incSize;

    ArrayList<Variable> subBox = new ArrayList<Variable>();
    for (int ind = row; ind < row+incSize; ind++) {
        for (int ind2 = col; ind2 < col+incSize; ind2++) {
            subBox.add(svars[ind][ind2]);
        }
    }
    for (int i = 0; i < subBox.size(); i++) {
            for (int j = i + 1; j < subBox.size(); j++) {
               NotEqualConstraint c = new NotEqualConstraint(subBox.get(i), subBox.get(j));
               constraints.add(c);
            }
    }   
}
1 голос
/ 20 октября 2011

Я не совсем уверен, что вы пытаетесь сделать, но приведенный ниже алгоритм должен дать вам все необходимое вам значение.Вы можете просто игнорировать и / или удалять значения, которые вам не нужны.Вы могли бы, вероятно, заполнить все свои массивы соответствующим образом в той точке, где у вас есть все числа.

Слова, которые я использую:

  • квадрат: один квадрат, чтобы вставить число.
  • субрегион: группа квадратов, сетка 3x3 в классическом судоку.
  • головоломка: все, 3x3 субрегиона и 9x9 квадратов.

Код:

//You should have these values at this point:
int subRegionWidth = something; //amount of horizontal squares in a subregion
int subRegionHeight = something; //amount of vertical squares in a subregion
int amountOfHorizontalSubRegions = something; //amount of subRegion columns next to each other
int amountOfVerticalSubRegions = something; //amount of subregion rows on top of each other

//Doesn't change, so calculated once in advance:
int squaresPerPuzzleRow = subRegionWidth*amountOfHorizontalSubRegions;

//Variables to use inside the loop:
int subRegionIndex = 0;
int squareColumnInPuzzle;
int squareRowInPuzzle;
int squareIndexInPuzzle;
int squareIndexInSubRegion;

for(int subRegionRow=0; subRegionRow<amountOfVerticalSubRegions;subRegionRow++)
{
    for(int subRegionColumn=0; subRegionColumn<amountOfHorizontalSubRegions;subRegionColumn++)
    {
        for(int squareRowInRegion=0; squareRowInRegion<subRegionHeight; squareRowInRegion++)
        {
            for(int squareColumnInRegion=0; squareColumnInRegion<subRegionWidth; squareColumnInRegion++)
            {
                squareColumnInPuzzle = subRegionColumn*subRegionWidth + squareColumnInRegion;
                squareRowInPuzzle = subRegionRow*subRegionHeight + squareRowInRegion;
                squareIndexInPuzzle = squareRowInPuzzle*squaresPerPuzzleRow + squareColumnInPuzzle;
                squareIndexInSubRegion = squareRowInRegion*subRegionWidth + squareColumnInRegion;

                //You now have all the information of a square:

                //The subregion's row (subRegionRow)
                //The subregion's column (subRegionColumn)
                //The subregion's index (subRegionIndex)
                //The square's row within the puzzle (squareRowInPuzzle)
                //The square's column within the puzzle (squareColumnInPuzzle)
                //The square's index within the puzzle (squareIndexInPuzzle)
                //The square's row within the subregion (squareRowInSubRegion)
                //The square's column within the subregion (squareColumnInSubRegion)
                //The square's index within the subregion (squareIndexInSubRegion)

                //You'll get this once for all squares, add the code to do something with it here.
            }
        }
        subRegionIndex++;
    }
}

Если вам нужны только левые верхние квадраты на субрегион, просто удалите две внутренние петли:

for(int subRegionRow=0; subRegionRow<amountOfVerticalSubRegions;subRegionRow++)
{
    for(int subRegionColumn=0; subRegionColumn<amountOfHorizontalSubRegions;subRegionColumn++)
    {
        squareColumnInPuzzle = subRegionColumn*subRegionWidth;
        squareRowInPuzzle = subRegionRow*subRegionHeight;
        squareIndexInPuzzle = squareRowInPuzzle*squaresPerPuzzleRow + squareColumnInPuzzle;

        //You now have all the information of a top left square:

        //The subregion's row (subRegionRow)
        //The subregion's column (subRegionColumn)
        //The subregion's index (subRegionIndex)
        //The square's row within the puzzle (squareRowInPuzzle)
        //The square's column within the puzzle (squareColumnInPuzzle)
        //The square's index within the puzzle (squareIndexInPuzzle)
        //The square's row within the subregion (always 0)
        //The square's column within the subregion (always 0)
        //The square's index within the subregion (always 0)

        //You'll get this once for all squares, add the code to do something with it here.

        subRegionIndex++;
    }
}
0 голосов
/ 11 октября 2011

Я не совсем понял, что вы пытаетесь сделать, но если вы пытаетесь решить головоломку, вам просто нужен рекурсивный метод, который будет вводить числа, пока он не заполнит всю таблицу, и головоломка будет действительной. Это было мое решение для решения головоломок futoshiki (похоже на sudoku)

0 голосов
/ 10 октября 2011
for (int start1 = start1; start1 < svars.length/incSize; start1 ++) {
    for (int start2 = start2; start2 < svars.length/incSize; start2++) {//iterate through all subsets
        ArrayList<Variable> subBox = new ArrayList<Variable>();

        for (int ind = start1*incSize; ind < incSize; ind++) {
            for (int ind2 = start2*incSize; ind2 < incSize; ind2++) {
                 subBox.add(svars[ind][ind2]);
            }
        }

       for (int i = 0; i < subBox.size(); i++) {
        for (int j = i + 1; j < subBox.size(); j++) {
           NotEqualConstraint row = new NotEqualConstraint(subBox.get(i), subBox.get(j));
           constraints.add(row);
           }
        }
    }
}
...