def __init__(self, G):
        self._G = G
        self._pre = Queue()
        self._post = Queue()
        self._reverse_post = Stack()

        self._marked = [False] * G.V()
        for v in range(G.V()):
            if not self._marked[v]:
                self.dfs(v)
    def keys_between(self, lo, hi):
        """Returns all keys in this symbol table in the given range, as an
        Iterable.

        :param lo: minimum endpoint
        :param hi: maximum endpoint
        :returns: all keys in this symbol table between lo
            (inclusive) and hi (inclusive)
        :raises ValueError: if either lo or hi are None

        """
        if lo is None:
            raise ValueError("first argument to keys() is None")
        if hi is None:
            raise ValueError("second argument to keys() is None")

        queue = Queue()
        if lo > hi:
            return queue

        i = self.rank(lo)
        end = self.rank(hi)
        while i < end:
            queue.enqueue(self._keys[i])
            i += 1

        if self.contains(hi):
            queue.enqueue(self._keys[self.rank(hi)])
        return queue
示例#3
0
def diameter(G):
    marked = [False] * G.V()
    edge_to = [None] * G.V()
    q = Queue()

    marked[0] = True
    q.enqueue(0)

    while not q.is_empty():
        v = q.dequeue()
        for adj in G.adj(v):
            if marked[adj] == False:
                marked[adj] = True
                edge_to[adj] = v
                q.enqueue(adj)

    # compute dist of all paths
    paths = []
    for i in range(G.V()):
        dist = 0
        curr = i
        while edge_to[curr] != None:
            dist += 1
            curr = edge_to[curr]

        paths.append(dist)

    return max(paths)
示例#4
0
    def __init__(self, G):
        self._weight = 0.0  # total weight of MST
        self._mst = Queue()  # edges in the MST
        self._marked = [False] * G.V()  # marked[v] = True if v on tree
        self._pq = MinPQ()  # edges with one endpoint in tree

        for v in range(G.V()):  # run Prim from all vertices to
            if not self._marked[v]:
                self._prim(G, v)  # get a minimum spanning forest
示例#5
0
文件: tst.py 项目: joemocha/itu.algs4
 def keys_with_prefix(self, prefix):
     if prefix is None:
         raise ValueError("calls keys_with_prefix with null argument") # TODO IllegalArgumentException
     queue = Queue()
     x = self._get(self.root, prefix, 0)
     if x is None:
         return queue
     if x.val is not None:
         queue.enqueue(prefix)
     self._collect(x.mid, prefix, queue)
     return queue
 def _bfs(self, G, s):
     # breadth-first search from a single source
     queue = Queue()
     self._marked[s] = True  # Mark the source
     queue.enqueue(s)  # and put it on the queue.
     while not queue.is_empty():
         v = queue.dequeue()  # Remove next vertex from the queue.
         for w in G.adj(v):
             if not self._marked[w]:
                 self._edgeTo[w] = v  # For every unmarked adjacent vertex,
                 self._marked[w] = True  # mark it because path is known,
                 queue.enqueue(w)  # and add it to the queue.
示例#7
0
    def edges(self):
        """
        Returns the edges in a minimum spanning tree (or forest).
        :returns: the edges in a minimum spanning tree (or forest) as
                an iterable of edges
        """
        mst = Queue()
        for v in range(len(self._edge_to)):
            e = self._edge_to[v]
            if e is not None:
                mst.enqueue(e)

        return mst
    def __init__(self, digraph):
        """Determines a depth-first order for the digraph.

        :param digraph: the digraph to check

        """
        self._pre = [0] * digraph.V()
        self._post = [0] * digraph.V()
        self._preorder = Queue()
        self._postorder = Queue()
        self._marked = [False] * digraph.V()

        self._pre_counter = 0
        self._post_counter = 0

        if isinstance(digraph, Digraph):
            dfs = self._dfs
        else:
            dfs = self._dfs_edge_weighted

        for v in range(digraph.V()):
            if not self._marked[v]:
                dfs(digraph, v)
