2016-11-02 3 views
-1

Я работаю над программой Java для задания, и я застрял в реализации и не знаю, где еще искать помощь. Задание создать программу Откат Java, который позволит решить данную Судоку доску с помощью нескольких требуемых методов:Java Recursion Backtracking с определенными методами (Sudoku)

Необходимые методы:

isFullSolution, метод, который принимает частичное решение и возвращает истину если это полное, действительное решение.

отклоняет, метод, который принимает частичное решение и возвращает true, если он должен быть отклонен, потому что он никогда не может быть расширен до полного решения.

extend, метод, который принимает частичное решение и возвращает другое частичное решение, которое включает в себя один дополнительный добавленный вариант. Этот метод возвращает null, если больше нет выбора для добавления в решение. Следует также обязательно внести новое частичное решение, вместо того, чтобы модифицировать исходный объект

следующий, метод, который принимает частичное решение и возвращает другое частичное решение, в котором был выбран последний выбор, который был добавлен изменен на следующий вариант. Этот метод вернет значение null, если больше нет параметров для самого последнего выбора, который был сделан.

Мы также дали наш Решить метод здесь:

static int[][] solve(int[][] board) { 
    if (reject(board)) return null; 
    if (isFullSolution(board)) return board; 
    int[][] attempt = extend(board); 
    while (attempt != null) { 
     int[][] solution = solve(attempt); 
     if (solution != null) return solution; 
     attempt = next(attempt); 
    } 
    return null; 
} 

У меня есть 3 Основные вопросы, касающиеся реализации этого.

Я мог бы легко решить эту проблему без необходимости иметь дело с Продлить, Далее и Premade Решить методы.

1. бы Продлить просто найти первые 0 (0, используются в качестве пустых пространств) и заменить его на 1; поэтому следующий метод мог бы сравнить это, используя методы для сравнения с Row, Column и Box? И даже если я прав, полагая, что метод Solve никогда не достигает метода следующего в любом из моих тестов, и я не знаю, как его обойти.

Мои Продлить Метод:

static int[][] extend(int[][] board) { 
    // Initialize the new partial solution 
    int[][] temp = new int[9][9]; 
    for (int i = 0; i < 9; i++) { 
    for(int j = 0; j < 9; j++){ 
     temp[i][j] = board[i][j]; 
    } 
    } 
    for (int i = 0; i < 9; i++) { 
    for(int j = 0; j < 9; j++){ 
     if(temp[i][j] == 0){ 
     temp[i][j] = 1; 
     return temp; 
     } 
    } 
    } 
    //If we reach this, can no longer extend 
    return null; 
} 

2.Следующая метод никогда не достигается, если явно не вызывается мной внутри Продлить метод. Я написал много разных методов для этого, и никто из них не работает по разным причинам. Я сравниваю методы для строки, столбца и поля, чтобы проверить, какое значение МОЖЕТ быть размещено, и если ни одна из них не работает, она установлена ​​на 0. Однако, во всех моих тестах он никогда не менял ни одного из 1, установленного Расширение способ. Я честно просто очень запутался и потерялся в этот момент, и любое руководство было бы замечательным.

3. Наконец, как бы я знать, в каких случаях отклонять для моего Отклонить метод? Я чувствую, что есть только бесконечное количество угловых шкафов для платы судоку, когда можно вставить любую доску.

Я просто невероятно потерян и понятия не имею, как действовать. Любая помощь приветствуется.

+0

Добро пожаловать в StackOverflow.Прочтите и следуйте инструкциям по отправке в справочной документации. [Минимальный, полный, проверяемый пример] (http://stackoverflow.com/help/mcve) применим здесь. Мы не можем эффективно помочь вам, пока вы не опубликуете свой код и не сможете точно описать проблему. В частности, вы не указали нам одну строку своих попыток отладить это, а просто общие ваши (отсутствующие) тестовые примеры. – Prune

ответ

1

Резюме - мои мнения; см. ниже предостережения.

  1. Расширение может, действительно, просто поставить «1» вместо «0» - или, возможно, сначала необходимо будет проверить RCB (строка столбцов столбцов) для конфликтов. Вы проверите время выполнения с проверкой.
  2. Ваше первое предложение неверно. См. Обзор ниже. Что касается общей путаницы, мы не можем помочь вам без кода и симптомов. Отправьте сообщение MCVE, если у вас все еще есть проблемы.
  3. Я ожидаю, что вы можете просто проверить наличие немедленных конфликтов RCB. Логический поток настроен для обработки более сложных случаев с рекурсивным поиском.

Обзор

Я чувствую, что у Вас есть запутанные две проблемы здесь: (1) проблемы спецификации, которые нужно уточнить с инструктором; (2) Проблемы с кодированием, которые необходимо правильно указать для переполнения стека.

В соответствии с (1) объем работ, выполняемых каждым из ваших методов. Прежде всего, ваше предположение о выводе следующее неверно; основной цикл решить будет звонить следующий всякий раз, когда конкретная плата не может обеспечить решение.

верхнего уровня логики

В английском языке (псевдо-код), ваш дал решить Регламентные работы что-то вроде этого:

If the board has no solution, return null. 
If the board *is* a solution, return it. 
If neither of those ... 
    attempt = extend the board one guess 
    while there's still a valid attempt ... 
     if there is a solution for this attempt, return it. 
     else alter attempt to the next guess. 

Это последняя строка, где следующий будет вызываться на регулярной основе.

Перегородки из вопросов

Открытые вопросы, с моим мнением (если я назначая это своим ученикам):

  • ли продлить проверку на достоверность первого порядка (проверить RCB - Row, Column, Box - для конфликта с существующими номерами) новой догадки? Если нет, то замена 0 на 1 работает отлично.
  • отклонить проверить только на срок действия первого порядка или он должен определить, существует ли решение? Я подозреваю, что это простая проверка, учитывая логический поток, который вы опубликовали.
Смежные вопросы