def a_star_search(start, goal, heuristics=None): visited = [] frontier = PriorityQueue() start.set_dist_from_start(0) if heuristics is None: h_dist = 0 else: h_dist = heuristics.get((start.getName(), goal.getName()), 0) frontier.insertItem( h_dist, start) #key should be the sum of distance from start and h() #implement the algorithm while not frontier.isEmpty(): #start your code here ... if heuristics is None: h_dist2 = 0 else: h_dist2 = heuristics.get( (frontier.queue[0][1].getName(), goal.getName()), 0) #update the distance from start in the node frontier.queue[0][1].set_dist_from_start((frontier.minKey() - h_dist2)) v = frontier.removeMin() #return the 1st node in the priority queue visited.append(v) if v.getName() == goal.getName(): #Include this line before returning the path (when the goal is found) print("\nThe total number of nodes visited:", len(visited)) return retrieve_path(v, start) else: neighbors = v.getNeighbors() for (item, diskey) in neighbors: if not (item in visited): if heuristics is None: h_dist3 = 0 else: h_dist3 = heuristics.get( (item.getName(), goal.getName()), 0) dist = diskey + v.get_dist_from_start() + h_dist3 if not (frontier.contains(item)): frontier.insertItem(dist, item) item.setParent(v) else: for tup in frontier.queue: if tup[1] == item: if dist < tup[0]: frontier.update(dist, item) tup[1].setParent(v)
def prims_algorithm_mst(graph): """ Prim's algorithm, this algorithm has the same time complexity as Djikstra's single source shorted path algorithm. This particular algorithm is O((V ** 2) + (V * E)) but with a priority queue or vEB tree this can be reduced to O((V * log(V)) + (V * E)) a time complexity equivalent to Djikstra's """ if not isinstance(graph, Graph): raise TypeError('this function expects an instance of Graph') queue = PriorityQueue(graph) root = None nodes = {u: TreeNode(u) for u in graph.vertices} while not queue.is_empty(): u = queue.pop_min() if root is None: root = nodes[u] for v in graph.adj[u]: if queue.contains(v): queue.update(v, graph.weights[(u, v)]) nodes[v].parent = nodes[u] for n in nodes: node = nodes[n] if node.parent is not None: node.parent.children.append(node) return root