Exemplo n.º 1
0
 def __init__(self, digraph):
     # This is used to keep track of whether a vertex has been encountered or not.
     # This way dfs() will only run at most once for each vertex
     self.marked_array = [False]*digraph.V()
     
     # This array is used to build the cycle_stack
     # For a given index
     self.paths_array = [None]*digraph.V()
     
     # This stack stays empty until a cycle is detected.
     # If a cycle is detected, all of the vertices along the cycle are added to the stack
     # This is done by utilizing the paths_array which stores the previous vertex along its path
     self.cycle_stack = Stack_ResizingArray()
     
     # This array keeps track of whether a vertex is still on the call stack.
     # If we encounter a vertex that is still on the call stack, then we know a cycle exists (similar to how if the end of the string re-encounters the string in the Tremaux maze)
     # The value at a given index is turned to True while it is on the call stack and turned to False when dfs finishes (and it is no longer on the call stack)
     self.onStack = [False]*digraph.V()
     
     for i in range(digraph.V()):
         # This way dfs goes through all vertices even if in different components.
         if not self.marked_array[i]:
             self.onStack[i]=True
             self.dfs(i, digraph)
             self.onStack[i]=False
class Directed_DFS_Orderings:
    def __init__(self, digraph):
        self.marked_array = [False] * digraph.V()

        self.pre_order = Queue_LinkedList()
        self.post_order = Queue_LinkedList()
        self.reverse_post_order = Stack_ResizingArray()

        for i in range(digraph.V()):
            if not self.marked_array[i]:
                self.dfs(i, digraph)

    def dfs(self, v, digraph):
        self.pre_order.enqueue(v)
        self.marked_array[v] = True
        for j in digraph.adjacent(v):
            if not self.marked_array[j]:
                self.dfs(j, digraph)
        self.post_order.enqueue(v)
        self.reverse_post_order.push(v)

    def preorder(self):
        return self.pre_order

    def postorder(self):
        return self.post_order

    def reversepostorder(self):
        return self.reverse_post_order
Exemplo n.º 3
0
class Directed_DFS_Orderings_EWD:
    def __init__(self, ew_digraph):
        self.ew_digraph = ew_digraph
        self.marked_array = [False] * self.ew_digraph.V()

        self.pre_order = Queue_LinkedList()
        self.post_order = Queue_LinkedList()
        self.reverse_post_order = Stack_ResizingArray()

        for i in range(self.ew_digraph.V()):
            if self.marked_array[i] != True:
                self.dfs(i)

    def dfs(self, v):
        self.pre_order.enqueue(v)
        self.marked_array[v] = True

        # For Edge_Weighted_Digraph, self.ew_digraph.adjacent(v) returns the edges coming from vertex v (in Digraph, self.digraph.adjacent(v) returns the vertices v is pointing towards).
        for directed_edge in self.ew_digraph.adjacent(v):
            w = directed_edge.towards_vert()
            if self.marked_array[w] != True:
                self.dfs(w)
        self.post_order.enqueue(v)
        self.reverse_post_order.push(v)

    def preorder(self):
        return self.pre_order

    def postorder(self):
        return self.post_order

    def reversepostorder(self):
        return self.reverse_post_order
Exemplo n.º 4
0
    def pathTo(self, v):
        if not self.hasPathTo(v): return None
        stack = Stack_ResizingArray()

        while v is not None:
            stack.push(v)
            v = self.paths_array[v]
        return stack
Exemplo n.º 5
0
    def pathTo(self, v):
        if not self.hasPathTo(v): return None
        stack = Stack_ResizingArray()
        x = v
        while x is not None:
            stack.push(x)
            x = self.path_array[x]

        return stack
    def __init__(self, digraph):
        self.marked_array = [False] * digraph.V()

        self.pre_order = Queue_LinkedList()
        self.post_order = Queue_LinkedList()
        self.reverse_post_order = Stack_ResizingArray()

        for i in range(digraph.V()):
            if not self.marked_array[i]:
                self.dfs(i, digraph)
