After some heavy research/tinkering, I have fixed all the bugs in my A* (A-star) algorithm. I solved the dreaded parent cell problem by creating a second, 2-dimensional array that stores the parent cell of a given cell, for later analysis. I also changed how the next cell in the open list is found. Instead of choosing a cell with an F-score lower than the current cell, it chooses the cell in the list with the lowest F-score (regardless of the current cell's F-score). This keeps the program from crashing when no cell has an F-score lower than the current cell.

Well, enough discourse. I have attached the program to this post and inserted the code below:

#Version 2 is nearly the same as version 1, but all the bugs are gone. Now a#clear and readable path is found.##This is an example of the A* pathfinding algorithm I wrote in Python. This#program is primarly based on Abraham L. Howell's ER1 Mapper made specifically#for the ER1 robot. His program was written in Visual Basic, so I tried to#"translate" it to Python as best I can. All credit goes to him for the basic#code I used as a general guide to create this. You are free to use, edit and#distribute this as long as credit is given where appropriate.##The code is very basic right now. You create a map in the grid below; it can#be any size as long as if it stays a rectangle or square (it does not have to#be one, but it is significantly easier if it is). This grid is basically a#list within a list: lists a through e are the rows and they are in list "map".#The bottom-left cell is reached by typing "map[0][0]". The first x and y#coordinates are 0 (so if you have 5 rows, the bottom is row 0 and the top is#row 4). You enter the x and y coordinates of the start and goal cells to the#"start" and "target" variables appropriately (see below). You then run the#program and it finds a path to the start to goal cell. It then prints the#entire map again with the path marked. That is all it does for now; it finds#a path. Other details about this code can be discovered by reading this code#or Howell's original code/documentation.

#--------------------------------------------------------------------#This part of the code creates a 2-dimensional array for storing parent cells.#For example: Pcell[2][3] = [2, 2]. It has the same dimensions and size as the#above map, so no "cell is out of range" errors can occur. It works the same as#the map above; y value first and x second. Example: Pcell[y][x] = [NewX, NewY]

#--------------------------------------------------------------------#this part of the code establishes the telnet connection to the RCC and is#independent and unrelated to the A* algorithm or finding a path (it is only#used to physically move the robot after the path is found).

#----------------------------------------------------------------------#When the goal cell is found, print map with marked cells.def ShowPath(): #Display that a path was found and how many loops were made to find it. print "Path found! ", "Number of loops =", numpasses

#Find the parent of the goal cell, then find that cell's parent and so on, #until, the current cell is the start cell. This trail of parent cells is #the found path. while curCellX != startX or curCellY != startY: intPathLength = intPathLength + 1 #Record the length of the path P = Pcell[curCellY][curCellX] curCellX = P[0] curCellY = P[1] map[curCellY][curCellX] = 4 #Mark each parent cell with a 4

print "Path length =", intPathLength

map.reverse() #reverse list "map", so when printed in the for i in map: #for: loop, it comes out right-side up print i

if len(openlist) == 0: #if openlist is empty, exit NoSolutionFound() #loop; there is no solution. break

#now we find the cell on the openlist with the lowest F score and set it #as the current cell. smallest = F(openlist[0]) #Assume the first member is the smallest. for r in openlist: if F(r) <= smallest: #If an item on the list is smaller than smallest = F(r) #the first item, set it as the new smallest NewX = r[0] NewY = r[1] #Keep looping until a smaller value is found

#add the cell you just selected to the closed list and remove it from the #open list. closedlist.append([NewX, NewY]) openlist.remove([NewX, NewY])

#Find out if the cell you put in the closed list is the target cell #else, mark the current cell, so when you print "map", you can see it #was analyzed (analyzed cells are marked with the number 3) if NewX == targetX and NewY == targetY: ShowPath() break

I've been thinking that this may be the first time ever that the A* (A-star) algorithm has been written in Python. I don't know for sure, but I've looked everywhere for one on the net without success, so it's possible. Also, to Admin: I've heard you're creating an A* tutorial and that links to certain forum topics were in it. Please feel free to use this code (Actually, everyone feel free to use it). I know it's not written in C/C++, but it might be useful.

Thank you to everyone on this forum; I could not have done this without your guy's help.

Thank you for taking the time and effort to write this down. I wish I'd have the time to dust off my ER1 to play around with your code... Eh, maybe during the winter, when I'll have less work. Right now it's hard to even follow through with my current projects.

What do you think it will be the next step? Making a list of places coordinates so the robot can go where you tell him to go? Something like Couch = Map[3][2], Coffe table = Map[4][7] and so on. And a grammar list for the speech recognition engine that contains the commands (Go to, Bring, Come here, Rub my back, Vacoom, Walk the Dog, etc.), places to go (Couch, Fridge, Table, ...) objects to bring (Beer, Coffe, Socks, Newspaper, ...) and so on... Oh, I've got ideeas, just don't know how to make them work (yet). I've got to stop now, this is allready steering me away from my projects and... oh well.

By the way, the coolest thing I read about what other people did with their ER1 was about a guy that had his robot walk his dog around the block! He was watching remotely on his computer what the robot would see and even had the robot saying Good morning to the neighbours! He was saying that nobody dared to touch the robot because of the dog, hehe.

#These are the heuristic constants. If Dg > Dh, more cells are analyzed and a#more ideal path is found. If Dh >= Dg, less cells are analyzed and a path is#found quicker.A* should be provably optimal for an admissible heuristic. Different heuristics might affect how long it takes to find the solution, but not whether if finds the optimal one.

Also, if speed is important to you, you should implement A* with heaps.

There are python implementations on the net, you have to google "A-star" instead b/c google interprets * as a special character. I had a lot of trouble finding code for AO* a while back, because of that same problem.

Yeah, the Dg and Dh constants were part of the original program and I carried them over to my script. What is meant by "optimal" is that the path is shorter. For example, I noticed if Dg < Dh, the path will zig-zag towards the goal cell, if the map is very open. However, if Dg > Dh, the path will be much more direct and more cells are analyzed (which, in theory, takes longer). But I agree with you; every other A* (A-star) code I've seen does not use these constants. Also, I planed on creating a binary heap sometime soon, but speed is not an issue for me, plus, I don't know how to yet. My goal right now is to have my robot actually traverse the path it found (should see results soon). Once that is fully working, I'll make it better.

Hm, where *exactly* did you get the code from? It clearly isn't A* if it can't find the shortest path (assuming the heuristic is admissible, and the manhattan distance is an admissible heuristic). If all you want to do is to find a path, DFS (with node marking) is faster and works just fine.

Hmm... Technically, G(x) isn't really an estimate, it calculates the actual distance between the current cell and the start cell (of course, it may refer to the actual distance traveled from the start cell following the path it created). If you're curious, here's the link to the site with the original program: