Как найти кратчайший путь в этом типе лабиринта

Красный

Red Dot - Represents the initial location
Black Dot - Already occupied
Green - Free to occupy
Destination - Boundry of the matrix [which means either x = 0 or y = 0 or x = 8 or y = 8]

eg. Пример:

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

Ответы

Ответ 1

Прежде всего, вам не нужна Dijkstra, потому что все значения ребер одинаковы. Вы можете использовать простой алгоритм BFS или DFS. Хуже всего сложность случая одинакова, но я бы использовал BFS, так как у него была более сложная сложность. Однако O (| V | + | E |) является самым быстрым, что вы можете получить здесь, и это доказано.

Как представить ваш график? Лучший способ - сохранить список соседей для каждого Node. Черные точки из вашего примера не считаются соседями. Поэтому в вашем примере каждый node будет иметь 0 (полностью покрытый черными точками) до 6 соседей. Затем вы можете получить все, что вы можете получить из любой точки node через эти списки.

Алгоритм BFS обладает свойством, которое присваивает каждому слою node, что означает, насколько он далеко от начального node. Вы начинаете с начальной точки, а ваш текущий слой равен 0. Затем вы просто следуете за всеми узлами текущего слоя (обычно в очереди) и пытаетесь найти его соседи (из их списка соседей), который не имеет слоя и вы назначаете им +1 более высокий уровень. Как только вы найдете свой Node, (который по-прежнему может иметь x, y в качестве атрибутов для проверки границ (или границы свойства bool)), на границе вашего лабиринта вы знаете это до уровня вашего уровня. Если вы хотите напечатать точный способ, вам нужно только найти путь назад (через списки соседей), который соответствует условию, что каждый шаг на -1 ниже. Это напечатает путь от начала до конца, но я уверен, что вы получите результат с небольшой помощью из структуры данных Stack:)

Ответ 2

У вас есть "простая" проблема графа. Связность графиков - это юридические действия, которые у вас есть. Начало node - ваша красная точка. Чтобы получить один терминал node, придумайте еще один круг за пределами данного лабиринта; подключите все реальные выходные узлы к новому кругу с перемещением нулевой стоимости.

Теперь применим алгоритм Дейкстры. Готово.


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

Неужели вы застряли?

Ответ 3

Алгоритм поиска A *

(с: https://en.wikipedia.org/wiki/A*_search_algorithm)

Следующий псевдокод описывает алгоритм [dubious - discuss]:

function A*(start,goal)
    ClosedSet := {}       // The set of nodes already evaluated.
    OpenSet := {start}    // The set of tentative nodes to be evaluated, initially containing the start node
    Came_From := the empty map    // The map of navigated nodes.


    g_score := map with default value of Infinity
    g_score[start] := 0    // Cost from start along best known path.
    // Estimated total cost from start to goal through y.
    f_score := map with default value of Infinity
    f_score[start] := g_score[start] + heuristic_cost_estimate(start, goal)

    while OpenSet is not empty
       current := the node in OpenSet having the lowest f_score[] value
        if current = goal
            return reconstruct_path(Came_From, goal)

       OpenSet.Remove(current)
       ClosedSet.Add(current)
       for each neighbor of current
           if neighbor in ClosedSet 
               continue     // Ignore the neighbor which is already evaluated.
        tentative_g_score := g_score[current] + dist_between(current,neighbor) // length of this path.
        if neighbor not in OpenSet  // Discover a new node
            OpenSet.Add(neighbor)
        else if tentative_g_score >= g_score[neighbor] 
            continue        // This is not a better path.

        // This path is the best until now. Record it!
        Came_From[neighbor] := current
        g_score[neighbor] := tentative_g_score
        f_score[neighbor] := g_score[neighbor] + heuristic_cost_estimate(neighbor, goal)

return failure

function reconstruct_path(Came_From,current)
    total_path := [current]
    while current in Came_From.Keys:
        current := Came_From[current]
        total_path.append(current)
    return total_path

поэтому, насколько я понимаю, вы можете установить начало node в положение красной точки\в центре, а цель node как x = 0 или y = 0 или x = 8 или y = 8 (вы можете сделать 4 вызова функций и взять минимум)

что и для эвристических значений для node - просто установите черные блокированные узлы очень высокими эвристическими значениями, что сделает их недоступными, поэтому алгоритм пройдет вокруг них.