コード例 #1
0
    def del_edge(self, graph, edge):

        if edge not in set(self._mst):
            return self._mst

        # init disjoint set with iterable object
        uf = GenericUnionFind([(e.either(), e.other(e.either()))
                               for e in self._mst if e is not edge])

        pq = MinPQ()
        for e in graph.edges():
            if e is not edge:
                pq.insert(e)

        tmp = Queue([e for e in self._mst if e is not edge])

        # find the minimum edge with both vertices is not connected
        while not pq.is_empty():
            min_edge = pq.del_min()
            vertx_a = min_edge.either()
            vertx_b = min_edge.other(vertx_a)

            if uf.connected(vertx_a, vertx_b):
                continue
            # only need one edge
            tmp.enqueue(min_edge)
            break

        self._mst = tmp
        return self._mst
コード例 #2
0
 def _init_priority_queue(self, vertices, forest):
     dup_set = set()
     pq = MinPQ()
     for v in vertices:
         for edge in forest.adjacent_edges(v):
             if edge not in dup_set:
                 pq.insert(edge)
                 dup_set.add(edge)
     return pq
コード例 #3
0
 def _init_priority_queue(self, vertices, forest):
     dup_set = set()
     pq = MinPQ()
     for v in vertices:
         for edge in forest.adjacent_edges(v):
             if edge not in dup_set:
                 pq.insert(edge)
                 dup_set.add(edge)
     return pq
コード例 #4
0
class LazyPrimMST(object):

    """
      Lazy version Prim-Minimum-Spanning-Tree. This algorithm is a greedy strategy.
    First input a start vertex, then visit all the adjacent edges, if the other side
    of the vertex is not marked, put the edge into a priority queue. The result queue
    only enqueue those edges with small weight and either vertex is not marked.
    The cost of space is proportional to number of edges, and the worst case of running time
    is proportional to O(ElogE) (E is the number of edges).
    >>> test_data = ((4, 5, 0.35), (4, 7, 0.37), (5, 7, 0.28), (0, 7, 0.16), (1, 5, 0.32),
    ...              (0, 4, 0.38), (2, 3, 0.17), (1, 7, 0.19), (0, 2, 0.26), (1, 2, 0.36),
    ...              (1, 3, 0.29), (2, 7, 0.34), (6, 2, 0.4), (3, 6, 0.52), (6, 0, 0.58),
    ...              (6, 4, 0.93))
    >>> ewg = EdgeWeightedGraph()
    >>> for a, b, weight in test_data:
    ...    edge = Edge(a, b, weight)
    ...    ewg.add_edge(edge)
    ...
    >>> lazy_prim_mst = LazyPrimMST(ewg, 0)
    >>> lazy_prim_mst.weight()
    1.81
    >>> [edge for edge in lazy_prim_mst.edges()]
    [0-7 0.16, 1-7 0.19, 0-2 0.26, 2-3 0.17, 5-7 0.28, 4-5 0.35, 6-2 0.4]
    """

    def __init__(self, graph, start_vertex):
        self._pq = MinPQ()
        self._marked = defaultdict(bool)
        self._mst = Queue()
        self.visit(graph, start_vertex)
        while not self._pq.is_empty():
            edge = self._pq.del_min()
            a = edge.either()
            b = edge.other(a)
            if self._marked[a] and self._marked[b]:
                continue
            self._mst.enqueue(edge)
            if not self._marked[a]:
                self.visit(graph, a)
            if not self._marked[b]:
                self.visit(graph, b)

    def visit(self, graph, vertex):
        self._marked[vertex] = True
        for edge in graph.adjacent_edges(vertex):
            if not self._marked[edge.other(vertex)]:
                self._pq.insert(edge)

    def edges(self):
        return self._mst

    # 4.3.31 practice, lazy weight implementation
    def weight(self):
        return sum(i.weight for i in self._mst)
コード例 #5
0
    def build_trie(freq):
        min_pq = MinPQ()
        for i in range(256):
            if freq[i]:
                min_pq.insert(chr(i), freq, None, None)

        while min_pq.size() > 1:
            left = min_pq.del_min()
            right = min_pq.del_min()
            parent = Node('\0', left.freq + right.freq, left, right)
            min_pq.insert(parent)
        return min_pq.del_min()
コード例 #6
0
class LazyPrimMST(object):
    """
      Lazy version Prim-Minimum-Spanning-Tree. This algorithm is a greedy strategy.
    First input a start vertex, then visit all the adjacent edges, if the other side
    of the vertex is not marked, put the edge into a priority queue. The result queue
    only enqueue those edges with small weight and either vertex is not marked.
    The cost of space is proportional to number of edges, and the worst case of running time
    is proportional to O(ElogE) (E is the number of edges).
    >>> test_data = ((4, 5, 0.35), (4, 7, 0.37), (5, 7, 0.28), (0, 7, 0.16), (1, 5, 0.32),
    ...              (0, 4, 0.38), (2, 3, 0.17), (1, 7, 0.19), (0, 2, 0.26), (1, 2, 0.36),
    ...              (1, 3, 0.29), (2, 7, 0.34), (6, 2, 0.4), (3, 6, 0.52), (6, 0, 0.58),
    ...              (6, 4, 0.93))
    >>> ewg = EdgeWeightedGraph()
    >>> for a, b, weight in test_data:
    ...    edge = Edge(a, b, weight)
    ...    ewg.add_edge(edge)
    ...
    >>> lazy_prim_mst = LazyPrimMST(ewg, 0)
    >>> lazy_prim_mst.weight()
    1.81
    >>> [edge for edge in lazy_prim_mst.edges()]
    [0-7 0.16, 1-7 0.19, 0-2 0.26, 2-3 0.17, 5-7 0.28, 4-5 0.35, 6-2 0.4]
    """
    def __init__(self, graph, start_vertex):
        self._pq = MinPQ()
        self._marked = defaultdict(bool)
        self._mst = Queue()
        self.visit(graph, start_vertex)
        while not self._pq.is_empty():
            edge = self._pq.del_min()
            a = edge.either()
            b = edge.other(a)
            if self._marked[a] and self._marked[b]:
                continue
            self._mst.enqueue(edge)
            if not self._marked[a]:
                self.visit(graph, a)
            if not self._marked[b]:
                self.visit(graph, b)

    def visit(self, graph, vertex):
        self._marked[vertex] = True
        for edge in graph.adjacent_edges(vertex):
            if not self._marked[edge.other(vertex)]:
                self._pq.insert(edge)

    def edges(self):
        return self._mst

    # 4.3.31 practice, lazy weight implementation
    def weight(self):
        return sum(i.weight for i in self._mst)
コード例 #7
0
 def __init__(self, graph, start_vertex):
     self._marked = defaultdict(bool)
     self._mst = Queue()
     self.pq = MinPQ()
     self.visit(graph, start_vertex)
     while not self.pq.is_empty():
         edge = self.pq.del_min()
         if self._marked[edge[1]] and self._marked[edge[2]]:
             continue
         self._mst.enqueue(edge)
         if not self._marked[edge[1]]:
             self.visit(graph, edge[1])
         if not self._marked[edge[2]]:
             self.visit(graph, edge[2])
コード例 #8
0
    def build_trie(freq):
        min_pq = MinPQ()
        for i in range(256):
            if freq[i]:
                min_pq.insert(chr(i), freq, None, None)

        while min_pq.size() > 1:
            left = min_pq.del_min()
            right = min_pq.del_min()
            parent = Node('\0', left.freq + right.freq, left, right)
            min_pq.insert(parent)
        return min_pq.del_min()
コード例 #9
0
 def __init__(self, graph, start_vertex):
     self._pq = MinPQ()
     self._marked = defaultdict(bool)
     self._mst = Queue()
     self.visit(graph, start_vertex)
     while not self._pq.is_empty():
         edge = self._pq.del_min()
         a = edge.either()
         b = edge.other(a)
         if self._marked[a] and self._marked[b]:
             continue
         self._mst.enqueue(edge)
         if not self._marked[a]:
             self.visit(graph, a)
         if not self._marked[b]:
             self.visit(graph, b)
コード例 #10
0
    def del_edge(self, graph, edge):

        if edge not in set(self._mst):
            return self._mst

        # init disjoint set with iterable object
        uf = GenericUnionFind([(e.either(), e.other(e.either()))
                               for e in self._mst if e is not edge])

        pq = MinPQ()
        for e in graph.edges():
            if e is not edge:
                pq.insert(e)

        tmp = Queue([e for e in self._mst if e is not edge])

        # find the minimum edge with both vertices is not connected
        while not pq.is_empty():
            min_edge = pq.del_min()
            vertx_a = min_edge.either()
            vertx_b = min_edge.other(vertx_a)

            if uf.connected(vertx_a, vertx_b):
                continue
            # only need one edge
            tmp.enqueue(min_edge)
            break

        self._mst = tmp
        return self._mst
コード例 #11
0
 def __init__(self, graph, start_vertex):
     self._marked = defaultdict(bool)
     self._mst = Queue()
     self.pq = MinPQ()
     self.visit(graph, start_vertex)
     while not self.pq.is_empty():
         edge = self.pq.del_min()
         if self._marked[edge[1]] and self._marked[edge[2]]:
             continue
         self._mst.enqueue(edge)
         if not self._marked[edge[1]]:
             self.visit(graph, edge[1])
         if not self._marked[edge[2]]:
             self.visit(graph, edge[2])
コード例 #12
0
 def __init__(self, graph, start_vertex):
     self._pq = MinPQ()
     self._marked = defaultdict(bool)
     self._mst = Queue()
     self.visit(graph, start_vertex)
     while not self._pq.is_empty():
         edge = self._pq.del_min()
         a = edge.either()
         b = edge.other(a)
         if self._marked[a] and self._marked[b]:
             continue
         self._mst.enqueue(edge)
         if not self._marked[a]:
             self.visit(graph, a)
         if not self._marked[b]:
             self.visit(graph, b)
