def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ with open(filename) as file: file_it = iter(file) graph_type = {'D': True, 'G': False}.get(next(file_it).strip('\n')) if graph_type is None: raise ValueError() graph = Graph(is_directed=graph_type) for num in next_alnum(next(file_it)): ## Use the second line to add the vertices to the graph graph.add_vertex(num) for line in file_it: ## Use the 3rd+ line to add the edges to the graph lineit = next_alnum(line) try: node1, node2 = next(lineit), next(lineit) graph.add_edge(node1, node2) except: pass return graph
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ # TODO: Use 'open' to open the file with open(filename, 'r', encoding='utf-8-sig') as f: # TODO: Use the first line (G or D) to determine whether graph is directed first = next(f).strip('\n') if first == 'D': graph = Graph(is_directed=True) elif first == 'G': graph = Graph(is_directed=False) else: raise ValueError('Invalid file format') # TODO: Use the second line to add the vertices to the graph for each in next(f).strip('\n').split(','): graph.add_vertex(each) # TODO: Use the 3rd+ line to add the edges to the graph for line in f: graph.add_edge(line[1], line[3]) return graph
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ my_file = open(filename) graph_type = my_file.readline().strip() if graph_type == "G": graph = Graph(False) elif graph_type == "D": graph = Graph(True) else: raise ValueError("Unexpected character") vertices = my_file.readline().strip().split(",") for vertex in vertices: graph.add_vertex(vertex) for edge in my_file: vertex1, vertex2 = edge.strip()[1:-1].split(",") graph.add_edge(vertex1, vertex2) return graph pass
def test_edge(): g = Graph() vertex_apple = g.add('apple') vertex_banana = g.add('banana') g.add_edge(vertex_apple, vertex_banana, 3) assert g._graph['apple'] == [('banana', 3)] assert g._graph['banana'] == [('apple', 3)]
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ # Use 'open' to open the file f = open(filename, "r").read().split() # Use the first line (G or D) to determine whether graph is directed # and create a graph object is_directed = True if f[0] == "D" else False graph = Graph(is_directed=is_directed) # Use the second line to add the vertices to the graph vertices = f[1].split(',') for v in vertices: graph.add_vertex(v) # Use the 3rd+ line to add the edges to the graph edges = f[2:] for e in edges: v1, v2 = e.strip(')(').split(',') graph.add_edge(v1, v2) return graph
def test_get_edges(self): graph = Graph() # Create test Verticies v1,v2,v3 = Vertex("a"), Vertex("b"), Vertex("c") # Add verticies graph.add_vertex(v1) graph.add_vertex(v2) graph.add_vertex(v3) self.assertEqual(graph.num_verticies, 3) self.assertEqual(graph.num_edges, 0) # Create edges edges = [ ("a", "b", 10), ("b", "c", 10), ("c", "a", 4) ] # Iterate through edges for edge in edges: fromVert, toVert, weight = edge graph.add_edge(fromVert, toVert, weight) self.assertEqual(graph.num_edges, 3)
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ # TODO: Use 'open' to open the file with open(filename) as f: lines = next(f).strip('\n') if lines == "G": graph = Graph(is_directed=False) elif lines == "D": graph = Graph() else: raise ValueError('Invalid graph type') next_line = next(f).strip('\n').split(',') for _ in next_line: graph.add_vertex(_) for line in f: graph.add_edge(line[1], line[3]) return graph
def main(s): file_name = '../resources/tinyG.txt' with open(file_name) as f: ints = list() for line in f.read().split('\n'): ints.append(line) vertices, edges = int(ints[0]), int(ints[1]) graph = Graph(vertices) print(graph) inp = ints[2:] # skip first lines vertices and edges for i in range(edges): v, w = inp[i].split(' ') graph.add_edge(int(v), int(w)) print(graph) search = DepthFirstSearch(graph, int(s)) for v in range(graph.get_V()): if search.marked(v): print(f'{v} ') print() if search.count() != graph.get_V(): print('Not connected.') else: print('Connected')
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ # Use 'open' to open the file with open(filename) as graph_file: graph_file_lines = graph_file.readlines() # Use the first line (G or D) to determine whether graph is directed # and create a graph object direction = graph_file_lines[0].strip() if direction != 'G' and direction != 'D': raise ValueError('File is in an imporper format') graph = Graph(is_directed=direction is 'D') # Use the second line to add the vertices to the graph for vertex in graph_file_lines[1].strip().split(','): graph.add_vertex(vertex) # Use the 3rd+ line to add the edges to the graph for edge in graph_file_lines[2:]: edge = edge.strip().split(',') graph.add_edge(edge[0][1], edge[1][0]) graph_file.close() return graph
def __satisfies_necessary_and_sufficient_conditions(g): """ Determines whether a digraph has an Eulerian path using necessary and sufficient conditions (without computing the path itself): - indegree(v) = outdegree(v) for every vertex, except one vertex v may have outdegree(v) = indegree(v) + 1 (and one vertex v may have indegree(v) = outdegree(v) + 1) - the graph is connected, when viewed as an undirected graph (ignoring isolated vertices) """ # Condition 0: at least 1 Edge if g.get_E() == 0: return True # Condition 1: indegree(v) == outdegree(v) for every vertex, # except one vertex may have outdegree(v) = indegree(v) + 1 deficit = 0 for v in range(g.get_V()): if g.outdegree() > g.indegree(v): deficit += (g.outdegree() - g.indegree(v)) if deficit > 1: return False # Condition 2: graph is connected, ignoring isolated vertices h = Graph(g.get_V()) for v in range(g.get_V()): for w in g.adj_vertices(v): h.add_edge(v, w) # check that all non-isolated vertices are connected s = DirectedEulerianPath.__non_isolated_vertex(g) bfs = BreadthFirstPaths(h, s) for v in range(g.get_V()): if h.degree(v) > 0 and not bfs.has_path_to(v): return False return True
def __satisfies_necessary_and_sufficient_conditions(g): """ Determines whether a digraph has an Eulerian cycle using necessary and sufficient conditions (without computing the cycle itself): - at least one edge - indegree(v) = outdegree(v) for every vertex - the graph is connected, when viewed as an undirected graph (ignoring isolated vertices) """ # Condition 0: at least 1 Edge if g.get_E() == 0: return False # Condition 1: indegree(v) == outdegree(v) for every vertex for v in range(g.get_V()): if g.outdegree() != g.indegree(v): return False # Condition 2: graph is connected, ignoring isolated vertices h = Graph(g.get_V()) for v in range(g.get_V()): for w in g.adj_vertices(v): h.add_edge(v, w) # check that all non-isolated vertices are connected s = DirectedEulerianCycle.__non_isolated_vertex(g) bfs = BreadthFirstPaths(h, s) for v in range(g.get_V()): if h.degree(v) > 0 and not bfs.has_path_to(v): return False return True
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ # Use 'open' to open the file # Use the first line (G or D) to determine whether graph is directed # and create a graph object f = open(filename).read().split() if f[0] not in ["D", "G"]: raise ValueError("File not proper format") directed = True if f[0] == "D" else False graph = Graph(directed) # Use the second line to add the vertices to the graph verticies = f[1].split(',') for vertex in verticies: graph.add_vertex(vertex) # Use the 3rd+ line to add the edges to the graph for edge in f[2:]: v1, v2 = edge[1:len(edge) - 1].split(',') graph.add_edge(v1, v2) return graph
def test_add_edge(self): graph = Graph(directed=True, weighted=False) graph.add_node(1) graph.add_edge(1, 2) assert len(graph) == 2 assert len(graph.nodes) == 2 assert len(graph.edges) == 1 assert graph.contains_edge((1, 2)) assert graph.adj == {1: {2}, 2: set()}
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ # Use 'open' to open the file f = open(filename, "r") # Use the first line (G or D) to determine whether graph is directed # and create a graph object first_line = f.readline().strip() graph = Graph(False) # If undirected if first_line == "G": graph = Graph(False) # If directed elif first_line == "D": graph = Graph() else: print("Invalid Input") print(first_line) # Use the second line to add the vertices to the graph vertices = f.readline().strip() for _ in vertices: graph.add_vertex(_) # Use the 3rd+ line to add the edges to the graph for line in f: if line != '': print(line) curr = line.replace('(', '') curr = curr.replace(')', '').strip() curr = curr.split(",") print("Current line: {}".format(curr)) if curr: vert1 = graph.add_vertex(curr[0]) vert2 = graph.add_vertex(curr[1]) # print("Vert 1: {} Vert 2: {}".format(vert1, vert2)) graph.add_edge(vert1.get_id(), vert2.get_id()) f.close() return graph
def test_does_contain_cycle(self): graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('C', 'A') self.assertTrue(graph.contains_cycle())
def test_add_edge_interloper_end(): graph = Graph() end = Vertex('end') start = graph.add_node('start') with pytest.raises(KeyError): graph.add_edge(start, end)
def test_does_not_contain_cycle_dag(self): """Test that a DAG does not contain a cycle.""" graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('A', 'C') self.assertFalse(graph.contains_cycle())
def courseOrder(numCourses, prerequisites): """Return a course schedule according to the prerequisites provided.""" graph = Graph(is_directed=True) for i in range(numCourses): graph.add_vertex(i) for elm in prerequisites: graph.add_edge(elm[1], elm[0]) return graph.topological_sort()
def test_contains_cycle_undirected(self): graph = Graph(is_directed=False) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A','B') graph.add_edge('B','C') graph.add_edge('C','A') # This would be true if graph were directed self.assertTrue(graph.contains_cycle())
def test_not_bipartite(self): """Test that a cycle on 3 vertices is NOT bipartite.""" graph = Graph(is_directed=False) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('B', 'C') self.assertFalse(graph.is_bipartite())
def test_find_path_dfs(self): graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('C', 'A') path = graph.find_path_dfs_iter('A', 'C') self.assertEqual(path, ['A', 'B', 'C'])
def test_is_bipartite_tree(self): """Test that a tree on 4 vertices is bipartite.""" graph = Graph(is_directed=False) vertex_a = graph.add_vertex('A') vertex_b = graph.add_vertex('B') vertex_c = graph.add_vertex('C') vertex_d = graph.add_vertex('D') graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('A', 'D') self.assertTrue(graph.is_bipartite())
def test_does_not_contain_cycle_tree(self): """Test that a tree on 4 vertices does not contain a cycle.""" graph = Graph(is_directed=True) vertex_a = graph.add_vertex('A') vertex_b = graph.add_vertex('B') vertex_c = graph.add_vertex('C') vertex_d = graph.add_vertex('D') graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('A', 'D') self.assertFalse(graph.contains_cycle())
def test_is_bipartite_cycle(self): """Test that a cycle on 4 vertices is bipartite.""" graph = Graph(is_directed=False) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_vertex('D') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('C', 'D') graph.add_edge('A', 'D') self.assertTrue(graph.is_bipartite())
def to_graph(self): """ Create a graph from this tree, vertices pointing toward their parents. """ g = Graph() count = 0 for vertex in self.preorder(): vertex._index = count g.add_vertex(vertex._index, vertex.value) if vertex.parent is not None: g.add_edge(vertex._index, vertex._index, vertex.parent._index) count += 1 return g
def bipartite_generator(v1, v2, p): def bernoulli(_p=0.5): if _p < 0 or _p > 1.0: raise AttributeError('probability must be between 0 and 1') return random.uniform(0, 1) < _p vertices = [i for i in range(v1 + v2)] random.shuffle(vertices) g = Graph(v1 + v2) for i in range(v1): for j in range(v2): if bernoulli(p): g.add_edge(vertices[i], vertices[v1 + j]) return g
def test_has_cycle(self): """Create a graph.""" graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_vertex('D') graph.add_vertex('E') graph.add_vertex('F') graph.add_vertex('G') graph.add_vertex('H') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('C', 'A') graph.add_edge('D', 'E') graph.add_edge('E', 'F') graph.add_edge('G', 'H') graph.add_edge('G', 'F') self.assertEqual(True, graph.contains_cycle())
def test_add_edge(): graph = Graph() graph.add_edge(Edge(Node(2), Node(2))) assert len(graph.edges) == 0 graph.add_edge(Edge(Node(5), Node(2))) assert len(graph.edges) == 0 graph.add_node(Node(2)) graph.add_edge(Edge(Node(2), Node(2))) assert len(graph.edges) == 1 graph.add_node(Node(5)) graph.add_edge(Edge(Node(2), Node(5))) assert len(graph.edges) == 2 graph.add_edge(Edge(Node(5), Node(2))) assert len(graph.edges) == 2
def test_connected_components_directed(self): """Create a graph.""" graph = Graph(is_directed=True) graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_vertex('D') graph.add_vertex('E') graph.add_vertex('F') graph.add_vertex('G') graph.add_vertex('H') graph.add_edge('A', 'B') graph.add_edge('B', 'C') graph.add_edge('C', 'A') graph.add_edge('D', 'E') graph.add_edge('E', 'F') graph.add_edge('G', 'H') graph.add_edge('G', 'F') connected_components = sorted([ sorted(component) for component in graph.get_connected_components() ]) answer = sorted([ sorted(['A', 'B', 'C']), sorted(['D', 'E', 'F', 'G', 'H']), ]) self.assertListEqual(connected_components, answer)
def main(): g = Graph(6) print(g) g.add_edge(0, 5) g.add_edge(2, 4) g.add_edge(2, 3) g.add_edge(1, 2) g.add_edge(0, 1) g.add_edge(3, 4) g.add_edge(3, 5) g.add_edge(0, 2) print(g) s = 0 dfs = DepthFirstPaths(g, s) print(dfs) for v in range(g.get_V()): if dfs.has_path_to(v): print(f'{s} to {v}') for x in reversed(dfs.path_to(v)): if x == s: print(x, end="") else: print(f' - {x}', end="") print() else: print(f'{s} to {v}: not connected\n')
def read_graph_from_file(filename): """ Read in data from the specified filename, and create and return a graph object corresponding to that data. Arguments: filename (string): The relative path of the file to be processed Returns: Graph: A directed or undirected Graph object containing the specified vertices and edges """ # TODO: Use 'open' to open the file # TODO: Use the first line (G or D) to determine whether graph is directed # and create a graph object # TODO: Use the second line to add the vertices to the graph # TODO: Use the 3rd+ line to add the edges to the graph graph_obj = None with open(filename) as graph_file: for index, line in enumerate(graph_file.readlines()): line = line.strip() if index == 0: line_parts = line.split(", ") if line_parts[0] not in ("D", "G"): raise (ValueError("Bad graph type")) return graph_obj = Graph(is_directed=(line_parts[0] == "D"), lat=float(line_parts[1]), lng=float(line_parts[2])) elif index == 1: for vertex in line.split(';'): vertex_id, sweetness, saltiness, savoriness, num_stars = vertex.split( ", ") if vertex_id == "": continue else: graph_obj.add_vertex(vertex_id, sweetness, saltiness, savoriness, num_stars) else: if line == "": continue vertices = line[1:-1].split(',') graph_obj.add_edge(vertices[0], vertices[1]) return graph_obj
from graphs.topological_sort import * from graphs import util from graphs.graph import Graph import unittest graph1 = Graph() for v in [0, 1, 2, 3, 4, 5]: graph1.add_node(v) graph1.add_edge(5, 2) graph1.add_edge(5, 0) graph1.add_edge(4, 0) graph1.add_edge(4, 1) graph1.add_edge(2, 3) graph1.add_edge(3, 1) graph2 = Graph() for v in [5, 7, 3, 11, 8, 2, 9, 10]: graph2.add_node(v) graph2.add_edge(3, 8) graph2.add_edge(3, 10) graph2.add_edge(5, 11) graph2.add_edge(7, 8) graph2.add_edge(7, 11) graph2.add_edge(8, 9) graph2.add_edge(11, 2) graph2.add_edge(11, 9) graph2.add_edge(11, 10) class TestTopsort(unittest.TestCase): def test_dfs_topsort(self):
assert((s,t) in a) aa[(s,t)] = set() for e in graph.iter_connections(s,t): aa[(s,t)].add(e) if not graph.is_adjacent(s,t): assert((s,t) not in a) assert(aa==a) g = Graph() assert(str(g) == "<Graph with %d vertices and %d edges>" %(0, 0)) check_graph_validity(g) g.add_vertex('spam') check_graph_validity(g) g.add_edge('E1,2', 1, 2) check_graph_validity(g) assert(str(g) == "<Graph with %d vertices and %d edges>" %(3, 1)) check_graph_validity(g) g.remove_vertex(1) check_graph_validity(g) g.clear() check_graph_validity(g) g.add_vertex("spam") g.add_vertex("eggs") for i in range(0,4): for j in range(0,4): if i<j: