我的 A Star 实现不会返回到达目的地的步骤列表
我会在这里尽量简短一些。我正在尝试在Python上实现A Star,但显然我做错了一些事情,因为当我测试它时,它不会返回到达目的地的步骤列表。
基本上,上下文是:我有一个地图,表示为图形,由节点形成。我有一个 Player 类、一个 Node 类和一个 Graph 类。这并不重要,但可能是必要的。玩家必须到达最近的有硬币的节点,这也是一个类。
我的实现基于维基百科伪代码,但由于某种原因它无法工作。我几乎完全确定我的错误在 A* Star 上,但我找不到它。在这里,我将放置我为 A Star 所做的两个函数。希望它不会太混乱,我刚刚开始编程,我很喜欢评论。
我真的很感激任何帮助找到问题的人:)
注意:我不会说英语,所以我对我的错误感到抱歉。希望几年后我能更好地沟通。
def A_Star(player,graph,array_of_available_coins):
# Define the initial position and the last position, where the coin is
initial_position=player.position # Player is a class. Position is of type Node
final_position=closest_cpin(player,graph,array_of_available_coins)
# Define the open_set, closed_set, and work with a Heap.
open_set=[initial_position] # Open_set will be initialized with the current position of the player
closed_set=[]
heapq.heapify(open_set) # Converts the open_set into a Python Heap (or Priority Queue)
came_from={} # It's a dictionary where each key is the a node, and the value is the previous node in the path
# Modify G and H, and therefore F, of the initial position. G of the inicial position is 0.
#And H of the initial position is the pitagoric distance.
initial_position.modify_g_and_h(0,initial_position.distance(final_position))
while open_set!=[]:
square=heapq.heappop(open_set) # Gets the least value of the open_set
if square.is_wall(): # If it's a Wall, the player can't move over it.
continue
if square==final_position:
movements=[] # Creates a empty array to save the movements
rebuild_path(came_from,square,movements) # Calls the function to rebuild the path
player.add_movements_array(movements) # Copies the movements into the movements array of the player
return
# In this point, the square is not a wall and it's not the final_position
closed_set.append(square) # Add the square into the closed_set
neighbours=graph.see_neighbours(square) # Checks all the neighbours of the current square
for neigh in neighbours:
if neigh.is_wall()==True:
continue
if neigh in closed_set:
continue
# Calculates the new G, H and F values
g_aux=square.see_g()+square.get_cost(neigh) # Current g + the cost to get from current to neighbour
h_aux=neigh.distance(final_position) # Pitagoric distance between the neighbour and the last position
f_aux=g_aux+h_aux # F=G+H
if neigh not in open_set:
heapq.heappush(open_set,neigh) # Adds the neigh into the open_set
is_better=True
elif f_aux<neigh.see_f():
is_better=True
else:
is_better=False
if is_better==True:
came_from[neigh]=square # The actual neigh came from the actual square
neigh.modify_g_and_h(g_aux,h_aux) #Modifies the g and h values of the actual neighbour
return None
def rebuild_path(came_from,square,array_of_movements):
array_of_movements.insert(0,square) # Adds, in the first position of the array, the square it gets by parameter
if not square in came_from: # if there is no key "square" in the came_from dictionary, then it's the first position
array_of_movements.remove(array_of_movements[0]) # Gets the first element of the array out (because i need it to be that way later)
return array_of_movements
rebuild_path(came_from,came_from[square],array_of_movements)
return
问题是,我必须实现这个算法,因为它是练习的一部分(更大,有 Pygame 和其他东西),这是唯一让我紧张的事情。如果我使用图书馆,它会被视为我没有这样做,所以我必须再次交付:(
I'll try to be brief here. I'm trying to implement A Star on Python, but obviously I'm doing something wrong, because when I test it, it doesn't return the list of steps to get to the destination.
Basically, the context is: I have a map, represented as a graph, formed by nodes. I have a Player class, a Node class, and a Graph class. That doens't matter much, but might be necessary. The player has to get to the nearest node with a Coin in it, which is also a Class.
My implementation is based on the Wikipedia pseudocode, but for some reason it won't work. I'm almost completely sure that my mistake is on A* Star, but i can't find it. Here, i'll put the two functions that i made regarding A Star. Hope it's not too messy, i'm just starting with programming and i like commenting a lot.
I would really appreciate any help to find the problem :)
Note: I'm not an english speaker, so i'm sorry for my mistakes. Wish, in a few years, i'll be able to comunicate better.
def A_Star(player,graph,array_of_available_coins):
# Define the initial position and the last position, where the coin is
initial_position=player.position # Player is a class. Position is of type Node
final_position=closest_cpin(player,graph,array_of_available_coins)
# Define the open_set, closed_set, and work with a Heap.
open_set=[initial_position] # Open_set will be initialized with the current position of the player
closed_set=[]
heapq.heapify(open_set) # Converts the open_set into a Python Heap (or Priority Queue)
came_from={} # It's a dictionary where each key is the a node, and the value is the previous node in the path
# Modify G and H, and therefore F, of the initial position. G of the inicial position is 0.
#And H of the initial position is the pitagoric distance.
initial_position.modify_g_and_h(0,initial_position.distance(final_position))
while open_set!=[]:
square=heapq.heappop(open_set) # Gets the least value of the open_set
if square.is_wall(): # If it's a Wall, the player can't move over it.
continue
if square==final_position:
movements=[] # Creates a empty array to save the movements
rebuild_path(came_from,square,movements) # Calls the function to rebuild the path
player.add_movements_array(movements) # Copies the movements into the movements array of the player
return
# In this point, the square is not a wall and it's not the final_position
closed_set.append(square) # Add the square into the closed_set
neighbours=graph.see_neighbours(square) # Checks all the neighbours of the current square
for neigh in neighbours:
if neigh.is_wall()==True:
continue
if neigh in closed_set:
continue
# Calculates the new G, H and F values
g_aux=square.see_g()+square.get_cost(neigh) # Current g + the cost to get from current to neighbour
h_aux=neigh.distance(final_position) # Pitagoric distance between the neighbour and the last position
f_aux=g_aux+h_aux # F=G+H
if neigh not in open_set:
heapq.heappush(open_set,neigh) # Adds the neigh into the open_set
is_better=True
elif f_aux<neigh.see_f():
is_better=True
else:
is_better=False
if is_better==True:
came_from[neigh]=square # The actual neigh came from the actual square
neigh.modify_g_and_h(g_aux,h_aux) #Modifies the g and h values of the actual neighbour
return None
def rebuild_path(came_from,square,array_of_movements):
array_of_movements.insert(0,square) # Adds, in the first position of the array, the square it gets by parameter
if not square in came_from: # if there is no key "square" in the came_from dictionary, then it's the first position
array_of_movements.remove(array_of_movements[0]) # Gets the first element of the array out (because i need it to be that way later)
return array_of_movements
rebuild_path(came_from,came_from[square],array_of_movements)
return
The thing is, i have to implement the algorithm, because it's part of an Excercise (much larger, with Pygame and everything), and this is the only thing that's making me nervous. If i use a library, it'll count as if i didn't do it, so i'll have to deliver it again :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我会推荐networkx,
它可以做这种事情:
I would recommend networkx
this can do this kind of stuff: