如何在这种迷宫中找到最短路径
How to find shortest path in this type of maze
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
一次只能放置一个移动,并且可以移动到附加到它的六个绿色圆圈之一。
在这种迷宫中计算最短路径的最快方法是什么。
您遇到的是一道 "simple" 图形问题。图形连通性是您拥有的合法移动。起始节点是您的红点。要获得单个终端节点,请在给定迷宫外再创建一个圆圈;以零成本移动将所有 真实 出口节点连接到新圆。
现在,应用 Dijkstra 算法。完成。
另一种看待问题的方法是递归。移动红点,将旧位置标记为黑色。从新位置重复。 Return 当您退出(return 路径长度 1)或没有合法移动(return 路径长度无限)。保持已知的最短路径。
这些能让你摆脱困境吗?
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次函数调用,取最少的)
至于节点的启发值 - 只需将黑色阻塞节点的启发值设置得非常高,这将使它们无法到达,因此算法将绕过它们。
首先,你不需要Dijkstra,因为所有边的值都是一样的。您可以使用简单的 BFS or DFS 算法。最坏情况的复杂度是相同的,但我会使用 BFS,因为它具有更好的平均情况复杂度。然而,O(|V|+|E|) 是最快的,并且已被证明。
如何表示您的图表?最好的方法是为每个 Node
保留一个邻居列表。您示例中的黑点不算作邻居。因此,在您的示例中,每个节点将有 0(完全被黑点覆盖)到 6 个邻居。然后,您可以通过这些列表从任何节点到达任何您可以到达的地方。
BFS 算法有一个属性,它为每个节点分配一个层,这意味着它与起始节点的距离。你从你的起点开始,你的当前层将为 0。然后你只需跟随当前层的所有节点(通常保持在队列中)并尝试找到它的邻居(从他们的邻居列表中),它没有层分配,你分配给他们 +1 更高层。一旦您在迷宫的边界找到您的节点(它仍然可以将 x,y 作为边界检查的属性(或 属性 bool border)),您就知道它与您的图层值一样远。如果你想打印确切的方式,你只需要找到满足每一步都在 -1 层以下的条件的返回方式(通过你的邻居列表)。这将打印从头到尾的方式,但我相信在 Stack
数据结构的帮助下你会得到你的结果 :)
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
一次只能放置一个移动,并且可以移动到附加到它的六个绿色圆圈之一。
在这种迷宫中计算最短路径的最快方法是什么。
您遇到的是一道 "simple" 图形问题。图形连通性是您拥有的合法移动。起始节点是您的红点。要获得单个终端节点,请在给定迷宫外再创建一个圆圈;以零成本移动将所有 真实 出口节点连接到新圆。
现在,应用 Dijkstra 算法。完成。
另一种看待问题的方法是递归。移动红点,将旧位置标记为黑色。从新位置重复。 Return 当您退出(return 路径长度 1)或没有合法移动(return 路径长度无限)。保持已知的最短路径。
这些能让你摆脱困境吗?
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次函数调用,取最少的)
至于节点的启发值 - 只需将黑色阻塞节点的启发值设置得非常高,这将使它们无法到达,因此算法将绕过它们。
首先,你不需要Dijkstra,因为所有边的值都是一样的。您可以使用简单的 BFS or DFS 算法。最坏情况的复杂度是相同的,但我会使用 BFS,因为它具有更好的平均情况复杂度。然而,O(|V|+|E|) 是最快的,并且已被证明。
如何表示您的图表?最好的方法是为每个 Node
保留一个邻居列表。您示例中的黑点不算作邻居。因此,在您的示例中,每个节点将有 0(完全被黑点覆盖)到 6 个邻居。然后,您可以通过这些列表从任何节点到达任何您可以到达的地方。
BFS 算法有一个属性,它为每个节点分配一个层,这意味着它与起始节点的距离。你从你的起点开始,你的当前层将为 0。然后你只需跟随当前层的所有节点(通常保持在队列中)并尝试找到它的邻居(从他们的邻居列表中),它没有层分配,你分配给他们 +1 更高层。一旦您在迷宫的边界找到您的节点(它仍然可以将 x,y 作为边界检查的属性(或 属性 bool border)),您就知道它与您的图层值一样远。如果你想打印确切的方式,你只需要找到满足每一步都在 -1 层以下的条件的返回方式(通过你的邻居列表)。这将打印从头到尾的方式,但我相信在 Stack
数据结构的帮助下你会得到你的结果 :)