Exemplo n.º 1
0
    def __init__(self, regex):
        """Initializes the NFA from the specified regular expression.

        :param regex: the regular expression

        """
        self.regex = regex
        m = len(regex)
        self.m = m
        ops = Stack()
        graph = Digraph(m + 1)
        for i in range(0, m):
            lp = i
            if regex[i] == "(" or regex[i] == "|":
                ops.push(i)
            elif regex[i] == ")":
                or_ = ops.pop()

                # 2-way or operator
                if regex[or_] == "|":
                    lp = ops.pop()
                    graph.add_edge(lp, or_ + 1)
                    graph.add_edge(or_, i)
                elif regex[or_] == "(":
                    lp = or_
                else:
                    assert False
            if i < m - 1 and regex[i + 1] == "*":
                graph.add_edge(lp, i + 1)
                graph.add_edge(i + 1, lp)
            if regex[i] == "(" or regex[i] == "*" or regex[i] == ")":
                graph.add_edge(i, i + 1)
        if ops.size() != 0:
            raise ValueError("Invalid regular expression")
        self.graph = graph
Exemplo n.º 2
0
    def __init__(self, filename, delimiter):
        """
        Initializes a digraph from a file using the specified delimiter.
        Each line in the file contains
        the name of a vertex, followed by a list of the names
        of the vertices adjacent to that vertex, separated by the delimiter.

        :param filename: the name of the file
        :param delimiter: the delimiter between fields
        """
        self._st = BinarySearchST()  # string -> index

        # First pass builds the index by reading strings to associate
        # distinct strings with an index
        stream = InStream(filename)
        while not stream.isEmpty():
            a = stream.readLine().split(delimiter)
            for i in range(len(a)):
                if not self._st.contains(a[i]):
                    self._st.put(a[i], self._st.size())

        stdio.writef("Done reading %s\n", filename)

        # inverted index to get keys in an array
        self._keys = [None] * self._st.size()  # index  -> string
        for name in self._st.keys():
            self._keys[self._st.get(name)] = name

        # second pass builds the graph by connecting first vertex on each
        # line to all others
        self._graph = Digraph(self._st.size())  # the underlying graph
        stream = InStream(filename)
        while stream.hasNextLine():
            a = stream.readLine().split(delimiter)
            v = self._st.get(a[0])
            for i in range(1, len(a)):
                w = self._st.get(a[i])
                self._graph.add_edge(v, w)
Exemplo n.º 3
0
def main():
    """Unit tests the DirectedDFS data type."""
    G = Digraph.from_stream(InStream(None))
    sources = Bag()
    for i in range(1, len(sys.argv)):
        s = int(sys.argv[i])
        sources.add(s)

    dfs = DirectedDFS(G, *sources)
    print("Reachable vertices:")
    for v in range(0, G.V()):
        if dfs.is_marked(v):
            print(v, end=" ")
    print()
Exemplo n.º 4
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()
Exemplo n.º 5
0
def main(args):
    stream = InStream(args[0])
    G = Digraph.from_stream(stream)

    tc = TransitiveClosure(G)

    # print header
    print("     ", end="")
    for v in range(G.V()):
        print("{x:3d}".format(x=v), end="")
    print()
    print("--------------------------------------------")

    # print transitive closure
    for v in range(G.V()):
        print("{x:3d}: ".format(x=v), end="")
        for w in range(G.V()):
            if tc.reachable(v, w):
                print("  T", end="")
            else:
                print("   ", end="")
        print()
