def nagamochi_forest(g): unscanned_edges = set(multigraph_edges_as_triples(g)) r = dict((node, 0) for node in g) graph_to_heap = {} unscanned_r_heap = Fibonacci_heap() for node in g: graph_to_heap[node] = unscanned_r_heap.enqueue(node, 0) partitions = {} while unscanned_r_heap: x_heap_node = unscanned_r_heap.dequeue_min() x = x_heap_node.get_value() graph_to_heap[x] = None for y, xy_es in g[x].items(): for i, edge_dict in xy_es.items(): edge = (x, y, i) if not edge in unscanned_edges: continue unscanned_edges.remove(edge) unscanned_edges.remove((y, x, i)) k = r[y] + 1 if not k in partitions: partitions[k] = set() partitions[k].add(edge) if r[x] is r[y]: r[x] += 1 r[y] += 1 y_heap_node = graph_to_heap[y] y_prio = y_heap_node.get_priority() unscanned_r_heap.decrease_key(y_heap_node, y_prio - 1) return partitions
def nagamochi_capforest(g): unscanned_edges = set(multigraph_edges_as_triples(g)) r = dict((node, 0) for node in g) q = {} graph_to_heap = {} unscanned_r_heap = Fibonacci_heap() for node in g: graph_to_heap[node] = unscanned_r_heap.enqueue(node, 0) while unscanned_r_heap: x_heap_node = unscanned_r_heap.dequeue_min() x = x_heap_node.get_value() for y, xy_dict in g[x].items(): for i, edge_data in xy_dict.items(): edge = (x, y, i) if not edge in unscanned_edges: continue unscanned_edges.remove(edge) unscanned_edges.remove((y, x, i)) c = edge_data[EDGE_CAPACITY_ATTR] q[edge] = r[y] + c r[y] = r[y] + c y_heap_node = graph_to_heap[y] y_prio = y_heap_node.get_priority() unscanned_r_heap.decrease_key(y_heap_node, y_prio - c) return q
def nagamochi_capforest(g): unscanned_edges = set(multigraph_edges_as_triples(g)) r = dict((node, 0) for node in g) q = {} graph_to_heap = {} unscanned_r_heap = Fibonacci_heap() for node in g: graph_to_heap[node] = unscanned_r_heap.enqueue(node, 0) while unscanned_r_heap: x_heap_node = unscanned_r_heap.dequeue_min() x = x_heap_node.get_value() for y, xy_dict in g[x].items(): for i, edge_data in xy_dict.items(): edge = (x, y, i) if not edge in unscanned_edges: continue unscanned_edges.remove(edge) unscanned_edges.remove((y, x, i)) c = edge_data[EDGE_CAPACITY_ATTR] q[edge] = r[y] + c r[y] = r[y] + c y_heap_node = graph_to_heap[y] y_prio = y_heap_node.get_priority() unscanned_r_heap.decrease_key(y_heap_node, y_prio - c) return q
def nagamochi_forest(g): unscanned_edges = set(multigraph_edges_as_triples(g)) r = dict((node, 0) for node in g) graph_to_heap = {} unscanned_r_heap = Fibonacci_heap() for node in g: graph_to_heap[node] = unscanned_r_heap.enqueue(node, 0) partitions = {} while unscanned_r_heap: x_heap_node = unscanned_r_heap.dequeue_min() x = x_heap_node.get_value() graph_to_heap[x] = None for y, xy_es in g[x].items(): for i, edge_dict in xy_es.items(): edge = (x, y, i) if not edge in unscanned_edges: continue unscanned_edges.remove(edge) unscanned_edges.remove((y, x, i)) k = r[y] + 1 if not k in partitions: partitions[k] = set() partitions[k].add(edge) if r[x] is r[y]: r[x] += 1 r[y] += 1 y_heap_node = graph_to_heap[y] y_prio = y_heap_node.get_priority() unscanned_r_heap.decrease_key(y_heap_node, y_prio - 1) return partitions
def buildMST(self, startx, starty): print 'building MST' mstT0 = time.time() heap = Fibonacci_heap() self.startpt = (startx, starty) heapTempGraph = {} for neighCoor, neighCost in self.pixelNodeList2D[ self.startpt].neighbors.iteritems(): heapTempGraph[neighCoor] = heap.enqueue(value=neighCoor, priority=neighCost) self.pixelNodeList2D[neighCoor].totalCost = neighCost self.pixelNodeList2D[neighCoor].prevNode = self.startpt while heap.m_size != 0: # print 'deq' # deqt0 = time.time() q = heap.dequeue_min() # mark q as EXPANDED (state = 0) self.pixelNodeList2D[q.m_elem].state = 0 self.pixelNodeList2D[q.m_elem].totalCost = q.m_priority for rCoor, rCost in self.pixelNodeList2D[ q.m_elem].neighbors.iteritems(): rState = self.pixelNodeList2D[rCoor].state if rState != 0: if rState == -1: self.pixelNodeList2D[rCoor].prevNode = q.m_elem self.pixelNodeList2D[ rCoor].totalCost = self.pixelNodeList2D[ q.m_elem].totalCost + rCost heapTempGraph[rCoor] = heap.enqueue( value=rCoor, priority=self.pixelNodeList2D[rCoor].totalCost) self.pixelNodeList2D[rCoor].state = 1 else: if self.pixelNodeList2D[ rCoor].totalCost > self.pixelNodeList2D[ q.m_elem].totalCost + rCost: self.pixelNodeList2D[rCoor].prevNode = q.m_elem self.pixelNodeList2D[ rCoor].totalCost = self.pixelNodeList2D[ q.m_elem].totalCost + rCost heap.decrease_key( heapTempGraph[rCoor], self.pixelNodeList2D[rCoor].totalCost) # deqTime = time.time() - deqt0 # print deqTime self.pixelNodeList2D[self.startpt].prevNode = None mstTime = time.time() - mstT0 print mstTime self.built_MST = True
def dijkstra_search(self, source_vertex: V, target_vertex: V) -> Tuple[List[V], E]: self._assert_contains_vertices(source_vertex, target_vertex) # short-circuit for search for source if source_vertex == target_vertex: return [source_vertex], 0 graph = self.graph parents = {} queue = Fibonacci_heap() # enqueue source vertex parents[source_vertex] = (source_vertex, 0, queue.enqueue(source_vertex, 0)) # do search while len(queue) > 0: vertex = queue.dequeue_min().get_value() # check for target vertex if vertex == target_vertex: break for edge in graph.edges_from_vertex(vertex): adjacent_vertex = edge.get_target_vertex() priority = edge.get_weight() + parents[vertex][1] if adjacent_vertex not in parents: # push new vertex parents[adjacent_vertex] = (vertex, priority, queue.enqueue( adjacent_vertex, priority)) elif priority < parents[adjacent_vertex][1]: # adjust priority of adjacent_vertex entry = parents[adjacent_vertex][2] queue.decrease_key(entry, priority) parents[adjacent_vertex] = (vertex, priority, entry) if target_vertex not in parents: raise NoGraphPathException( "Source and target vertices are not linked in the graph") parent = parents[target_vertex][0] path = [target_vertex, parent] while parent != source_vertex: parent = parents[parent][0] path.append(parent) return reversed(path), parents[target_vertex][1]
def dijkstra(graph, start, end, flag="shortest"): """Calculate the shortest path between a start- and an end-vertex. `graph` needs to support at least neighbors(n) which returns a list of new nodes and weight(a,b) returning a float value. Smaller weights are preferred by the algorithm. """ prev = {} costs = {} entry = {} remaining = set([end]) weight_fn = COST_FN[flag] costs[start] = 0.0 queue = Fibonacci_heap() entry[start] = queue.enqueue(start, 0.0) while queue: system = queue.dequeue_min().get_value() if system in remaining: remaining.remove(system) # Early exit as we found everything if not remaining: break for neighbor in graph.neighbors(system): if neighbor in prev: # we have already seen this neighbor continue new_cost = costs[system] + weight_fn(graph, neighbor) if neighbor in costs and new_cost < costs[neighbor]: costs[neighbor] = new_cost prev[neighbor] = system queue.decrease_key(entry[neighbor], costs[neighbor]) if neighbor not in costs: costs[neighbor] = new_cost prev[neighbor] = system entry[neighbor] = queue.enqueue(neighbor, costs[neighbor]) return path(prev, start, end)
def dijkstra_search(self, source_vertex: V, target_vertex: V) -> Tuple[List[V], E]: self._assert_contains_vertices(source_vertex, target_vertex) # short-circuit for search for source if source_vertex == target_vertex: return [source_vertex], 0 graph = self.graph parents = {} queue = Fibonacci_heap() # enqueue source vertex parents[source_vertex] = (source_vertex, 0, queue.enqueue(source_vertex, 0)) # do search while len(queue) > 0: vertex = queue.dequeue_min().get_value() # check for target vertex if vertex == target_vertex: break for edge in graph.edges_from_vertex(vertex): adjacent_vertex = edge.get_target_vertex() priority = edge.get_weight() + parents[vertex][1] if adjacent_vertex not in parents: # push new vertex parents[adjacent_vertex] = (vertex, priority, queue.enqueue(adjacent_vertex, priority)) elif priority < parents[adjacent_vertex][1]: # adjust priority of adjacent_vertex entry = parents[adjacent_vertex][2] queue.decrease_key(entry, priority) parents[adjacent_vertex] = (vertex, priority, entry) if target_vertex not in parents: raise NoGraphPathException("Source and target vertices are not linked in the graph") parent = parents[target_vertex][0] path = [target_vertex, parent] while parent != source_vertex: parent = parents[parent][0] path.append(parent) return reversed(path), parents[target_vertex][1]
def dijkstra(graph, start, ends): prev = {} costs = {} entry = {} remaining = set(ends) costs[start] = 0.0 q = Fibonacci_heap() entry[start] = q.enqueue(start, 0.0) while q: u = q.dequeue_min().get_value() if u in remaining: remaining.remove(u) if not remaining: break for v in graph[u]: if v in prev: continue new_cost = costs[u] + 1 if v in costs and new_cost < costs[v]: costs[v] = new_cost prev[v] = u q.decrease_key(entry[v], costs[v]) if v not in costs: costs[v] = new_cost prev[v] = u entry[v] = q.enqueue(v, costs[v]) result = [] for end in ends: result.append(path(prev, start, end)) return result
class MyFibonacciHeap(dict): # ------------------------------------------------------ # have 3 container # itemlist: a list to store key # super : a dict to store entry # heap : a fibonacci heap to maintain the priority # ------------------------------------------------------ def __init__(self, *args, **kw): self.itemlist = [] self.heap = Fibonacci_heap() self.update(*args, **kw) # ------------------------------------------------------ # __setitem__ # key: item name # value: (int)priority # # ------------------------------------------------------ def __setitem__(self, key, priority): if type(priority) is not int: raise TypeError, "priority type is " + str(type(priority)) if key in self.itemlist: if self[key] < priority: raise ValueError, "priority cannot be increase." else: entry = super(MyFibonacciHeap, self).__getitem__(key) self.heap.decrease_key(entry, priority) else: self.itemlist.append(key) super(MyFibonacciHeap, self).__setitem__(key, self.heap.enqueue(key, priority)) # ------------------------------------------------------ # __getitem__ # key: the value of the item or item name # # return the priority of the entry of the key # ------------------------------------------------------ def __getitem__(self, key): return super(MyFibonacciHeap, self).__getitem__(key).get_priority() def __delitem__(self, key): entry = super(MyFibonacciHeap, self).pop(key) self.heap.delete(entry) self.itemlist.remove(key) """ def __iter__(self): ''' if self.heap.__len__() is not 0: i = 1 entry = self.heap.min() yield entry.get_value() while i < self.heap.__len__(): entry = entry.m_next yield entry.get_value() i += 1 ''' while self.heap.__len__() is not 0: entry = self.heap.dequeue_min() yield entry.get_value() self.itemlist.remove(entry.get_value()) super(MyFibonacciHeap, self).pop(entry.get_value()) """ def __repr__(self): string = '{\n ' string += ', \n '.join([str(key) + ': ' + str(self[key]) for key in self]) string += '\n}' return string def __len__(self): return super(MyFibonacciHeap, self).__len__() def keys(self): return self.itemlist def update(self, *args, **kw): if len(args) is not 0: if type(args[0]) is dict: # dict in tuple for key in args[0]: self.__setitem__(key, args[0][key]) elif type(args[0]) is list: # tuple in list in tuple for item in args[0]: self.__setitem__(item[0], item[1]) for key in kw: self.__setitem__(key, kw[key]) def enqueue(self): self.__setitem__(value, priority) def dequeue(self, value, priority): entry = self.heap.dequeue_min() self.itemlist.remove(entry.get_value()) super(MyFibonacciHeap, self).pop(entry.get_value()) return entry
class MyFibonacciHeap(dict): # ------------------------------------------------------ # have 3 container # itemlist: a list to store key # super : a dict to store entry # heap : a fibonacci heap to maintain the priority # ------------------------------------------------------ def __init__(self, *args, **kw): self.itemlist = [] self.heap = Fibonacci_heap() self.update(*args, **kw) # ------------------------------------------------------ # __setitem__ # key: item name # value: (int)priority # # ------------------------------------------------------ def __setitem__(self, key, priority): if type(priority) is not int: raise TypeError, "priority type is " + str(type(priority)) if key in self.itemlist: if self[key] < priority: raise ValueError, "priority cannot be increase." else: entry = super(MyFibonacciHeap, self).__getitem__(key) self.heap.decrease_key(entry, priority) else: self.itemlist.append(key) super(MyFibonacciHeap, self).__setitem__(key, self.heap.enqueue(key, priority)) # ------------------------------------------------------ # __getitem__ # key: the value of the item or item name # # return the priority of the entry of the key # ------------------------------------------------------ def __getitem__(self, key): return super(MyFibonacciHeap, self).__getitem__(key).get_priority() def __delitem__(self, key): entry = super(MyFibonacciHeap, self).pop(key) self.heap.delete(entry) self.itemlist.remove(key) """ def __iter__(self): ''' if self.heap.__len__() is not 0: i = 1 entry = self.heap.min() yield entry.get_value() while i < self.heap.__len__(): entry = entry.m_next yield entry.get_value() i += 1 ''' while self.heap.__len__() is not 0: entry = self.heap.dequeue_min() yield entry.get_value() self.itemlist.remove(entry.get_value()) super(MyFibonacciHeap, self).pop(entry.get_value()) """ def __repr__(self): string = '{\n ' string += ', \n '.join( [str(key) + ': ' + str(self[key]) for key in self]) string += '\n}' return string def __len__(self): return super(MyFibonacciHeap, self).__len__() def keys(self): return self.itemlist def update(self, *args, **kw): if len(args) is not 0: if type(args[0]) is dict: # dict in tuple for key in args[0]: self.__setitem__(key, args[0][key]) elif type(args[0]) is list: # tuple in list in tuple for item in args[0]: self.__setitem__(item[0], item[1]) for key in kw: self.__setitem__(key, kw[key]) def enqueue(self): self.__setitem__(value, priority) def dequeue(self, value, priority): entry = self.heap.dequeue_min() self.itemlist.remove(entry.get_value()) super(MyFibonacciHeap, self).pop(entry.get_value()) return entry