0

Моя цель состоит в том, чтобы перейти от source к destination по кратчайшему число шагов в матрице, лишь делая рыцарских движений (в форме L ходов)Минимальное количество рыцаря движется, чтобы перейти от источника к месту назначения в матрице

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

public class knightminmoves { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 

     int degree = 5; 
     int[][] board = new int[degree][degree]; 
     boolean[][] visited = new boolean[degree][degree]; 

     System.out.println(minMoves(0, 0, degree - 1, degree - 1, board, visited)); 
    } 


    static int minMoves(int x, int y, int destx, int desty, int[][] board, boolean[][] visited) { 
     if (x < 0 || y < 0 || x >= board.length || y >= board[0].length) 
      return Integer.MAX_VALUE - 2; 

     if (x == destx && y == desty) 
      return 0; 

     if (visited[x][y] == true) 
      return Integer.MAX_VALUE - 2; 
     else 
      visited[x][y] = true; 

     int upleft = minMoves(x - 2, y - 1, destx, desty, board, visited); 
     int upright = minMoves(x - 2, y + 1, destx, desty, board, visited); 
     int downleft = minMoves(x + 2, y - 1, destx, desty, board, visited); 
     int downright = minMoves(x + 2, y + 1, destx, desty, board, visited); 
     int leftup = minMoves(x - 1, y - 2, destx, desty, board, visited); 
     int leftdown = minMoves(x + 1, y - 2, destx, desty, board, visited); 
     int rightup = minMoves(x - 1, y + 2, destx, desty, board, visited); 
     int rightdown = minMoves(x + 1, y + 2, destx, desty, board, visited); 

     visited[x][y] = false; 

     return min(upleft, upright, downleft, downright, leftup, leftdown, rightup, rightdown) + 1; 
    } 

    static int min(int a, int b, int c, int d, int e, int f, int g, int h) { 
     int[] arr = new int[8]; 
     arr[0] = a; 
     arr[1] = b; 
     arr[2] = c; 
     arr[3] = d; 
     arr[4] = e; 
     arr[5] = f; 
     arr[6] = g; 
     arr[7] = h; 

     Arrays.sort(arr); 
     return arr[0]; 
    } 

} 
+3

Если этот код работает, я считаю, что этого следует попросить по [Обзор кода] (http://codereview.stackexchange.com/) – AxelH

+2

Даже не глядя на свой код, одна концептуальная вещь: для * кратчайшего * пути , вы не должны использовать глубину-сначала (которая в конечном итоге отслеживает все возможные пути до максимальной длины для того, чтобы попробовать следующий), но в ширину. – mtj

+0

Читайте о [алгоритме Дейкстры] (https://en.wikipedia.org/wiki/Dijkstra's_algorithm). Можете ли вы концептуализировать свою проблему как график? – RealSkeptic

ответ

1

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

+0

Кто-то сказал мне, что мое решение неверно, так как, скажем, мы начинаем с (0,0) и переходим к (1,2). В (1,2) возможный путь также равен (0,0). Но мы не знаем значения (0,0), так как его расчет еще не завершен, так как он ожидает вычисления (1,2). Итак, поскольку (0,0) и (1,2) зависят друг от друга, это не является кандидатом на динамическое программирование. Это правда? Подобным же образом он сказал мне, что эта проблема также невозможна для решения путем поиска/рекурсии глубины - http://www.geeksforgeeks.org/snake-ladder-problem-2/ – learningboy

+0

То, как я смотрю на нее, если вы перешли к (1,2) из ​​(0,0), то в (1,2) нет необходимости рассматривать возврат к (0,0) как один из возможных вариантов, так как это так или иначе не может быть кратчайшим путем, так как вы находитесь на том же самом месте, что и раньше, просто сделали несколько лишних шагов. – learningboy

+0

@learningboy Глубина первого поиска здесь не работает. Рекурсивное решение, которое проверяет все простые пути (да, никогда не нужно возвращать в (0,0)), работает, но оно экспоненциально. Что касается динамического программирования, то это зависит от его сглаживания. Некоторые люди считают алгоритм Джикстры и широкий поиск первого поиска динамическим программированием. В этом смысле работает динамическое программирующее решение. – kraskevich