Exemplo n.º 1
0
class LazyPrimMST:
    def __init__(self, g):
        self.marked = [False for _ in range(g.V)]
        self.pq = MinPQ()
        self.mst = Queue()
        self.weight = 0

        for v in range(g.V):
            if not self.marked[v]:
                self.prim(g, v)

    def prim(self, g, v):
        self.visit(g, v)
        while not self.pq.is_empty():
            e = self.pq.del_min()
            v = e.either()
            w = e.other(v)
            if self.marked[v] and self.marked[w]:
                continue
            self.mst.enqueue(e)
            self.weight += e.weight
            if not self.marked[v]:
                self.visit(g, v)
            if not self.marked[w]:
                self.visit(g, w)

    def visit(self, g, v):
        self.marked[v] = True
        for e in g.adj[v]:
            if not self.marked[e.other(v)]:
                self.pq.insert(e)

    def edges(self):
        return self.mst
Exemplo n.º 2
0
class DijkstraSP:
    def __init__(self, g, s):
        self.cost = 0
        self.cycle = None
        self.edgeTo = [None for _ in range(g.V)]
        self.distTo = [float("inf") for _ in range(g.V)]
        self.onQ = [false for _ in range(g.V)]
        for v in range(g.V):
            self.distTo[v] = POSITIVE_INFINITY
        self.distTo[s] = 0.0

        self.queue = Queue()
        self.queue.enqueue(s)
        self.onQ[s] = True
        while not self.queue.is_empty() and not self.has_negative_cycle():
            v = self.queue.dequeue()
            self.onQ[v] = False
            self.relax(g, v)

    def relax(self, g, v):
        for e in g.adj[v]:
            w = e.To()
            if self.distTo[w] > self.distTo[v] + e.weight:
                self.distTo[w] = self.distTo[v] + e.weight
                self.edgeTo[w] = e
                if not self.onQ[w]:
                    self.queue.enqueue(w)
                    self.onQ[w] = True
            self.cost += 1
            if self.cost % g.V == 0:
                self.find_negative_cycle()
                if self.has_negative_cycle():
                    return

    def find_negative_cycle(self):
        V = len(self.edgeTo)
        spt = EdgeWeightedDigraph(V)
        for v in range(V):
            if self.edgeTo[v] != None:
                spt.add_edge(self.edgeTo[v])
        finder = EdgeWeightedDirectedCycle(spt)
        self.cycle = finder.cycle()

    def has_negative_cycle(self):
        return self.cycle != None

    def has_path_to(self, v):
        return self.distTo[v] < POSITIVE_INFINITY

    def path_to(self, v):
        if not self.has_path_to(v):
            return None
        edges = Stack()
        e = self.edgeTo[v]
        while e != None:
            edges.push(e)
            e = self.edgeTo[e.From()]
        return edges
Exemplo n.º 3
0
 def bfs(self, G, s):
     self._marked[s] = True
     queue = Queue()
     queue.enqueue(s)
     while not queue.is_empty():
         v = queue.dequeue()
         for w in G.adj[v]:
             if not self._marked[w]:
                 self.edge_to[w] = v
                 self._marked[w] = True
                 queue.enqueue(w)
 def keys(self):
     """
      Returns all keys in the symbol table
      To iterate over all of the keys in the symbol table named {@code st},
      use the foreach notation: {for key in st.keys}
     """
     queue = Queue()
     for s in self.st:
         for key in s.keys():
             queue.enqueue(key)
     return queue
Exemplo n.º 5
0
    def keys_with_prefix(self, prefix):
        queue = Queue()

        x = self._get(self.root, prefix, 0)
        if x == None:
            return
        if x.val != None:
            queue.enqueue(prefix)

        self.collect(x, prefix, queue)
        return queue
Exemplo n.º 6
0
class KruskalMST:
    def __init__(self, g):
        self.weight = 0
        self.mst = Queue()
        self.pq = MinPQ()
        for e in g.edges():
            self.pq.insert(e)

        uf = UF(g.V)
        while not self.pq.is_empty() and self.mst.size() < g.V - 1:
            e = self.pq.del_min()
            v = e.either()
            w = e.other(v)
            if uf.connected(v, w):
                continue
            uf.union(v, w)
            self.mst.enqueue(e)
            self.weight += e.weight

    def edges(self):
        return self.mst
Exemplo n.º 7
0
    def level_order(self):
        """Return the keys in the BST in level order"""
        keys = Queue()
        queue = Queue()
        queue.enqueue(self.root)
        while not queue.is_empty():
            x = queue.dequeue()
            if x is None:
                continue

            keys.enqueue(x.key)
            queue.enqueue(x.left)
            queue.enqueue(x.right)
        return keys
Exemplo n.º 8
0
class DepthFirstOrder:

    def __init__(self, G):
        self.marked = [False for _ in range(G.V)]
        self.pre = Queue()
        self.post = Queue()
        for w in range(G.V):
            if not self.marked[w]:
                self.dfs(G, w)

    def dfs(self, G, v):
        self.pre.enqueue(v)
        self.marked[v] = True

        for w in G.adj[v]:
            if not self.marked[w]:
                self.dfs(G, w)
        self.post.enqueue(v)

    def reverse_post(self):
        reverse = Stack()
        for v in self.post:
            reverse.push(v)
        return reverse