示例#9
0
    def bfs(self, G, s):
        # mark source node and insert into queue to initialise bfs
        self._marked[s] = True
        q = Queue()
        q.enqueue(s)

        # continue bfs until queue is empty (all reachable nodes have been visited)
        while q.is_empty() == False:
            s = q.dequeue()
            for adj in G.adj(s):
                if self._marked[adj] == False:
                    self._marked[adj] = True
                    q.enqueue(adj)
                    self._count += 1
    def __init__(self, G):
        # initialise
        self._mst = Queue()
        self._edges = MinPQ()
        for edge in G.edges():
            self._edges.insert(edge)
        self._uf = WeightedQuickUnionUF(G.V())

        while not self._edges.is_empty() and self._mst.size() < G.V() - 1:
            min_edge = self._edges.del_min()
            u = min_edge.either()
            v = min_edge.other(u)
            if self._uf.connected(u, v):
                continue  # ineligible edge
            self._uf.union(u, v)  # union (are part of mst now)
            self._mst.enqueue(min_edge)
示例#11
0
    def __init__(self, G):
        """
        Compute a minimum spanning tree (or forest) of an edge-weighted graph.
        :param G: the edge-weighted graph
        """
        self._weight = 0.0  # total weight of MST
        self._mst = Queue()  # edges in the MST
        self._marked = [False] * G.V()  # marked[v] = True if v on tree
        self._pq = MinPQ()  # edges with one endpoint in tree

        for v in range(G.V()):  # run Prim from all vertices to
            if not self._marked[v]:
                self._prim(G, v)  # get a minimum spanning forest

        # check optimality conditions
        assert self._check(G)
示例#12
0
    def can_be_colored(self, src):
        coloring = [-1] * self._V

        for src in range(self._V):
            if coloring[src] == -1:
                coloring[src] = 1

                # Create a queue (FIFO) of vertex numbers and
                # enqueue source vertex for BFS traversal
                q = Queue()
                q.enqueue(src)

                # Run while there are vertices in queue
                # (Similar to BFS)
                while q.is_empty() == False:
                    u = q.dequeue()
                    for edge in self.adj(u):
                        start = u
                        for possibility in [edge.start(), edge.end()]:
                            if possibility != u:
                                end = possibility

                        # adjacent not visited yet
                        if coloring[end] == -1:
                            if edge.type() == 0:  # harmony
                                coloring[end] = coloring[start]

                            elif edge.type() == 1:  # conflict
                                if coloring[start] == 0:
                                    coloring[end] = 1
                                elif coloring[start] == 1:
                                    coloring[end] = 0
                            q.enqueue(end)
                            continue
                        if edge.type() == 0:  # harmony
                            # print(coloring[edge.start()], coloring[edge.end()])
                            if coloring[start] != coloring[end]:
                                return 0
                        elif edge.type() == 1:  # conflict
                            # print(coloring[edge.start()], coloring[edge.end()])
                            if coloring[start] == coloring[end]:
                                return 0
        return 1
示例#13
0
    def __init__(self, G, s):
        self._distTo = [sys.float_info.max
                        ] * G.V()  #distTo[v] = distance  of shortest s->v path
        self._edgeTo = [None
                        ] * G.V()  #edgeTo[v] = last edge on shortest s->v path
        self._onQueue = [False
                         ] * G.V()  #onQueue[v] = is v currently on the queue?
        self._queue = Queue()  #queue of vertices to relax
        self._cost = 0  #number of calls to relax()
        self._cycle = None  #negative cycle (or None if no such cycle)

        #Bellman-Ford algorithm
        self._distTo[s] = 0.0
        self._queue.enqueue(s)
        self._onQueue[s] = True
        while not self._queue.is_empty() and not self.has_negative_cycle():
            v = self._queue.dequeue()
            self._onQueue[v] = False
            self._relax(G, v)
        assert self._check(G, s)
