16

红色的

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]

例如。 例子:

red dot一次只能移动一次,并且可以在附在其上的绿色六个圆圈之一中移动。在这种迷宫中计算最短路径的最快方法是什么?

4

3 回答 3

4

首先,您不需要 Dijkstra,因为边的所有值都是相同的。您可以使用简单的BFSDFS算法。最坏情况的复杂性是相同的,但我会使用 BFS,因为它具有更好的平均情况复杂性。但是,O(|V|+|E|) 是您可以达到的最快速度,并且已得到证明。

如何表示您的图表?最好的方法是为每个Node. 您示例中的黑点不算作邻居。因此,在您的示例中,每个节点将有 0(完全被黑点覆盖)到 6 个邻居。然后,您可以通过这些列表从任何节点点到达任何地方。

BFS 算法有一个属性,它为每个节点分配一个层,这意味着它与起始节点的距离。你从你的起点开始,你的当前层将为0。然后你只需跟随当前层中的所有节点(通常保留在队列中)并尝试找到它的邻居(从他们的邻居列表中),它没有层分配,你分配给他们+1更高的层。一旦你在迷宫的边界找到了你的节点(它仍然可以将 x,y 作为边界检查的属性(或属性布尔边界)),你就知道它与你的层值一样远。如果你想打印准确的方式,你只需要找到返回的方式(通过你的邻居列表),它满足每一步都在 -1 层以下的条件。这将打印从头到尾的方式,但我相信你会在一些帮助下得到你的结果Stack数据结构 :)

于 2015-11-13T13:52:37.123 回答
3

你所拥有的是一个“简单”的图形问题。图形连接是您拥有的合法移动。起始节点是你的红点。要获得单个终端节点,请在给定迷宫外再创造一个圆圈;以零成本的移动将所有真正的出口节点连接到新的圈子。

现在,应用 Dijkstra 算法。完毕。


另一种看待问题的方法是递归。移动红点,将旧位置标记为黑色。从新位置再次出现。退出时返回(返回路径长度 1)或没有合法移动(返回路径长度无限)。保持最短的已知路径。

这些能让你摆脱困境吗?

于 2015-11-04T21:56:46.453 回答
-1

A* 搜索算法

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

以下伪代码描述了算法[可疑 - 讨论]:

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

所以,据我了解 - 您可以将您的起始节点设置在红点位置 \ 中心位置,并将目标节点设置为 x = 0 或 y = 0 或 x = 8 或 y = 8(您可以进行 4 个函数调用,并取最小值)

至于节点的启发式值 - 只需将黑色阻塞节点设置为非常高的启发式值,这将使它们无法访问,因此算法将绕过它们。

于 2015-11-07T13:16:54.050 回答