예제 #1
0
 def bfs(self, v, digraph):
     queue = Queue_LinkedList()
     queue.enqueue(v)
     while queue:
         v = queue.dequeue()
         for points_towards in digraph.adjacent(v):
             if not self.marked_array[points_towards]:
                 self.marked_array[points_towards] = True
                 self.paths_array[points_towards] = v
                 queue.enqueue(points_towards)
예제 #2
0
 def bfs(self, graph, v):
     queue = Queue_LinkedList()
     self.marked_array[v] = True
     queue.enqueue(v)
     while queue:
         vertex = queue.dequeue()
         neighbors_list = graph.adj[vertex]
         for i in neighbors_list:
             if not self.marked_array[i]:
                 queue.enqueue(i)
                 self.marked_array[i] = True
                 self.path_array[i] = vertex
예제 #3
0
    def bfs(self, graph, v):
        queue = Queue_LinkedList()
        queue.enqueue(v)

        while queue:
            v = queue.dequeue()
            # if the vertex has already been marked as true, this means that this vertex was placed on the queue twice which can only occur if there is a cycle
            if self._marked_array[v]:
                self.has_cycle = True
            self._marked_array[v] = True
            neighbors = graph.adjacent(v)
            for neighbor in neighbors:
                if not self._marked_array[neighbor]:
                    queue.enqueue(neighbor)
예제 #4
0
 def bfs(self, graph, v):
     queue = Queue_LinkedList()
     queue.enqueue(v)
     
     while queue:
         v = queue.dequeue()
         if self._marked_array[v]:
             continue
         self._marked_array[v] = True
         
         self._id[v] = self._count
         neighbors = graph.adjacent(v)
     
         for neighbor in neighbors:
             if not self._marked_array[neighbor]:
                 queue.enqueue(neighbor)
예제 #5
0
    def bfs(self, graph, v):
        queue = Queue_LinkedList()
        queue.enqueue(v)

        while queue:
            v = queue.dequeue()
            if self._marked_array[v]:
                continue
            self._marked_array[v] = True
            neighbors = graph.adjacent(v)
            for neighbor in neighbors:
                if (self._marked_array[neighbor]) and (neighbor !=
                                                       self.prev_vertex[v]):
                    self.has_cycle = True
                elif not self._marked_array[neighbor]:
                    queue.enqueue(neighbor)
                    self.prev_vertex[neighbor] = v
예제 #6
0
    def bfs(self, graph, v):
        queue = Queue_LinkedList()
        queue.enqueue(v)

        while queue:
            v = queue.dequeue()

            for neighbor in graph.adjacent(v):
                if (self.marked_array[neighbor]) and (
                        self.biparite_array[neighbor]
                        == self.biparite_array[v]):
                    self._isBiparite = False

                elif not self.marked_array[neighbor]:
                    #self.previous_vertex_array[neighbor] = v
                    self.biparite_array[neighbor] = not self.biparite_array[v]
                    self.marked_array[neighbor] = True
                    queue.enqueue(neighbor)
예제 #7
0
    class _Iterator:
        def __init__(self, root_node):
            self.root_node = root_node
            self.current_node = root_node
            self.queue = Queue_LinkedList()

            # Build the queue (default is from least node to greatest node)
            self.build_queue(self.current_node)

        def __next__(self):
            if self.queue.isEmpty() == True: raise StopIteration
            returned_node = self.queue.dequeue()
            return returned_node

        def build_queue(self, current_node):
            if current_node == None: return
            self.build_queue(current_node.left)
            self.queue.enqueue(current_node)
            #print(current_node.key)
            self.build_queue(current_node.right)
예제 #8
0
class Shortest_Paths:
    def __init__(self, ewdg, s):
        self.dist = [float('inf') for i in range(ewdg.V())]
        self.dist[s] = 0
        
        self.edgeTo = [None]*ewdg.V()
        
        self.queue = Queue_LinkedList()
        self.queue.enqueue(s) 
        
        self.on_queue = [False]*ewdg.V()
        self.on_queue[s] = True
        
        # keeps track of the # of edges from source to vertex in shortest path (should be a max of V-1, otherwise we have a negative cycle)
        self.len_path=[float('inf')]*ewdg.V()
        self.len_path[s]=0
        
        self.cycle = False
        self.s=s
        while self.queue:
            
            u = self.queue.dequeue()
            self.on_queue[u]=False
            
            for edge in ewdg.adjacent(u):
                v=edge.towards_vert()
                weight=edge.weight()
                if self.dist[u]+weight < self.dist[v]:
                    self.dist[v] = self.dist[u]+weight
                    self.len_path[v] = self.len_path[u]+1
                    if self.len_path[v] >= ewdg.V():
                        self.cycle=True
                        print('Negative cycle detected')
                        return
                    self.queue.enqueue(v)
                    self.on_queue[v]=True
                    self.edgeTo[v]=edge
            
            
        
    
    def distTo(self, v):
        return self.dist[v]
        
    def hasPathTo(self,v):
        return self.dist[v] != float('inf')
        
    # Returns stack of directed edges from the source vertex s to a given vertex v.    
    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
    

    def hasNegativeCycle(self):
        return self.cycle
    
        
    def negativeCycle(self):
        return self.cycle