示例#14
0
def main(args):
    stream = InStream(args[0])
    G = Digraph.from_stream(stream)
    scc = KosarajuSharirSCC(G)

    # number of connected components
    m = scc.count()
    print("{} strong components".format(m))

    # compute list of vertices in each strong component
    components = [Queue() for i in range(m)]

    for v in range(G.V()):
        components[scc.id(v)].enqueue(v)

    # print results
    for i in range(m):
        for v in components[i]:
            print(str(v), end=" ")
        print()
def solve(world, R, L):
    # find starting indices
    start_from = []
    for j in range(R):
        if world[j][0] == 'P':
            start_from.append((j, 1))

    # dijkstra shortest path finding from starting positions to the right
    min_distances = []
    for index in start_from:
        i, j = index
        # built dist_to array
        dist_to = []
        for _ in range(R):
            line = []
            for _ in range(L):
                line.append(math.inf)
            dist_to.append(line)

        # intialise starting position
        dist_to[i][j] = int(world[i][j])
        q = Queue()
        q.enqueue((i, j))

        while not q.is_empty():
            v = q.dequeue()  # dequeue current index
            for adj in adjacents(R, L, v[0], v[1]):
                i, j = adj[0], adj[1]
                if world[i][j] in ['P', 'U', 'M', 'A', '.']:
                    # print(f'found: {world[i][j]}')
                    continue
                else:
                    # if distance can be decreased, decrease
                    if dist_to[i][j] > int(world[i][j]) + dist_to[v[0]][v[1]]:
                        dist_to[i][j] = int(world[i][j]) + dist_to[v[0]][v[1]]
                        q.enqueue(adj)
        min_distances.append(min([dist_to[i][L-2] for i in range(R)]))

    return min(min_distances)
示例#16
0
    def _bfs(self, G: Graph, s: int):
        """
        bfs to search for shortest path from source s to all vertex

        :param G:
        :param s:
        :return:
        """
        queue = Queue()
        self._dist_to[s] = 0
        self._edgeTo[s] = 0
        self._marked[s] = True
        queue.enqueue(s)

        while not queue.is_empty():
            v = queue.dequeue()
            for w in G.adj(v):
                if not self._marked[w]:
                    self._marked[w] = True
                    self._edgeTo[w] = v
                    self._dist_to[w] = self._dist_to[v] + 1
                    queue.enqueue(w)
示例#17
0
    def build_fail(self):
        """

        build the fail pointer for each node.
        fail pointer is the longest suffix which can match the other's prefix,最长可匹配后缀
        and the pointer points to the prefix's last node.
        the building idea is like reversion.

        1.pc(p's child)'s fail is qc:  pc=qc when pc.data==qc.data. q =p.fail
        2.root's fail is none
        BFS the AcTrie and build fail for each node get from queue.

        :return:
        """
        queue = Queue()
        self._root.fail = None
        queue.enqueue(self._root)

        while not queue.is_empty():
            p = queue.dequeue()
            # BFS traverse the trie,each time set the p'c child pc's fail when p's fail is known.
            for pc in p.children:
                if pc is None:
                    continue
                if pc == self._root:
                    pc.fail = self._root
                else:
                    q = p.fail
                    while q:
                        # qc is the q'child which has same char with pc.
                        qc = q.children[ord(pc.data)]
                        if qc:
                            pc.fail = qc
                            break
                        # if qc not exist, q=q.fail, repeat.
                        q = q.fail
                    if q is None:
                        pc.fail = self._root
                queue.enqueue(pc)
示例#18
0
def solve(R, C, world):
    flat_world = [item for sublist in world for item in sublist]
    G = Graph(len(flat_world))

    # add horizontal edges
    for i in range(R):
        for j in range(C - 1):
            G.add_edge(j + (i * C), j + (i * C) + 1)
    # add vertical edges
    for i in range(R - 1):
        for j in range(C):
            G.add_edge(j + (i * C), j + (i * C) + C)

    # create mapping
    mapping = {i: flat_world[i] for i in range(len(flat_world))}
    # print(G)
    # print(mapping)

    # find virus and make it source
    s = 0
    for x in flat_world:
        if x == 2:
            break
        s += 1

    # start bfs from infection
    q = Queue()
    q.enqueue(s)

    while q.is_empty() == False:
        v = q.dequeue()
        for adj in G.adj(v):
            if mapping[adj] == 1:  # land
                mapping[adj] = 2  # infect the land
                q.enqueue(adj)
            elif mapping[adj] == 3:  # encounter human
                return 1
    return 0