Exemplo n.º 6
0
class SymbolDigraph:
    """
    The SymbolDigraph class representsclass represents a digraph, where the
    vertex names are arbitrary strings.
    By providing mappings between vertex names and integers,
    it serves as a wrapper around the Digraph data type, which assumes the 
    vertex names are integers between 0 and V - 1.
    It also supports initializing a symbol digraph from a file.
    
    This implementation uses an ST to map from strings to integers,
    an array to map from integers to strings, and a Digraph to store
    the underlying graph.
    The index_of and contains operations take time 
    proportional to log V, where V is the number of vertices.
    The name_of operation takes constant time.
    """
    def __init__(self, filename, delimiter):
        """
        Initializes a digraph from a file using the specified delimiter.
        Each line in the file contains
        the name of a vertex, followed by a list of the names
        of the vertices adjacent to that vertex, separated by the delimiter.

        :param filename: the name of the file
        :param delimiter: the delimiter between fields
        """
        self._st = BinarySearchST()  # string -> index

        # First pass builds the index by reading strings to associate
        # distinct strings with an index
        stream = InStream(filename)
        while not stream.isEmpty():
            a = stream.readLine().split(delimiter)
            for i in range(len(a)):
                if not self._st.contains(a[i]):
                    self._st.put(a[i], self._st.size())

        stdio.writef("Done reading %s\n", filename)

        # inverted index to get keys in an array
        self._keys = [None] * self._st.size()  # index  -> string
        for name in self._st.keys():
            self._keys[self._st.get(name)] = name

        # second pass builds the graph by connecting first vertex on each
        # line to all others
        self._graph = Digraph(self._st.size())  # the underlying graph
        stream = InStream(filename)
        while stream.hasNextLine():
            a = stream.readLine().split(delimiter)
            v = self._st.get(a[0])
            for i in range(1, len(a)):
                w = self._st.get(a[i])
                self._graph.add_edge(v, w)

    def contains(self, s):
        """
        Does the graph contain the vertex named s?

        :param s: the name of a vertex
        :return:s true if s is the name of a vertex, and false otherwise        
        """
        return self._st.contains(s)

    def index_of(self, s):
        """
        Returns the integer associated with the vertex named s.
        :param s: the name of a vertex
        :returns: the integer (between 0 and V - 1) associated with the vertex named s
        """
        return self._st.get(s)

    def name_of(self, v):
        """
        Returns the name of the vertex associated with the integer v.
        @param  v the integer corresponding to a vertex (between 0 and V - 1) 
        @throws IllegalArgumentException unless 0 <= v < V
        @return the name of the vertex associated with the integer v
        """
        self._validateVertex(v)
        return self._keys[v]

    def digraph(self):
        return self._graph

    def _validateVertex(self, v):
        # throw an IllegalArgumentException unless 0 <= v < V
        V = self._graph.V()
        if v < 0 or v >= V:
            raise ValueError("vertex {} is not between 0 and {}".format(
                v, V - 1))
            i = 0
            for v in self._order:
                self._rank[v] = i
                i += 1

    def has_order(self):
        return self._order is not None

    def order(self):
        return self._order

    def rank(self, v):
        if self.has_order():
            return self._rank[v]
        else:
            return -1


if __name__ == '__main__':
    graph = Digraph(5)
    graph.add_edge(0, 1)
    graph.add_edge(0, 3)
    graph.add_edge(2, 3)
    graph.add_edge(4, 0)
    graph.add_edge(2, 4)

    # cycles = DirectedCycle(graph)
    topo = Topological(graph)
    print(topo.has_order())
    print(topo.order())
Exemplo n.º 8
0
        self._on_stack[v] = False

    def has_cycle(self):
        """Does the digraph have a directed cycle?

        :returns: true if there is a cycle, false otherwise

        """
        return self._cycle is not None

    def cycle(self):
        """Returns a directed cycle if the digraph has a directed cycle, and
        null otherwise.

        :returns: a directed cycle (as an iterable) if the digraph has a directed cycle, and null otherwise

        """
        return self._cycle


if __name__ == "__main__":
    # Create stream from file or the standard input,
    # depending on whether a file name was passed.
    stream = sys.argv[1] if len(sys.argv) > 1 else None

    d = Digraph.from_stream(InStream(stream))

    cyc = DirectedCycle(d)
    print(cyc.cycle())