2015-01-01 1 views
0

Давайте рассмотрим приведенное ниже изображение для сценария. Я хочу переместить мяч с позиции A1 на C9. Может быть «n» количество путей.Библиотека для логики наилучшего пути в Java

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

Я хотел бы сделать это Java.

  1. Есть ли какая-либо вспомогательная библиотека для поиска пути/наилучшего пути (в основном, я в порядке с любым путем) в определенную позицию.
  2. В основном я предпочитаю алгоритмы A */BFS/DFS

Пожалуйста, советы

enter image description here

+3

Должно быть несколько библиотек. У вас есть googled? – user1822729

ответ

1

Я бы не пойти на библиотеку третьей стороны, потому что реализация алгоритма там будет сильно зависеть на пути изображен график (есть много вариантов , как двухмерный массив, список списков или какой-либо другой пользовательский класс). Если бы я был вами, я бы сам реализовал алгоритм.

Во-первых, вам необходимо определить структуру/класс, который будет представлять вашу доску с шарами, которые занимают некоторые из ячеек. Чтобы это было просто, я буду использовать двумерный массив пользовательского класса Cell, который я добавил как static. Он будет удерживать текущее состояние платы ('B' означает синий и 'O' обозначает orange).

Тогда мне понадобится метод, который возвращает все смежные ячейки для данной ячейки. Я буду использовать список смежных ячеек в реализации Depth First Search.

Наконец, реализация Depth-First Search будет работать следующим образом:

  1. Добавим стартовую ячейку в списке посещенных клеток.
  2. Мы находим все соседние ячейки исходной ячейки (чтобы узнать, к чему мы можем перейти).
  3. Для каждого из соседней ячейки, мы проверяем, если ячейка еще не посетили и не занята
    • Если соседняя cell не является ни посещала, ни занимала, мы делаем рекурсивный вызов dfs(cell, end).
  4. Мы останавливаемся, когда начальная ячейка совпадает с той, которую мы хотим достичь.

Вот реализация:

public class BoardOfBalls { 

    static class Cell { 
     private int x; 
     private int y; 
     private String value; 

     public Cell(int x, int y, String value) { 
      this.x = x; 
      this.y = y; 
      this.value = value; 
     } 
    } 

    private Cell[][] board; 

    private List<Cell> visited = new ArrayList<Cell>(); 

    public void setBoard(Cell[][] board) { 
     this.board = board; 
    } 

    public List<Cell> getAdjacentCellsOf(Cell cell) { 
     List<Cell> result = new ArrayList<Cell>(); 
     int moves[][] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; 
     for (int l = 0; l < 4 /* moves.length */; ++l) { 
      int ti = cell.x + moves[l][0]; 
      int tj = cell.y + moves[l][1]; 
      if (ti >= 0 && ti < board.length && tj >= 0 && tj < board[0].length) { 
       result.add(board[ti][tj]); 
      } 
     } 
     return result; 
    } 

    public void dfs(Cell start, Cell end) { 
     visited.add(start); 
     if (start.x == end.x && start.y == end.y) { 
      printPath(); 
     } else { 
      List<Cell> adjacent = getAdjacentCellsOf(start); 
      for (Cell cell : adjacent) { 
       if (!visited.contains(cell) && cell.value == null) { 
        dfs(cell, end); 
       } 
      } 
     } 
    } 

    private void printPath() { 
     System.out.print("Found a way: "); 
     for (int i = 0; i < visited.size(); i++) { 
      Cell next = visited.get(i); 
      System.out.print("[" + next.x + "][" + next.y + "]"); 
      if (i != visited.size() - 1) { 
       System.out.print(" -> "); 
      } 
     } 
     System.out.println(); 
    } 
} 

Я также написал простой main метод, который проверяет выполнение на меньшем борту:

public static void main(String[] args) { 
    Cell[][] cells = new Cell[3][3]; 
    for (int i = 0; i < 3; i++) { 
     for (int j = 0; j < 3; j++) { 
      cells[i][j] = new Cell(i, j, null); 
     } 
    } 
    cells[0][2].value = "O"; 
    cells[1][1].value = "B"; 
    cells[2][2].value = "B"; 
    BoardOfBalls board = new BoardOfBalls(); 
    board.setBoard(cells); 

    board.dfs(cells[0][0], cells[2][1]); 
} 

, который печатает:

Found a way: [0][0] -> [1][0] -> [2][0] -> [2][1] 
+0

Как пройти по всему возможному пути с использованием этой методологии. Это просто, чтобы выделить возможную ячейку, где мяч может двигаться. Пожалуйста, укажите пункт 2 в вопросе – iappmaker

+0

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

+0

Большое спасибо. Поскольку я новичок в написании игр на основе алгоритмов, ваш вклад в мой вопрос дает мне лучшее понимание. С этим я могу узнать BFS/A *, который понадобится. – iappmaker

2

Вы должны использовать поиск в ширину для этой задачи. Он не только находит путь, но и находит кратчайший путь. Для любого пути вы также можете использовать поиск по глубине. Оба алгоритма довольно просты и легки. Логика BFS заключается в поиске всех не исследованных соседних позиций позиции. Это выполняется с использованием структуры данных очереди, к которой добавляются все неизведанные позиции. Это очень похоже на проблему лабиринта, на которую я могу дать вам решение. Вы можете изучить его и реализовать аналогичную реализацию для своей собственной проблемы. http://pastebin.com/9uk5DY16 Вы также можете узнать больше о BFS здесь: http://en.wikipedia.org/wiki/Breadth-first_search

+0

http://pastebin.com/9uk5DY16 ссылка пуста – iappmaker

+1

Это работает для меня @iappmaker –

+0

Breadth-First с обрезкой - это алгоритм A *. Итак, реализуйте алгоритм ширины и затем выполните обрезку. Книга Алгоритмов в двух словах имеет очень хороший пример. (включая многие другие алгоритмы, такие как поиск, сортировка и т. д.) – Blaatz0r

0

Если вы хотите использовать A *, вы обязательно должны использовать библиотеку. A * нетривиальна, а roll-your-own реализации трудно отлаживать.

Библиотека поиска Java (JSL) имеет класс AStarSearch. (но также классы для поиска в первый раз и другие типы поиска) График построен с использованием объектов SearchNode и SearchEdge. Ваш собственный класс узлов должен расширять AbstractSearchNode и реализовать isGoal, чтобы указать, что представляет собой узел цели. Для краев вы, вероятно, можете просто использовать DefaultSearchEdge s.

После создания отправьте начальную точку на объект AStarSearch, используя setSeed(). search() найдет у вас самый короткий путь к воротам.