示例#19
0
def shortest_path(G, u, v):
    marked = [False] * G.V()
    edge_to = [None] * G.V()

    q = Queue()
    marked[u] = True
    q.enqueue(u)

    while not q.is_empty():
        s = q.dequeue()
        for adj in G.adj(s):
            if not marked[adj]:
                marked[s] = True
                edge_to[adj] = s
                q.enqueue(adj)

    dist = 0
    curr = v
    while edge_to[curr] != None:
        dist += 1
        curr = edge_to[curr]

    return dist
示例#20
0
    def __init__(self, G):
        """Computes a minimum spanning tree (or forest) of an edge-weighted
        graph.

        :param G: the edge-weighted graph

        """
        self._weight = 0
        self._mst = Queue()
        pq = MinPQ()

        for e in G.edges():
            pq.insert(e)

        uf = WeightedQuickUnionUF(G.V())
        while not pq.is_empty() and self._mst.size() < G.V() - 1:
            e = pq.del_min()
            v = e.either()
            w = e.other(v)
            if not uf.connected(v, w):
                uf.union(v, w)
                self._mst.enqueue(e)
                self._weight += e.weight()
示例#21
0
def solve(R, C, world):
    # find virus and make it source
    s = None
    for i in range(R):
        for j in range(C):
            if world[i][j] == 2:
                s = (i, j)

    # start bfs from infection
    q = Queue()
    q.enqueue(s)

    while q.is_empty() == False:
        v = q.dequeue()
        # for row in world:
        #    print(row)
        # print('\n')
        for adj in adjacents(world, v[0], v[1]):
            if world[adj[0]][adj[1]] == 1:
                world[adj[0]][adj[1]] = 2
                q.enqueue(adj)
            elif world[adj[0]][adj[1]] == 3:
                return 1
    return 0
示例#22
0
#!/usr/bin/env python3
from itu.algs4.fundamentals.queue import Queue
from itu.algs4.stdlib import stdio

"""
Reads strings from an stdin and adds them to a queue.
When reading a '-' it removes the least recently added item and prints it.
Prints the amount of items left on the queue.
"""
queue: Queue[str] = Queue()
while not stdio.isEmpty():
    input_item = stdio.readString()
    if input_item != "-":
        queue.enqueue(input_item)
    elif not queue.is_empty():
        print(queue.dequeue())
print("({} left on queue)".format(queue.size()))
def connected_inhabitans_multiworld(L):
    # intialise graph object with V vertices
    R = len(L[0])
    C = len(L)

    flat_L = [item for sublist in L for item in sublist]
    V = len(flat_L)
    G = AdjacencyListGraph(V)

    # add horizontal edges
    for i in range(R - 1):
        for j in range(C):
            G.add_edge(i + (R * j), i + (R * j) + 1)
    # add right diagonal edges
    for i in range(R):
        for j in range(C - 1):
            if j % 2 == 0:
                G.add_edge(i + (R * j), i + (R * j) + R)
            else:
                if i >= R - 1:
                    break
                G.add_edge(i + (R * j), i + (R * j) + R + 1)

    # add left diagonal edges
    for i in range(R):
        for j in range(C - 1):
            if j % 2 == 0:
                if i == 0:
                    continue
                G.add_edge(i + (R * j), i + (R * j) + R - 1)
            else:
                G.add_edge(i + (R * j), i + (R * j) + R)

    print(G)
    # create mapping
    mapping = {i: flat_L[i] for i in range(len(flat_L))}
    print(mapping)

    # find source
    s = 0
    for x in flat_L:
        if x == 0:
            break
        s += 1

    d = 0
    while True:
        print(d, mapping)
        # total number of grass fields
        total_count = len([x for x in mapping.values() if x == 0])

        marked = [False] * G.V()
        q = Queue()
        count = 1
        marked[s] = True
        q.enqueue(s)

        while q.is_empty() == False:
            v = q.dequeue()
            for adj in G.adj(v):
                if marked[adj] == False and mapping[adj] == 0:
                    marked[adj] = True
                    q.enqueue(adj)
                    count += 1

        print(total_count, count)

        if count == total_count:
            return d

        # base case (no more lowering of water possible)
        if len([x for x in mapping.values() if x > 0]) == 0:
            return 'impossible'

        d += 1
        for i in range(len(mapping)):
            if mapping[i] > 0:
                mapping[i] -= 1
