def test_find_love(self): ''' Función encargada de probar la función find love. :return: ''' # Primer test start, goal = 0, 4 arcs = [(0, 1), (0, 2), (0, 3), (3, 4)] g = Graph(goal + 1) for arc in arcs: g.add_edge(arc[0], arc[1]) self.assertEqual(g.find_love(start, goal), (2, ['3', '4'])) # Segundo test start, goal = 0, 9 arcs = [(0, 1), (0, 2), (0, 3), (1, 5), (2, 4), (3, 7), (4, 9), (5, 6), (7, 8), (6, 9), (8, 9)] g = Graph(goal + 1) for arc in arcs: g.add_edge(arc[0], arc[1]) self.assertEqual(g.find_love(start, goal), (3, ['2', '4', '9'])) # Tercer test start, goal = 0, 4 arcs = [(0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (2, 4)] g = Graph(goal + 1) for arc in arcs: g.add_edge(arc[0], arc[1]) self.assertEqual(g.find_love(start, goal), (2, ['2', '4']))
# # Reset all values in visited[] as false and do # # DFS beginning from v to check if all vertices are # # reachable from it or not. # visited = [False]*(g.vertices) # perform_DFS(g, last_v, visited) # if any(i is False for i in visited): # return -1 # else: # return last_v # # # # A recursive function to print DFS starting from v # def perform_DFS(g, node, visited): # # # Mark the current node as visited and print it # visited[node] = True # # # Recur for all the vertices adjacent to this vertex # temp = g.array[node].head_node # while(temp): # if visited[temp.data] is False: # perform_DFS(g, temp.data, visited) # temp = temp.next_element g = Graph(4) g.add_edge(0, 1) g.add_edge(1, 2) g.add_edge(3, 0) g.add_edge(3, 1) print(find_mother_vertex(g))
if count != len(all_data_vertex_mapping): print("Graph has cycle.") return False, [] return True, top_order if __name__ == '__main__': # H <-- E --------> F --> G # ^ ^ # | | # A --> C <-- B --> D graph1 = Graph() graph1.add_edge('A', 'C', is_directed=True) graph1.add_edge('B', 'C', is_directed=True) graph1.add_edge('B', 'D', is_directed=True) graph1.add_edge('C', 'E', is_directed=True) graph1.add_edge('D', 'F', is_directed=True) graph1.add_edge('E', 'F', is_directed=True) graph1.add_edge('E', 'H', is_directed=True) graph1.add_edge('F', 'G', is_directed=True) # A: A-->C # B: B-->C, B-->D # C: C-->E # D: D-->F # E: E-->H, E-->F # F: F-->G print('Graph:')
def num_edges(g): # For undirected graph, just sum up the size of # all the adjacency lists for each vertex sum_ = 0 for i in range(g.vertices): temp = g.array[i].head_node while temp is not None: sum_ += 1 temp = temp.next_element # Half the total sum as it is an undirected graph return sum_ // 2 g = Graph(9) g.add_edge(0, 2) g.add_edge(0, 5) g.add_edge(2, 3) g.add_edge(2, 4) g.add_edge(5, 3) g.add_edge(5, 6) g.add_edge(3, 6) g.add_edge(6, 7) g.add_edge(6, 8) g.add_edge(6, 4) g.add_edge(7, 8) g.add_edge(2, 0) g.add_edge(5, 0) g.add_edge(3, 2) g.add_edge(4, 2)
return not is_acyclic if __name__ == '__main__': # # ⟶ B ⟶ D ⟵ F # | | | | # A ⭣ ⭣ ⭣ # ⭡___ C ⟶ E G # # A - C - B - A # C - B - A - C graph1 = Graph() graph1.add_edge('A', 'B', is_directed=True) graph1.add_edge( 'B', 'C', is_directed=True) # Replace edge B -> C to B -> G it to remove cycle. # graph1.add_edge('B', 'G', is_directed=True) graph1.add_edge('B', 'D', is_directed=True) graph1.add_edge('C', 'A', is_directed=True) graph1.add_edge('C', 'E', is_directed=True) graph1.add_edge('D', 'E', is_directed=True) graph1.add_edge('F', 'D', is_directed=True) graph1.add_edge('F', 'G', is_directed=True) # A: A-->B # B: B-->D, B-->C # C: C-->E, C-->A # D: D-->E
# would be disconnected then, we might miss a few vertex while traversing the graph. for data, ver in all_data_vertex_mapping.items(): if not visited.get(data, False): __DFS__(ver) return dfs if __name__ == '__main__': # a -- b x # | | \ / \ # | | e y z # | | / # c -- d graph1 = Graph() graph1.add_edge('a', 'b', is_directed=False) graph1.add_edge('b', 'e', is_directed=False) graph1.add_edge('b', 'd', is_directed=False) graph1.add_edge('e', 'd', is_directed=False) graph1.add_edge('d', 'c', is_directed=False) graph1.add_edge('c', 'a', is_directed=False) graph1.add_edge('x', 'y', is_directed=False) graph1.add_edge('x', 'z', is_directed=False) print(graph1) bfs_arr = BFS(graph1) # [b, a, e, d, c, x, z, y] print("\nBFS:", bfs_arr) dfs_arr = DFS_recursive(graph1) # [b, d, c, a, e, x, z, y]
if new_dist < neighbor.dist: neighbor.dist = new_dist neighbor.predecessor = current_vert # print(neighbor.predecessor) # The problem is herede # queue.percolate_up(neighbor.key, queue.node_position[neighbor.key]) queue.percolate_up(queue.node_position[neighbor.key], neighbor.key) g = Graph() a = ['A', 'B', 'C', 'D', 'E'] for key in a: g.add_vertex(key) g.add_edge('A', 'B', 3) g.add_edge('B', 'A', 3) g.add_edge('A', 'C', 2) g.add_edge('C', 'A', 2) g.add_edge('A', 'E', 4) g.add_edge('E', 'A', 4) g.add_edge('B', 'C', 8) g.add_edge('C', 'B', 8) g.add_edge('E', 'D', 3) g.add_edge('D', 'E', 3) g.add_edge('D', 'C', 1) g.add_edge('C', 'D', 1) dijkstra(g, g.get_vertex('A'))
head_node = head_node.next_element # remove the node from the recursive call rec_node_stack[node] = False return False # g1 = Graph(4) # g1.add_edge(0, 1) # g1.add_edge(1, 2) # g1.add_edge(1, 3) # g1.add_edge(3, 0) # # g2 = Graph(3) # g2.add_edge(0, 1) # g2.add_edge(1, 2) g3 = Graph(10) g3.add_edge(0, 1) g3.add_edge(0, 2) g3.add_edge(1, 4) g3.add_edge(1, 5) g3.add_edge(2, 6) g3.add_edge(2, 7) g3.add_edge(3, 8) g3.add_edge(3, 9) g3.add_edge(9, 0) # print(detect_cycle(g1)) # print(detect_cycle(g2)) print(detect_cycle(g3))
class GraphApi(Resource): def __init__(self): # Arcos self._arcs = [] # Nodo inicial self._start = None # Nodo final self._goal = None # Instancia de la clase 'Graph' self._g_instance = None # Mensaje de respuesta al usuario self._data = None # Getters y setters @property def arcs(self): ''' Getter de la variable 'arcs'. :return: La variable 'arcs' ''' return self._arcs @arcs.setter def arcs(self, arcs): ''' Setter de la variable 'arcs'. :return: None ''' self._arcs = arcs @property def start(self): ''' Getter de la variable 'start'. :return: La variable 'start' ''' return self._start @start.setter def start(self, start): ''' Setter de la variable 'start'. :return: None ''' self._start = start @property def goal(self): ''' Getter de la variable 'goal'. :return: La variable 'goal' ''' return self._goal @goal.setter def goal(self, goal): ''' Setter de la variable 'goal'. :return: None ''' self._goal = goal @property def g_instance(self): ''' Getter de la variable 'g_instance'. :return: La variable 'g_instance' ''' return self._g_instance @g_instance.setter def g_instance(self, g_instance): ''' Setter de la variable 'g_instance'. :return: None ''' self._g_instance = g_instance @property def data(self): ''' Getter de la variable 'data'. :return: La variable 'data' ''' return self._data @data.setter def data(self, data): ''' Setter de la variable 'data'. :return: None ''' self._data = data def get(self): ''' Función que devuelve la lista de arcos del árbol (si la hay) al hacer una petición GET al endpoint '/graph'. :return: Un JSON con los arcos del grafo. ''' return {"data": "Graph API working..."} def put(self): ''' Función encargada de recibir los datos necesarios para crear un grafo. Los recibe en formato JSON cuando se hace una petición PUT al endpoint. :return: Una tupla de la forma (num_personas_necesarias, [lista_de_personas_necesarias]) ''' # Verificamos que cumpla con los datos que necesitamos args = graph_put_args.parse_args() # Función encargada de tratar la entrada self.clean_data(args) # Iniciamos el grafo self.start_graph() # Le damos formato al JSON de respuesta self.data = {"distance": self.data[0], "nodes": self.data[1]} return self.data, 201 def clean_data(self, args): # Guardamos el inicio y el objetivo self.start = args['start'] self.goal = args['goal'] # Separamos los arcos por parejas edges = args['edges'].split(',') # Separamos cada pareja edges = [tuple(map(int, edge.split('-'))) for edge in edges] # Guardamos los arcos en su variable respectiva self.arcs = edges # Modificamos la variable global for el in self.arcs: temp_graph.append(el) def delete(self): temp_graph.clear() return {"message": "Arcos borrados satisfactoriamente"} def are_arcs_empty(self): if len(temp_graph) == 0: abort(404, message="No se puede consultar un grafo sin nodos") def start_graph(self): self.g_instance = Graph(self.goal + 1) # Agregamos los arcos al grafo for pair in self.arcs: self.g_instance.add_edge(pair[0], pair[1]) # Buscamos la cantidad de personas necesarias para llegar de 'start' a 'goal' self.data = self.g_instance.find_love(self.start, self.goal)
# Dequeue a vertex/node from queue and add it to result current_node = queue.dequeue() result += str(current_node) # Get adjacent vertices to the current_node from the list, # and if they are not already visited then enqueue them in the Q temp = g.array[current_node].head_node while temp is not None: if not visited[temp.data]: queue.enqueue(temp.data) visited[temp.data] = True # Visit the current Node temp = temp.next_element return result g = Graph(7) g.add_edge(1, 2) g.add_edge(1, 3) g.add_edge(2, 4) g.add_edge(2, 5) g.add_edge(3, 6) print(bfs_traversal(g, 1)) # g = Graph(6) # # num_of_vertices = g.vertices # # if num_of_vertices == 0: # print("Graph is empty") # else: # g.add_edge(0, 1) # g.add_edge(0, 2) # g.add_edge(1, 3)
# Continue BFS by obtaining first element in linked list adjacent = g.array[node].head_node while adjacent: # enqueue adjacent node if it has not been visited if visited[adjacent.data] is False: queue.enqueue(adjacent.data) visited[adjacent.data] = True adjacent = adjacent.next_element # Destination was not found in the search return False g1 = Graph(9) g1.add_edge(0, 2) g1.add_edge(0, 5) g1.add_edge(2, 3) g1.add_edge(2, 4) g1.add_edge(5, 3) g1.add_edge(5, 6) g1.add_edge(3, 6) g1.add_edge(6, 7) g1.add_edge(6, 8) g1.add_edge(6, 4) g1.add_edge(7, 8) g2 = Graph(4) g2.add_edge(0, 1) g2.add_edge(1, 2) g2.add_edge(1, 3)
def check_cycle(g, node, visited, parent): # Mark node as visited visited[node] = True # Pick adjacent node and run recursive DFS adjacent = g.array[node].head_node while adjacent: if visited[adjacent.data] is False: if check_cycle(g, adjacent.data, visited, node) is True: return True # If adjacent is visited and not the parent node of the current node elif adjacent.data is not parent: # Cycle found return True adjacent = adjacent.next_element return False g = Graph(5) g.add_edge(0, 1) g.add_edge(0, 2) g.add_edge(0, 3) g.add_edge(3, 4) g.add_edge(1, 0) g.add_edge(2, 0) g.add_edge(3, 0) g.add_edge(4, 3) print(is_tree(g))