コード例 #13
0
class PrimitiveLazyPrimMST(object):

    """
    >>> test_data = ((0.35, 4, 5), (0.37, 4, 7), (0.28, 5, 7), (0.16, 0, 7), (0.32, 1, 5),
    ...              (0.38, 0, 4), (0.17, 2, 3), (0.19, 1, 7), (0.26, 0, 2), (0.36, 1, 2),
    ...              (0.29, 1, 3), (0.34, 2, 7), (0.4, 6, 2), (0.52, 3, 6), (0.58, 6, 0),
    ...              (0.93, 6, 4))
    >>> wg = WeightedGraph()
    >>> for edge in test_data:
    ...     wg.add_edge(edge)
    ...
    >>> primitive_mst = PrimitiveLazyPrimMST(wg, 0)
    >>> [edge for edge in primitive_mst.edges()]
    [(0.16, 0, 7), (0.19, 1, 7), (0.26, 0, 2), (0.17, 2, 3), (0.28, 5, 7), (0.35, 4, 5), (0.4, 6, 2)]
    """

    def __init__(self, graph, start_vertex):
        self._marked = defaultdict(bool)
        self._mst = Queue()
        self.pq = MinPQ()
        self.visit(graph, start_vertex)
        while not self.pq.is_empty():
            edge = self.pq.del_min()
            if self._marked[edge[1]] and self._marked[edge[2]]:
                continue
            self._mst.enqueue(edge)
            if not self._marked[edge[1]]:
                self.visit(graph, edge[1])
            if not self._marked[edge[2]]:
                self.visit(graph, edge[2])

    def visit(self, graph, vertex):
        self._marked[vertex] = True
        for edge in graph.adjacent_edges(vertex):
            if edge[1] == vertex and not self._marked[edge[2]]:
                self.pq.insert(edge)
            elif edge[2] == vertex and not self._marked[edge[1]]:
                self.pq.insert(edge)

    def edges(self):
        return self._mst

    def weight(self):
        return sum(edge[0] for edge in self._mst)
コード例 #14
0
class PrimitiveLazyPrimMST(object):
    """
    >>> test_data = ((0.35, 4, 5), (0.37, 4, 7), (0.28, 5, 7), (0.16, 0, 7), (0.32, 1, 5),
    ...              (0.38, 0, 4), (0.17, 2, 3), (0.19, 1, 7), (0.26, 0, 2), (0.36, 1, 2),
    ...              (0.29, 1, 3), (0.34, 2, 7), (0.4, 6, 2), (0.52, 3, 6), (0.58, 6, 0),
    ...              (0.93, 6, 4))
    >>> wg = WeightedGraph()
    >>> for edge in test_data:
    ...     wg.add_edge(edge)
    ...
    >>> primitive_mst = PrimitiveLazyPrimMST(wg, 0)
    >>> [edge for edge in primitive_mst.edges()]
    [(0.16, 0, 7), (0.19, 1, 7), (0.26, 0, 2), (0.17, 2, 3), (0.28, 5, 7), (0.35, 4, 5), (0.4, 6, 2)]
    """
    def __init__(self, graph, start_vertex):
        self._marked = defaultdict(bool)
        self._mst = Queue()
        self.pq = MinPQ()
        self.visit(graph, start_vertex)
        while not self.pq.is_empty():
            edge = self.pq.del_min()
            if self._marked[edge[1]] and self._marked[edge[2]]:
                continue
            self._mst.enqueue(edge)
            if not self._marked[edge[1]]:
                self.visit(graph, edge[1])
            if not self._marked[edge[2]]:
                self.visit(graph, edge[2])

    def visit(self, graph, vertex):
        self._marked[vertex] = True
        for edge in graph.adjacent_edges(vertex):
            if edge[1] == vertex and not self._marked[edge[2]]:
                self.pq.insert(edge)
            elif edge[2] == vertex and not self._marked[edge[1]]:
                self.pq.insert(edge)

    def edges(self):
        return self._mst

    def weight(self):
        return sum(edge[0] for edge in self._mst)
コード例 #15
0
 def _init_priority_queue(self, graph):
     pq = MinPQ()
     for edge in graph.edges():
         pq.insert(edge)
     return pq
コード例 #16
0
 def _init_priority_queue(self, graph):
     pq = MinPQ()
     for edge in graph.edges():
         pq.insert(edge)
     return pq
コード例 #17
0
 def _init_priority_queue(self, graph, contain_edges):
     pq = MinPQ()
     for edge in graph.edges():
         if edge not in contain_edges:
             pq.insert(edge)
     return pq
コード例 #18
0
 def _init_priority_queue(self, graph, contain_edges):
     pq = MinPQ()
     for edge in graph.edges():
         if edge not in contain_edges:
             pq.insert(edge)
     return pq