示例#24
0
 def keys(self):
     queue = Queue()
     self._collect(self.root, "", queue)
     return queue
示例#25
0
 def keys_that_match(self, pattern):
     queue = Queue()
     self._collect_match(self.root, "", 0, pattern, queue)
     return queue
示例#26
0
    def count(self):
        return self._count


if __name__ == "__main__":
    import sys

    from itu.algs4.fundamentals.queue import Queue
    from itu.algs4.graphs.graph import Graph
    from itu.algs4.stdlib import stdio
    from itu.algs4.stdlib.instream import InStream

    In = InStream(sys.argv[1])
    G = Graph.from_stream(In)
    cc = CC(G)

    # number of connected components
    m = cc.count()
    stdio.writef("%i components\n", m)

    # compute list of vertices in each connected component
    components = [Queue() for _ in range(m)]
    for v in range(G.V()):
        components[cc.id(v)].enqueue(v)

    # print results
    for i in range(m):
        for v in components[i]:
            stdio.writef("%i ", v)
        stdio.writeln()
示例#27
0
 def keys_with_prefix(self, prefix):
     results = Queue()
     x = self._get(self._root, prefix, 0)
     self._collect(x, prefix, results)
     return results
示例#28
0
 def keys_that_match(self, pattern):
     results = Queue()
     self._collect_match(self._root, "", pattern, results)
     return results
示例#29
0
# Created for BADS 2018
# See README.md for details
# Python 3
import sys

from itu.algs4.fundamentals.queue import Queue
from itu.algs4.stdlib import stdio

# is this really useful??
try:
    q = Queue()
    q.enqueue(1)
except AttributeError:
    print("ERROR - Could not import itu.algs4 queue")
    sys.exit(1)

# Execution:    python lookup_index.py movies.txt "/"
# Dependencies: queue.py stdio.py
# % python lookup_index.py aminoI.csv ","
# Serine
#   TCT
#   TCA
#   TCG
#   AGT
#   AGC
# TCG
#   Serine
#
# % python lookup_index.py movies.txt "/"
# Bacon, Kevin
#   Animal House (1978)
示例#30
0
import sys

from itu.algs4.errors.errors import (
    IllegalArgumentException,
    UnsupportedOperationException,
)
from itu.algs4.fundamentals.queue import Queue
from itu.algs4.fundamentals.stack import Stack
from itu.algs4.graphs.directed_edge import DirectedEdge
from itu.algs4.graphs.edge_weighted_digraph import EdgeWeightedDigraph
from itu.algs4.graphs.edge_weighted_directed_cycle import EdgeWeightedDirectedCycle
from itu.algs4.stdlib import stdio
from itu.algs4.stdlib.instream import InStream

try:
    q = Queue()
    q.enqueue(1)
except AttributeError:
    print('ERROR - Could not import itu.algs4 queue')
    sys.exit(1)

#  Execution:    python BellmanFordSP.py filename.txt s
#  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWDn.txt
#                https://algs4.cs.princeton.edu/44sp/mediumEWDnc.txt
#
#  Bellman-Ford shortest path algorithm. Computes the shortest path tree in
#  edge-weighted digraph G from vertex s, or finds a negative cost cycle
#  reachable from s.
"""
 The BellmanFordSP class represents a data type for solving the
 single-source shortest paths problem in edge-weighted digraphs with