예제 #9
0
class Shortest_Paths:
    def __init__(self, ewdg, s):
        self._distTo = [float('inf') for i in range(ewdg.V())]
        self._distTo[s] = 0

        self.edgeTo = [None] * ewdg.V()

        self.s = s

        self.vertex_queue = Queue_LinkedList()
        self.vertex_queue.enqueue(self.s)

        self.on_queue = [False] * ewdg.V()
        self.on_queue[self.s] = True

        self.cycle = None

        # Keeps track of the number of relax calls that are required in a pass
        # self.num_rcip = self.num_vaip after each pass
        self.num_rcip = 1
        # Keeps track of the number of edges that were eligible to be relaxed in the pass
        self.num_vaip = 0
        # Keeps track of the number of "passes" in the algorithm
        # When self.num_rcip reaches 0, we know we are starting a new "pass"
        self.pass_count = 1

        # some way of determining the order methodology of choosing v
        # In this case, we only look at edges coming from vertices that were relaxed in the previous pass instead of all of the edges as in sp_bellmanford_manual.
        print('Pass: '******'\n\n Negative cycle is reachable from s. Shortest paths cannot be computed.'
                )
                print(
                    '--------------------------------------------------------------------------------- \n\n'
                )
                self.findNegativeCycle()
                return

            v = self.vertex_queue.dequeue()
            self.on_queue[v] = False

            if self.num_rcip == 0:
                self.num_rcip = self.num_vaip
                self.num_vaip = 0
                self.pass_count += 1
                print('\n')
                print('Pass: '******'Queue is empty. Shortest paths for all reachable vertices from s have been found.'
        )
        print(
            '--------------------------------------------------------------------------------- \n\n'
        )

    def relax(self, ewdg, v):
        print("from vertex: ", v, " (removed from queue)")
        for edge in ewdg.adjacent(v):
            print('Edge: ', edge)
            v = edge.from_vert()
            w = edge.towards_vert()

            if self._distTo[v] + edge.weight() < self._distTo[w]:
                # number of vertices added on this relax
                self.num_vaip += 1

                print('This edge is eligible and will be relaxed')
                self.edgeTo[w] = edge

                self._distTo[w] = self._distTo[v] + edge.weight()
                print("towards vertex", w)
                if self.on_queue[w] == True:
                    print('The vertex ', w, ' is already on the queue')

                else:
                    print('The vertex ', w,
                          ' was not already on the queue. Added to queue.')
                    self.vertex_queue.enqueue(w)
                    self.on_queue[w] = True
            else:
                print('This edge is ineligible')

    def distTo(self, v):
        return self._distTo[v]

    def hasPathTo(self, v):
        return self._distTo[v] != float('inf')

    # Returns stack of directed edges from the source vertex s to a given vertex v.
    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

    # This method is not required for the algorithm, I just added this to keep track of the number of "passes"
    def num_passes(self):
        return self.pass_count

    def hasNegativeCycle(self):
        return self.cycle is not None

    def findNegativeCycle(self):
        # Build ew_digraph from edges in edgeTo
        new_graph = Edge_Weighted_Digraph(V=len(self._distTo))
        for edge in self.edgeTo:
            # The entry for self.edgeTo[s] is None
            # Reminder that the 'is' and 'is not' operators test for reference/identity equality
            # In python, there is only one location for None in a python script, no matter how many variables are set to None
            # ie id(edge) == id(None)
            if edge is not None:
                new_graph.addEdge(edge)

        # We know there is a (negative) cycle in this ew_digraph
        cycle_finder = Directed_Weighted_Cycle(new_graph)
        self.cycle = cycle_finder.cycle()

    def negativeCycle(self):
        return self.cycle