Exemplo n.º 7
0
    def __init__(self, ew_digraph):
        self.ew_digraph = ew_digraph
        self.marked_array = [False] * self.ew_digraph.V()

        self.pre_order = Queue_LinkedList()
        self.post_order = Queue_LinkedList()
        self.reverse_post_order = Stack_ResizingArray()

        for i in range(self.ew_digraph.V()):
            if self.marked_array[i] != True:
                self.dfs(i)
Exemplo n.º 8
0
    def dfs(self, graph, s):
        stack = Stack_ResizingArray()
        stack.push(s)
        while stack:
            v = stack.pop()

            self.count_connected += 1
            print(v, self.count_connected)
            for neighbor in graph.adj[v]:
                if not self.marked_array[neighbor]:
                    self.marked_array[v] = True
                    stack.push(neighbor)
    def dfs(self, graph, v):
        self.marked_array[v] = True
        stack = Stack_ResizingArray()
        stack.push(v)
        while stack:
            vertex = stack.pop()

            neighbors_list = graph.adj[vertex]
            for i in neighbors_list:
                if self.marked_array[i] != True:
                    stack.push(i)
                    self.marked_array[vertex] = True
                    self.path_array[i] = vertex
Exemplo n.º 10
0
 def pathTo(self,v):
     path_stack = Stack_ResizingArray()
     directed_edge = self.edgeTo[v]
     if v == self.s:
         return "No edges required to reach source vertex from source vertex"
     vert_from = directed_edge.from_vert()
     while vert_from != self.s:
         path_stack.push(directed_edge)
         directed_edge = self.edgeTo[vert_from]
         vert_from = directed_edge.from_vert()
     path_stack.push(directed_edge)
     return path_stack
class Directed_Weighted_Cycle:
    def __init__(self, ew_digraph):
        # This is used to keep track of whether a vertex has been encountered or not.
        # This way dfs() will only run at most once for each vertex
        self.marked_array = [False] * ew_digraph.V()

        # This array is used to build the cycle_stack
        # For a given index
        self.edgeTo = [None] * ew_digraph.V()

        # This stack stays empty until a cycle is detected.
        # If a cycle is detected, all of the vertices along the cycle are added to the stack
        # This is done by utilizing the paths_array which stores the previous vertex along its path
        self.cycle_stack = Stack_ResizingArray()

        # This array keeps track of whether a vertex is still on the call stack.
        # If we encounter a vertex that is still on the call stack, then we know a cycle exists (similar to how if the end of the string re-encounters the string in the Tremaux maze)
        # The value at a given index is turned to True while it is on the call stack and turned to False when dfs finishes (and it is no longer on the call stack)
        self.onStack = [False] * ew_digraph.V()

        for i in range(ew_digraph.V()):
            # This way dfs goes through all vertices even if in different components.
            if self.marked_array[i] != True:
                self.dfs(i, ew_digraph)

    def dfs(self, v, ew_digraph):
        self.onStack[v] = True
        self.marked_array[v] = True

        # For Edge_Weighted_Digraph, self.ewdigraph.adjacent(v) returns the edges coming from vertex v (in Digraph, self.digraph.adjacent(v) returns the vertices v is pointing towards.
        for directed_edge in ew_digraph.adjacent(v):
            w = directed_edge.towards_vert()

            # 1.
            # If a cycle has already been detected (and consequently cycle_stack has been built),
            # Then no more calls to dfs() will be added to the call stack and those remaining are quickly finished w/ this return statement.
            if self.hasCycle() == True:
                return

                # 2.
                # If a vertex has already been encountered, then we don't need to re-search through its neighbors.
                # We only search through the neighbors of a vertex once.
            elif self.marked_array[w] == False:
                self.edgeTo[w] = directed_edge
                self.dfs(w, ew_digraph)

            # 3.
            # If this is a true, a cycle has been detected and we can build the cycle stack to show the cycle.
            elif self.onStack[w] == True:
                self.cycle_stack.push(directed_edge)
                x = self.edgeTo[v]
                while x.from_vert() != directed_edge.towards_vert():
                    self.cycle_stack.push(x)
                    x = self.edgeTo[x.from_vert()]
                self.cycle_stack.push(x)

        self.onStack[v] = False

    def hasCycle(self):
        return not self.cycle_stack.isEmpty()

    def cycle(self):
        if self.hasCycle() == False:
            return None
        else:
            return self.cycle_stack