def heuristic(current=0, goal=0, space=city.chart([],[])): """heuristic :: nodenumber -> nodenumber -> chart -> distance""" startIdx = space.lookupCity(current) goalIdx = space.lookupCity(goal) if (startIdx == city.cityNotFound) or (goalIdx == city.cityNotFound): return 0 #there is no distance between cities that don't exist else: sCity = space.cities[startIdx] gCity= space.cities[goalIdx] #return the Euclidean Distance of the two cities. return getEuclideanDistance((sCity.xpos,sCity.ypos),(gCity.xpos,gCity.ypos))
def heuristic(current=0, goal=0, space=city.chart([], [])): """heuristic :: nodenumber -> nodenumber -> chart -> distance""" startIdx = space.lookupCity(current) goalIdx = space.lookupCity(goal) if (startIdx == city.cityNotFound) or (goalIdx == city.cityNotFound): return 0 #there is no distance between cities that don't exist else: sCity = space.cities[startIdx] gCity = space.cities[goalIdx] #return the Euclidean Distance of the two cities. return getEuclideanDistance((sCity.xpos, sCity.ypos), (gCity.xpos, gCity.ypos))
def Astar(start=0, goal=0, space=city.chart([], [])): """Astar :: nodenumber -> nodenumber -> chart -> [nodenumbers]""" #a few checks at the start if (space.lookupCity(start) == city.cityNotFound) or (space.lookupCity(goal) == city.cityNotFound): #start or goal does not exist. Do not search! return nonExistentPath #Set up some preliminary lists fringe = [start] #add the starting node to the fringe visited = [] #no nodes visited yet paths = {} #this will hold each node's predecessor #keep track of how far you've traveled on each node gScore = {start: 0} #begin with the start node's value in there workingNode = start #we're going to use this to denote the node we are working on #It will get reset in the first loop, This is to make sure its in this scope. while len(fringe) != 0: #choose the node that is best to traverse to best = -1 for eachNode in fringe: fCost = getTotalCost(eachNode, goal, gScore[eachNode], space) if (best == -1) or (fCost < best): #first run or better than current best: best = fCost #then the current best is the new best workingNode = eachNode #the next node to visit is this node #test to see if that is the goal if workingNode == goal: #reconstruct the path from the workingNode to the goal return reconstructPath(paths, workingNode) #if not, add it to the visited set, expand it's neighbors and add them to the fringe visited.append(workingNode) fringe.remove(workingNode) workingNeighbors = space.getNeighbors(workingNode) for eachNeighbor in workingNeighbors: #REMEMBER THAT eachNeighbor is a tuple of form (node, cost) updateNode = False newGvalue = gScore[workingNode] + eachNeighbor[1] if eachNeighbor[0] in visited: #if a Neighbor is in the visited set, we'll skip it continue elif eachNeighbor[0] not in fringe: #if it's not in the fringe, we will add it and update it's values fringe.append(eachNeighbor[0]) updateNode = True elif newGvalue < gScore[eachNeighbor[0]]: #at this point, we know its not visited and its in the fringe #if the new gscore is better than the old one, we want to update the stats for it updateNode = True if updateNode: #we want to update the node's predecessor, and it's gScore value paths[ eachNeighbor[0]] = workingNode #come from the working node gScore[eachNeighbor[ 0]] = newGvalue #the new G value is better than before #end for loop #end while loop #if we make it out of the main loop, then we didn't find it. return nonExistentPath
def getTotalCost(current=0, goal=0, gVal=0, space=city.chart([], [])): """getTotalCost :: nodenumber -> nodenumber -> number -> chart -> number""" #find the cost for the H() function #add H and G together and return F hVal = heuristic(current, goal, space) return hVal + gVal
if __name__ == "__main__": #unit testing print "Test 1 : Testing getEuclideanDistance" assert 1 == getEuclideanDistance((0, 0), (1, 0)) assert 6 == int(getEuclideanDistance( (12, 4), (6, 7))) #really long double, just truncating it print "Test 2 : Testing reconstructPath" dir2 = {2: 1, 3: 2, 4: 3, 5: 3, 6: 5, 7: 6, 8: 6} path2 = reconstructPath(dir2, 8) assert path2 == [1, 2, 3, 5, 6, 8] print "Test 3 : Testing heuristic" citylist3 = [(1, '', 35, 24), (2, '', 31, 22), (3, '', 34, 21), (4, '', 27, 20)] edgelist3 = [(1, 2, 5), (1, 3, 3), (2, 1, 5), (2, 3, 3), (2, 4, 5), (3, 1, 3), (3, 2, 3), (4, 2, 5)] chart3 = city.chart(citylist3, edgelist3) assert int(heuristic(1, 2, chart3)) == 4 print "Test 4 : Testing getTotalCost" assert int(getTotalCost(1, 2, 2, chart3)) == 6 print "Test 5 : Testing Simple A* Search" path5 = Astar(1, 4, chart3) assert path5 == [1, 2, 4] path5 = Astar(0, 4, chart3) assert path5 == nonExistentPath path5 = Astar(1, 5, chart3) assert path5 == nonExistentPath
################################################################################ # James Baiera # # Kent State University # # 11-16-2011 # # # # This file contains a map of the USA in graph format. We will use this data # # to test our A* search algorithm # ################################################################################ import astar import city citylist = [(1, "Augusta", 35,24),(2, "Albany", 31,22),(3, "Hartford", 34, 21),(4, "Cleveland", 27,20),(5, "Dover", 33,17),(6, "Columbia", 35, 12),(7, "Lansing", 24, 21),(8, "Flint", 24, 23),(9, "Chicago", 21, 20),(10, "Atlanta", 29, 9),(11, "Tallahassee", 32, 6),(12, "Miami", 34, 3),(13, "New Orleans", 25, 6),(14, "St. Paul", 19, 22),(15, "Apostle", 22, 24),(16, "Topeka", 19, 14),(17, "Fargo", 18, 25),(18, "El Paso", 16, 6),(19, "Tucson", 11, 5),(20, "Helena", 10, 24),(21, "Boise", 9, 20),(22, "Reno", 6, 16),(23, "Los Angeles", 4, 8),(24, "San Francisco", 2, 14),(25, "Portland", 3, 21),(26, "Seattle", 3, 25),(27, "Austin", 20, 2),(28, "Santa Fe", 13, 11)] edgelist = [(1,2,5),(1,3,3),(2,1,5),(2,3,3),(2,4,5),(3,1,3),(3,2,3),(3,5,6),(4,2,5),(4,5,7),(4,7,3),(4,10,15),(5,3,6),(5,4,7),(5,6,9),(6,5,9),(6,10,8),(6,11,10),(7,4,3),(7,8,3),(7,9,4),(8,7,3),(9,7,4),(9,14,4),(9,16,8),(10,4,15),(10,6,8),(10,11,7),(10,13,6),(10,16,15),(11,6,10),(11,10,7),(11,13,8),(11,12,6),(12,11,6),(13,10,6),(13,11,8),(13,27,9),(14,9,4),(14,15,5),(14,17,4),(15,14,5),(15,17,5),(16,9,8),(16,10,15),(16,22,17),(16,28,8),(17,14,4),(17,15,5),(17,20,9),(18,19,7),(18,27,10),(18,28,8),(19,18,7),(19,23,11),(20,17,9),(20,21,5),(20,26,8),(21,20,5),(21,22,7),(22,16,17),(22,21,7),(22,23,11),(22,25,9),(22,28,12),(23,19,11),(23,22,11),(23,24,9),(24,23,9),(24,25,9),(25,22,9),(25,24,9),(25,26,5),(26,20,8),(26,25,5),(27,13,9),(27,18,10),(28,16,8),(28,18,8),(28,22,12)] mychart = city.chart(citylist,edgelist) print "1 to 7: ", testpath = astar.Astar(1,7,mychart) print testpath print "17 to 1: ", testpath = astar.Astar(17, 1, mychart) print testpath print "1 to 24: ", testpath = astar.Astar(1, 24, mychart) print testpath print "1 to 26: ", testpath = astar.Astar(1, 26, mychart)
(5, 3, 6), (5, 4, 7), (5, 6, 9), (6, 5, 9), (6, 10, 8), (6, 11, 10), (7, 4, 3), (7, 8, 3), (7, 9, 4), (8, 7, 3), (9, 7, 4), (9, 14, 4), (9, 16, 8), (10, 4, 15), (10, 6, 8), (10, 11, 7), (10, 13, 6), (10, 16, 15), (11, 6, 10), (11, 10, 7), (11, 13, 8), (11, 12, 6), (12, 11, 6), (13, 10, 6), (13, 11, 8), (13, 27, 9), (14, 9, 4), (14, 15, 5), (14, 17, 4), (15, 14, 5), (15, 17, 5), (16, 9, 8), (16, 10, 15), (16, 22, 17), (16, 28, 8), (17, 14, 4), (17, 15, 5), (17, 20, 9), (18, 19, 7), (18, 27, 10), (18, 28, 8), (19, 18, 7), (19, 23, 11), (20, 17, 9), (20, 21, 5), (20, 26, 8), (21, 20, 5), (21, 22, 7), (22, 16, 17), (22, 21, 7), (22, 23, 11), (22, 25, 9), (22, 28, 12), (23, 19, 11), (23, 22, 11), (23, 24, 9), (24, 23, 9), (24, 25, 9), (25, 22, 9), (25, 24, 9), (25, 26, 5), (26, 20, 8), (26, 25, 5), (27, 13, 9), (27, 18, 10), (28, 16, 8), (28, 18, 8), (28, 22, 12)] mychart = city.chart(citylist, edgelist) print "1 to 7: ", testpath = astar.Astar(1, 7, mychart) print testpath print "17 to 1: ", testpath = astar.Astar(17, 1, mychart) print testpath print "1 to 24: ", testpath = astar.Astar(1, 24, mychart) print testpath print "1 to 26: ", testpath = astar.Astar(1, 26, mychart)
def Astar(start=0, goal=0, space=city.chart([],[])): """Astar :: nodenumber -> nodenumber -> chart -> [nodenumbers]""" #a few checks at the start if (space.lookupCity(start) == city.cityNotFound) or (space.lookupCity(goal) == city.cityNotFound): #start or goal does not exist. Do not search! return nonExistentPath #Set up some preliminary lists fringe = [start] #add the starting node to the fringe visited = [] #no nodes visited yet paths = {} #this will hold each node's predecessor #keep track of how far you've traveled on each node gScore = {start:0} #begin with the start node's value in there workingNode = start #we're going to use this to denote the node we are working on #It will get reset in the first loop, This is to make sure its in this scope. while len(fringe) != 0: #choose the node that is best to traverse to best = -1 for eachNode in fringe: fCost = getTotalCost(eachNode, goal, gScore[eachNode], space) if (best == -1) or (fCost < best): #first run or better than current best: best = fCost #then the current best is the new best workingNode = eachNode #the next node to visit is this node #test to see if that is the goal if workingNode == goal: #reconstruct the path from the workingNode to the goal return reconstructPath(paths, workingNode) #if not, add it to the visited set, expand it's neighbors and add them to the fringe visited.append(workingNode) fringe.remove(workingNode) workingNeighbors = space.getNeighbors(workingNode) for eachNeighbor in workingNeighbors: #REMEMBER THAT eachNeighbor is a tuple of form (node, cost) updateNode = False newGvalue = gScore[workingNode] + eachNeighbor[1] if eachNeighbor[0] in visited: #if a Neighbor is in the visited set, we'll skip it continue elif eachNeighbor[0] not in fringe: #if it's not in the fringe, we will add it and update it's values fringe.append(eachNeighbor[0]) updateNode = True elif newGvalue < gScore[eachNeighbor[0]]: #at this point, we know its not visited and its in the fringe #if the new gscore is better than the old one, we want to update the stats for it updateNode = True if updateNode: #we want to update the node's predecessor, and it's gScore value paths[eachNeighbor[0]] = workingNode #come from the working node gScore[eachNeighbor[0]] = newGvalue #the new G value is better than before #end for loop #end while loop #if we make it out of the main loop, then we didn't find it. return nonExistentPath
def getTotalCost(current=0, goal=0, gVal=0, space=city.chart([],[])): """getTotalCost :: nodenumber -> nodenumber -> number -> chart -> number""" #find the cost for the H() function #add H and G together and return F hVal = heuristic(current, goal, space) return hVal + gVal
if __name__ == "__main__": #unit testing print "Test 1 : Testing getEuclideanDistance" assert 1 == getEuclideanDistance((0,0),(1,0)) assert 6 == int(getEuclideanDistance((12,4),(6,7))) #really long double, just truncating it print "Test 2 : Testing reconstructPath" dir2 = {2:1, 3:2, 4:3, 5:3, 6:5, 7:6, 8:6} path2 = reconstructPath(dir2, 8) assert path2 == [1,2,3,5,6,8] print "Test 3 : Testing heuristic" citylist3 = [(1,'',35,24),(2,'',31,22),(3,'',34,21),(4,'',27,20)] edgelist3 = [(1,2,5),(1,3,3),(2,1,5),(2,3,3),(2,4,5),(3,1,3),(3,2,3),(4,2,5)] chart3 = city.chart(citylist3, edgelist3) assert int(heuristic(1,2,chart3)) == 4 print "Test 4 : Testing getTotalCost" assert int(getTotalCost(1,2,2,chart3)) == 6 print "Test 5 : Testing Simple A* Search" path5 = Astar(1,4,chart3) assert path5 == [1,2,4] path5 = Astar(0,4,chart3) assert path5 == nonExistentPath path5 = Astar(1,5,chart3) assert path5 == nonExistentPath