Я постараюсь быть кратким здесь. Я пытаюсь реализовать A Star на Python, но, очевидно, я делаю что-то не так, потому что, когда я тестирую его, он не возвращает список шагов, чтобы добраться до места назначения.
По сути, контекст таков: у меня есть карта, представленная в виде графа, состоящего из узлов. У меня есть класс 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 и всем остальным), и это единственное, что заставляет меня нервничать. Если я использую библиотеку, это будет считаться, как если бы я этого не делал, поэтому мне придется доставить ее снова :(
networkx
, которая уже реализует графики в Python и реализует (networkx.lanl.gov/reference/generated/) алгоритм A*. Поскольку это открытый код, вы можете увидеть, как они это делают: networkx .lanl.gov/_modules/networkx/algorithms/shortest_paths/ - person Katriel   schedule 17.01.2012