def from_networkx(ngraph): if ngraph.is_directed(): raise NotImplementedError() else: graph = UndirectedGraph(ngraph.number_of_nodes()) for edge in ngraph.edges_iter(): graph.add_edge(int(edge[0]), int(edge[1])) return graph
def build_graph(adj, features, labels): edges = np.array(adj.nonzero()).T y_values = np.array(labels.nonzero()).T domain_labels = [] for i in range(labels.shape[1]): domain_labels.append("c" + str(i)) # create graph graph = UndirectedGraph() id_obj_map = [] for i in range(adj.shape[0]): n = Node(i, features[i, :], domain_labels[y_values[i, 1]]) graph.add_node(n) id_obj_map.append(n) for e in edges: graph.add_edge(Edge(id_obj_map[e[1]], id_obj_map[e[0]])) return graph, domain_labels
def dfs_iterative(graph, start_node): visited = [start_node] stack = [start_node] print('Visited', start_node) while stack != []: popped = stack.pop() if popped not in visited: print('Visited', popped) visited.append(popped) for node in graph.adjacents(popped): if node not in visited: stack.append(node) if __name__ == '__main__': g = UndirectedGraph() g.add_edge(0, 1) g.add_edge(0, 2) g.add_edge(0, 3) g.add_edge(1, 4) g.add_edge(1, 5) g.add_edge(2, 6) g.add_edge(2, 7) g.add_edge(3, 7) bfs(g, 0) print('=' * 50) dfs(g, 0) print('=' * 50) dfs_iterative(g, 0)
self._marked[a] = True self.queue.append(a) def has_path_to(self, v: int): return self._marked[v] def path_to(self, v: int): if self.has_path_to(v) == False: return None path = [] x = v while x != self._s: path.append(x) x = self._edgeto[x] path.append(self._s) for i in reversed(path): print(f"{i}->", end='') def marked(self, v: int): return self._marked[v] G1 = UndirectedGraph(5) G1.add_edge(0, 1) G1.add_edge(1, 2) G1.add_edge(2, 3) print(G1) bfs = BFS(G1, 0) print(bfs.has_path_to(3)) print(bfs.path_to(4)) print(bfs.path_to(3))
class TestUndirectedGraphMethods(unittest.TestCase): def setUp(self): self.graph = UndirectedGraph() self.filled_graph = UndirectedGraph() for i in range(6): self.filled_graph.add_vertex(i + 1) self.filled_graph.add_edge(1, 2) self.filled_graph.add_edge(1, 4) self.filled_graph.add_edge(2, 4) self.filled_graph.add_edge(2, 3) self.filled_graph.add_edge(4, 3) self.filled_graph.add_edge(3, 6) self.filled_graph.add_edge(4, 5) self.filled_graph.add_edge(5, 6) def test_adjacent(self): # Edge does exist. self.assertTrue(self.filled_graph.adjacent(1, 2)) # Edge does not exist. self.assertFalse(self.filled_graph.adjacent(1, 3)) # Vertices to test do not exist. self.assertFalse(self.filled_graph.adjacent(5, 8)) def test_neighbors(self): self.assertCountEqual(self.filled_graph.neighbors(4), [1, 2, 3, 5]) self.assertCountEqual(self.filled_graph.neighbors(6), [3, 5]) self.assertEqual(self.filled_graph.neighbors(199), []) def test_add_vertex(self): old_len = len(self.graph) self.graph.add_vertex(0) self.assertEqual(len(self.graph), old_len + 1) def test_remove_vertex(self): # Remove a vertex that exists and verify its neighbors are updated. target = 6 old_len = len(self.filled_graph) self.filled_graph.remove_vertex(target) self.assertEqual(len(self.filled_graph), old_len - 1) self.assertNotIn(target, self.filled_graph.vertices) self.assertNotIn(target, self.filled_graph.neighbors(3)) self.assertNotIn(target, self.filled_graph.neighbors(5)) # Attempt to remove a vertex that doesn't exist. target = 100 old_len = len(self.filled_graph) self.filled_graph.remove_vertex(target) self.assertEqual(len(self.filled_graph), old_len) self.assertNotIn(target, self.filled_graph.vertices) def test_add_edge(self): # Add edge between existing vertices. self.assertFalse(self.filled_graph.adjacent(2, 6)) self.filled_graph.add_edge(2, 6) self.assertTrue(self.filled_graph.adjacent(2, 6)) # Attempt to add edge to vertex that doesn't exist. self.filled_graph.add_edge(2, 100) self.assertNotIn(100, self.filled_graph.neighbors(2)) def test_remove_edge(self): # Remove existing edge. self.assertIn(3, self.filled_graph.neighbors(6)) self.filled_graph.remove_edge(3, 6) self.assertNotIn(3, self.filled_graph.neighbors(6)) # Attempt to remove non-existing edge. self.assertNotIn(1, self.filled_graph.neighbors(5)) self.filled_graph.remove_edge(1, 5) self.assertNotIn(1, self.filled_graph.neighbors(5))
print(f'\nSolving {test}') # read the file with open(f'./tests/{test}', 'r') as f: n = int(f.readline().strip()) m = int(f.readline().strip()) # make sure the test is valid assert n > 0, 'Number of nodes is invalid' # I can have a maximum number of edges of n*(n-1)/2 assert m <= n * (n - 1) / 2, 'Number of edges is too big' # create our graph g = UndirectedGraph(n, {}) for _ in range(m): line = f.readline().strip() a, b = [int(x) for x in line.split(' ')] g.add_edge(a, b) # print(g) # answer the questions f_out = open('./tests/' + test.replace('.in', '.out'), 'w') no_queries = int(f.readline().strip()) for _ in range(no_queries): line = f.readline().strip() a, b = [int(x) for x in line.split(' ')] res = g.get_shortest_path(a, b) assert res == g.get_shortest_path_simple_bfs( a, b), 'One of the implementations is wrong' s = f'Distance between {a} and {b}: {res}' f_out.write(s + '\n') print(s)
def create_map(self, file_name): walls = {} print 'Reading File' f = open(file_name, 'r') # Reading walls: [row, col, up, left, down, right] print '\t> Parsing walls' [MAX_ROW, MAX_COL] = f.readline().split(' ') MAX_ROW = int(MAX_ROW) MAX_COL = int(MAX_COL) for i in range(0, MAX_ROW*MAX_COL): data = f.readline().split(' ') print 'data: ', data data = map(int, data) walls[(data[0],data[1])] = (data[2],data[3],data[4], data[5]) f.close() # Generating graph print 'Generating graph' graph = UndirectedGraph() for i in range(0, MAX_ROW): for j in range(0, MAX_COL): graph.add_node((i,j,Orientation.up)) graph.add_node((i,j,Orientation.left)) graph.add_node((i,j,Orientation.down)) graph.add_node((i,j,Orientation.right)) graph.add_edge((i,j,Orientation.up), (i,j,Orientation.left)) graph.add_edge((i,j,Orientation.left), (i,j,Orientation.down)) graph.add_edge((i,j,Orientation.down), (i,j,Orientation.right)) graph.add_edge((i,j,Orientation.right), (i,j,Orientation.up)) for node, ws in walls.items(): if ws[0] == 0: graph.add_edge((node[0],node[1],Orientation.up), (node[0]+1,node[1],Orientation.up)) if ws[1] == 0: graph.add_edge((node[0],node[1],Orientation.left), (node[0],node[1]-1,Orientation.left)) if ws[2] == 0: graph.add_edge((node[0],node[1],Orientation.down), (node[0]-1,node[1],Orientation.down)) if ws[3] == 0: graph.add_edge((node[0],node[1],Orientation.right), (node[0],node[1]+1,Orientation.right)) return graph
dist[initial_node] = 0 prev = [None for _ in range(g.num_vertices)] unseen_vertices = [v for v in range(g.num_vertices)] while unseen_vertices: min_node, min_value = unseen_vertices[0], dist[0] for v in unseen_vertices: if dist[v] < min_value: min_node, min_value = v, dist[v] cur = min_node unseen_vertices.remove(cur) for neighbour in g.get_neighbours(cur): if neighbour in unseen_vertices: alt = dist[cur] + g.get_weight(cur, neighbour) if alt < dist[neighbour]: dist[neighbour] = alt prev[neighbour] = cur return dist, prev if __name__ == "__main__": g = UndirectedGraph(5) g.add_edge(0, 1) g.add_edge(0, 2) g.add_edge(2, 3) g.add_edge(3, 4) print(dijkstra(g, 3))
return self._marked[v] def count(self): return self._count def connected(self): return self._cc == 1 class BFS: def __init__(self, G, s): self._G = G self._s = s G1 = UndirectedGraph(6) G1.add_edge(0, 1) G1.add_edge(0, 2) G1.add_edge(0, 5) G1.add_edge(1, 2) G1.add_edge(2, 3) G1.add_edge(2, 4) G1.add_edge(3, 4) G1.add_edge(3, 5) print(G1) dfs = DFS(G1, 0) print(dfs.connected()) print(dfs._cc) print(dfs._id) print(dfs.has_path_to(0))
print("\nPaths from A to D:") g.print_paths('A', 'D') print("\n\n***Undirected graph***") u = UndirectedGraph() u.add_vertex('A') u.add_vertex('A') u.add_vertex('B') u.add_vertex('C') print("\nVertices:", u.vertices()) u.add_edge('A', 'B') u.add_edge('B', 'C') u.add_edge('C', 'D') u.add_edge('C', 'B') u.add_edge('B', 'D') u.add_edge('D', 'A') print("\nEdges:") u.print_edges() print("\nA <-> B?", u.is_connected('A', 'B')) print("B <-> A?", u.is_connected('B', 'A')) print("C <-> D?",u.is_connected('C', 'D')) print("\nPaths from A to D: ") u.print_paths('A', 'D')
class FileLoader(object): def __init__(self): self.walls = {} self.starts = [] self.goals = [] self.keys = [] self.max_cols = None self.max_rows = None self.undirected_graph = UndirectedGraph() self.directed_graph = DirectedGraph() self.distance_node = {} self.node_distance = {} def read_map(self, file_name): print 'Reading File' f = open(file_name, 'r') # Reading walls: [row, col, up, left, down, right] print '\t> Parsing walls' [self.max_rows, self.max_cols] = f.readline().split(' ') self.max_rows = int(self.max_rows) self.max_cols = int(self.max_cols) for i in range(0, self.max_rows*self.max_cols): data = f.readline().split(' ') print 'data: ', data data = map(int, data) self.walls[(data[0],data[1])] = (data[2],data[3],data[4], data[5]) # Reading starts print '\t> Parsing ', f.readline() MAX_START = int(f.readline()) for i in range(0, MAX_START): data = f.readline().split(' ') if data[2][0] == 'u': orientation = 0 elif data[2][0] == 'l': orientation = 1 elif data[2][0] == 'd': orientation = 2 else: orientation = 3 self.starts.append((int(data[0]),int(data[1]),orientation)) # Reading Goals print '\t> Parsing ', f.readline() MAX_GOALS = int(f.readline()) for i in range(0, MAX_GOALS): data = f.readline().split(' ') row = int(data[0]) col = int(data[1]) self.goals.append((row,col)) # Reading Keys print '\t> Parsing ', f.readline() MAX_KEYS = int(f.readline()) for i in range(0, MAX_KEYS): data = f.readline().split(' ') row = int(data[0]) col = int(data[1]) self.keys.append((row,col)) f.close() def generate_undirected_graph(self): orientations = [Orientation.up, Orientation.left, Orientation.down, Orientation.right] for w in self.walls.keys(): row = w[0] col = w[1] for o in orientations: self.undirected_graph.add_node((row,col,o)) self.undirected_graph.add_edge((row,col,Orientation.up), (row,col,Orientation.left)) self.undirected_graph.add_edge((row,col,Orientation.left), (row,col,Orientation.down)) self.undirected_graph.add_edge((row,col,Orientation.down), (row,col,Orientation.right)) self.undirected_graph.add_edge((row,col,Orientation.right), (row,col,Orientation.up)) for node, ws in self.walls.items(): if ws[0] == 0: self.undirected_graph.add_edge((node[0],node[1],Orientation.up), (node[0]+1,node[1],Orientation.up)) if ws[1] == 0: self.undirected_graph.add_edge((node[0],node[1],Orientation.left), (node[0],node[1]-1,Orientation.left)) if ws[2] == 0: self.undirected_graph.add_edge((node[0],node[1],Orientation.down), (node[0]-1,node[1],Orientation.down)) if ws[3] == 0: self.undirected_graph.add_edge((node[0],node[1],Orientation.right), (node[0],node[1]+1,Orientation.right)) def generate_directed_graph(self): orientations = [Orientation.up, Orientation.left, Orientation.down, Orientation.right] for w in self.walls.keys(): row = w[0] col = w[1] for o in orientations: self.directed_graph.add_node((row,col,o)) self.directed_graph.add_edge((row,col,Orientation.up), (row,col,Orientation.left)) self.directed_graph.add_edge((row,col,Orientation.left), (row,col,Orientation.up)) self.directed_graph.add_edge((row,col,Orientation.left), (row,col,Orientation.down)) self.directed_graph.add_edge((row,col,Orientation.down), (row,col,Orientation.left)) self.directed_graph.add_edge((row,col,Orientation.down), (row,col,Orientation.right)) self.directed_graph.add_edge((row,col,Orientation.right), (row,col,Orientation.down)) self.directed_graph.add_edge((row,col,Orientation.right), (row,col,Orientation.up)) self.directed_graph.add_edge((row,col,Orientation.up), (row,col,Orientation.right)) for node, ws in self.walls.items(): if ws[0] == 0: self.directed_graph.add_edge((node[0],node[1],Orientation.up), (node[0]+1,node[1],Orientation.up)) if ws[1] == 0: self.directed_graph.add_edge((node[0],node[1],Orientation.left), (node[0],node[1]-1,Orientation.left)) if ws[2] == 0: self.directed_graph.add_edge((node[0],node[1],Orientation.down), (node[0]-1,node[1],Orientation.down)) if ws[3] == 0: self.directed_graph.add_edge((node[0],node[1],Orientation.right), (node[0],node[1]+1,Orientation.right)) def estimate_distances(self): #print '> Exploring distances' nodes = self.undirected_graph.nodes for node in nodes: #print '\t>>Localization::estimate_distances Node ', node distance = 0 orientation = node[2] aux_node = node test_node = node while True: if orientation == Orientation.up: test_node = (aux_node[0] + 1, aux_node[1], aux_node[2]) elif orientation == Orientation.left: test_node = (aux_node[0], aux_node[1] - 1, aux_node[2]) elif orientation == Orientation.down: test_node = (aux_node[0] - 1, aux_node[1], aux_node[2]) elif orientation == Orientation.right: test_node = (aux_node[0], aux_node[1] + 1, aux_node[2]) if not test_node in self.undirected_graph.edges[aux_node]: #BUG break aux_node = test_node distance = distance + 1 self.distance_node.setdefault(distance, []) self.distance_node[distance].append(node) self.node_distance[node] = distance
nonlocal found if found: return visited[from_vertex] = True if from_vertex == to: found = True return for related in graph_object.adj_table[from_vertex]: if found: return if not visited[related]: prev[related] = from_vertex _dfs(related) _dfs(fr) print('->'.join(print_path(fr, to, prev))) if __name__ == '__main__': ug = UndirectedGraph(8) ug.add_edge(0, 1) ug.add_edge(0, 3) ug.add_edge(1, 2) ug.add_edge(1, 4) ug.add_edge(2, 5) ug.add_edge(3, 4) ug.add_edge(4, 5) ug.add_edge(4, 6) ug.add_edge(5, 7) ug.add_edge(6, 7) bfs(ug, 0, 7) dfs(ug, 0, 7)