Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
        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
Esempio n. 6
0
    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]
Esempio n. 7
0
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)
Esempio n. 8
0
    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]
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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