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)
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
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)
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)
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
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)
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)
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
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