def __init__(self, theAnimator, colorOn=cOnQueue, colorOff=cRemovedFromQueue): """ theAnimator will usually be the GraphDisplay(Frame/Toplevel) """ PriorityQueue.__init__(self) self.Animator = theAnimator self.ColorOn = colorOn self.ColorOff = colorOff self.lastRemoved = None
def a_star(graph, source, destination, heuristic=None): # default heuristic is h=0, which makes A* behave like Dijkstra's if heuristic is None: heuristic = _return_zero closed = [] pq = PriorityQueue() # for reconstructing paths parent = {} # cost of going from source to node dist = {source: 0} # total cost of getting from source to destination by passing through node estimate = {} # todo: rewrite to make more efficient---dict.fromkeys? for node in graph.vertices: if node == source: dist[node] = 0 estimate[node] = heuristic(node, destination) else: dist[node] = inf estimate[node] = inf pq.insert(source, estimate[source]) while pq: node = pq.extract() # yay, we made it! if node == destination: return reconstruct_path(destination, parent) closed.append(node) for neighbor in graph.adj(node): if neighbor in closed: continue if neighbor not in pq: pq.insert(neighbor, estimate[neighbor]) # check the distance from source to neighbor # todo: make sure that weight is what I actually want here length = dist[node] + graph.weight(node, neighbor) # update! if length < dist[neighbor]: parent[neighbor] = node dist[neighbor] = length estimate[neighbor] = length + heuristic(neighbor, destination) pq.update_priority(neighbor, estimate[neighbor]) # didn't find a path return None
def shortest_path(self, source): q = PriorityQueue() dist = {} parent = {} for v in self.vertices: if v == source: dist[v] = 0 else: dist[v] = inf parent[v] = None q.insert(v, dist[v]) while not q.is_empty(): node = q.extract() for neighbor in self.adj(node): length = dist[node] + self.weight(node, neighbor) # update if length < dist[neighbor]: dist[neighbor] = length parent[neighbor] = node q.update_key(neighbor, length) return namedtuple("Shortest_Path", ["length", "parent"])(dist, parent)
def weighted_shortest_paths(graph, source): # todo: merge this into shortest_path and shortest_path_length pq = PriorityQueue() dist = {} parent = {} for v in graph.vertices: if v == source: dist[v] = 0 else: dist[v] = inf parent[v] = None pq.insert(v, dist[v]) while pq: node = pq.extract() for neighbor in graph.adj(node): length = dist[node] + graph.weight(node, neighbor) # update if length < dist[neighbor]: dist[neighbor] = length parent[neighbor] = node pq.update_priority(neighbor, length) return namedtuple("Shortest_Path", ["length", "parent"])(dist, parent)
def DeleteMin(self): v = PriorityQueue.DeleteMin(self) self.Animator.SetVertexColor(v, self.ColorOff) if self.lastRemoved is not None: self.Animator.SetVertexFrameWidth(self.lastRemoved, self.Animator.gVertexFrameWidth) self.Animator.SetVertexFrameWidth(v, 6) self.lastRemoved = v return v
def dijkstra(self, start_id): start = self.nodes[start_id] visited = set([start_id]) distance = defaultdict(lambda: sys.maxint) distance[start_id] = 0 prev = dict() pq = PriorityQueue() for edge in start.iteredges(): pq.enqueue((edge.weight, edge.src, edge.dest)) while len(pq) != 0: (weight, src, dest) = pq.dequeue() if dest not in visited: visited.add(dest) prev[dest] = src distance[dest] = distance[src] + self.nodes[src].getEdge( dest).weight for edge in self.nodes[dest].iteredges(): total_distance = distance[dest] + edge.weight pq.enqueue((total_distance, dest, edge.dest))
def DecreaseKey(self, value, newSortKey): PriorityQueue.DecreaseKey(self, value, newSortKey) self.Animator.BlinkVertex(value)
def Insert(self, value, sortKey): PriorityQueue.Insert(self, value, sortKey) self.Animator.SetVertexColor(value, self.ColorOn)
def __init__(self, s): self.source_string = s self.source_frequency = Counter(self.source_string) self.source_association = {} self.pqueue = pq.PriorityQueue() self.root = None