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 run_simulation(n, cycle, itererations, perturbation_scale=0.1, epsilon=0): correct_count = 0 graph_denoiser = GraphDenoiser(n, cycle) A_matrix = Graph.create_adjacency_matrix(n, A) # vector of small parameters for spectral hull epsilon_vector = epsilon * np.ones(n) for i in range(0, iterations): # perturb matrix (introduce noise to the weights) A_matrix_noisy = perturb_matrix(A_matrix, perturbation_scale) status, problem_value, A_recovered = graph_denoiser.denoise( A_matrix_noisy, epsilon_vector) if status == 'optimal': print('Problem status: ', status) cycle = is_cycle(Graph.create_adjacency_list(n, A_recovered)) print('Is cycle: ', cycle) if cycle: correct_count += 1 return correct_count
def graph_types(): graphFF = Graph(directed=False, weighted=False) graphFT = Graph(directed=False, weighted=True) graphTF = Graph(directed=True, weighted=False) graphTT = Graph(directed=True, weighted=True) return graphFF, graphFT, graphTF, graphTT
def test_deep_equals(self): A_matrix = Graph.create_adjacency_matrix(self.n, self.A) A1_matrix = Graph.create_adjacency_matrix(self.n, self.A1) A2_matrix = Graph.create_adjacency_matrix(self.n, self.A2) result = Utils.deep_equals(A_matrix, A1_matrix + A2_matrix, 1e-4) self.assertTrue(result)
def run_simulation(n, A1, multipartite_graph_matrix, iterations, partitions): correct_count = 0 for i in range(0,iterations): A2 = Graph.create_adjacency_list(n,multipartite_graph_matrix) #need to do this as it hasn't updated the internal adjacency list representation # graph deconvolver with new components graph_deconvolver = GraphDeconvolver(n,A1,A2) #convolved graphs A_matrix = Graph.create_adjacency_matrix(n,A1) + multipartite_graph_matrix status,problem_value,A1_star,A2_star= graph_deconvolver.deconvolve(A_matrix) # first check has the correct degree sequence before check multipartite, (needs to be complete) correct_degree_sequence = check_degree_sequence(partitions,np.round(A2_star)) # check_degree_sequence can't deal with weighted edges so round if correct_degree_sequence: adjacency_table = Graph.create_adjacency_table(n,A2_star) #print('p=',partitions,'\ng=',adjacency_table) multipartite_graph_recognizer=Multipartite_graph_recognizer(partitions,adjacency_table) ok=multipartite_graph_recognizer.check() print('multipartite:',multipartite_graph_recognizer.match) else: print('incorrect degree sequence') ok=False np.set_printoptions(suppress=True) print('Problem status: ',status) cycle = is_cycle(Graph.create_adjacency_list(n,A1_star)) print('Is cycle: ', cycle) print('A2 correct: ',ok) if cycle and ok: correct_count +=1 return correct_count
def run_simulation(n, A1, clebsch_graph, iterations, number_of_pertubations): correct_count = 0 for i in range(0, iterations): # perturb matrix (add/remove edge randomly) clebsch_matrix = clebsch_graph.adjacency_matrix.copy() clebsch_matrix = perturb_matrix(n, clebsch_matrix, number_of_pertubations) A2 = Graph.create_adjacency_list( n, clebsch_matrix ) #need to do this as it hasn't updated the internal adjacency list representation # graph deconvolver with new components graph_deconvolver = GraphDeconvolver(n, A1, A2) #convolved graphs A_matrix = Graph.create_adjacency_matrix(n, A1) + clebsch_matrix status, problem_value, A1_star, A2_star = graph_deconvolver.deconvolve( A_matrix) print('Problem status: ', status) cycle = is_cycle(Graph.create_adjacency_list(n, A1_star)) print('Is cycle: ', cycle) if cycle: correct_count += 1 return correct_count
def run_simulation(n, cycle, itererations, perturbation_scale=0.1, epsilon=0): correct_count = 0 graph_denoiser = GraphDenoiser(n, cycle) A_matrix = Graph.create_adjacency_matrix(n, A) # vector of small parameters for spectral hull epsilon_vector = epsilon * np.ones(n) # adjacency matrix to compare against to check is denoised correctly #test_clebsch_adjacency_matrix = Graph.create_adjacency_matrix(n,cycle) for i in range(0, iterations): # perturb matrix (introduce noise to the weights) A_matrix_noisy = perturb_matrix(A_matrix, perturbation_scale) status, problem_value, A_recovered = graph_denoiser.denoise( A_matrix_noisy, epsilon_vector) if status == 'optimal': print('Problem status: ', status) cycle = is_cycle(Graph.create_adjacency_list(n, A_recovered)) print('Is cycle: ', cycle) # check for clebsch graph #cycle = np.allclose(test_clebsch_adjacency_matrix,A_recovered, atol=1e-3) #print('Is clebsch graph: ', cycle) if cycle: correct_count += 1 return correct_count
def test_cyclic_graph(): graph = Graph() nodes = [["a", "b"], ["b", "c"], ["c", "d"], ["d", "e"], ["d", "a"], ["a", "d"], ["e", "z"], ["z", "a"]] graph.make_unweighted_from_list(nodes) with raises(CyclicGraphException): actual_path = graph.topological_sort()
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 run_simulation(n, cycle,itererations, perturbation_scale = 0.1): correct_count = 0 graph_denoiser = GraphDenoiser(n,cycle) A_matrix = Graph.create_adjacency_matrix(n,A) # generate cum sum of mean shift in eigenvalue distribution for i in range(0,iterations): # perturb matrix (introduce noise to the weights) A_matrix_noisy = perturb_matrix(A_matrix,perturbation_scale) epsilon_vector = calculate_epsilon_vector(A_matrix,A_matrix_noisy) print status,problem_value,A_recovered= graph_denoiser.denoise(A_matrix_noisy,epsilon_vector) print('Problem status: ',status) cycle = is_cycle(Graph.create_adjacency_list(n,A_recovered)) print('Is cycle: ', cycle) if cycle: correct_count +=1 return correct_count
def run_simulation(n, A1, clebsch_graph, iterations, perturbation_scale=0.1, epsilon=0): correct_count = 0 epsilon_vector = epsilon * np.ones(n) for i in range(0, iterations): # perturb matrix (introduce noise to the weights) clebsch_matrix = perturb_matrix(clebsch_graph.adjacency_matrix, perturbation_scale) A2 = Graph.create_adjacency_list( n, clebsch_matrix ) #need to do this as it hasn't updated the internal adjacency list representation # graph deconvolver with new components graph_deconvolver = GraphDeconvolver(n, A1, A2) #convolved graphs A_matrix = Graph.create_adjacency_matrix(n, A1) + clebsch_matrix status, problem_value, A1_star, A2_star = graph_deconvolver.deconvolve( A_matrix, epsilon_vector) if status == 'optimal': print('Problem status: ', status) cycle = is_cycle(Graph.create_adjacency_list(n, A1_star)) print('Is cycle: ', cycle) if cycle: correct_count += 1 return correct_count
def run_simulation(n, A1, clebsch_graph, iterations, perturbation_scale=0.1): correct_count = 0 epsilon_vector = np.zeros(n) # no small parameter # graph deconvolver with new components graph_deconvolver = GraphDeconvolver(n, A1, clebsch_graph.adjacency_list) for i in range(0, iterations): # perturb matrix (introduce noise to the weights) clebsch_matrix = perturb_matrix(clebsch_graph.adjacency_matrix, perturbation_scale) #convolved graphs A_matrix = Graph.create_adjacency_matrix(n, A1) + clebsch_matrix status, problem_value, A1_star, A2_star = graph_deconvolver.deconvolve( A_matrix, epsilon_vector) print('Problem status: ', status) cycle = is_cycle(Graph.create_adjacency_list(n, A1_star)) print('Is cycle: ', cycle) if cycle: correct_count += 1 return correct_count
def test_passes_with_unused_negative_weights(): graph = Graph() nodes = [["a","b", 4], ["c", "d", -1]] graph.make_weighted_from_list(nodes) actual_path = graph.dijkstras_with_target(start=Node("a"), target=Node("b")) expected_path = ["a", "b"] assert actual_path == expected_path
def test_large_vs_known_implementation(): """ Creates a large random graph and runs dijkstra's algorithm with this implementation as well as a known good implementation I grabbed from github. Compares that the results returned are the same """ import random size = 1000 my_graph = Graph() my_nodes = [] other_graph = OtherGraph() for i in range(size): start_node = i end_node = random.randint(0, size) length = random.randrange(0, 10000) my_nodes.append([start_node, end_node, length]) other_graph.add_edge(start_node, end_node, length) my_graph.make_weighted_from_list(my_nodes) my_prev, my_unvisited = my_graph.dijkstra(start=Node(0)) other_visited, other_prev = known_dijkstras_implementation(other_graph, 0) unvisited_diff = my_unvisited.keys() - other_visited.keys() visited_diff = other_visited.keys() - my_unvisited.keys() assert my_prev == other_prev and my_unvisited.keys() == unvisited_diff and other_visited.keys() == visited_diff
def test_with_disconnected_nodes(): graph = Graph() nodes = [["a"], ["b"]] graph.make_unweighted_from_list(nodes) actual_path = graph.dijkstras_with_target(start=Node("a"), target=Node("b")) expected_path = [] assert actual_path == expected_path
def test_cyclic_graph(): graph = Graph() nodes = [["a","b"], ["b","c"], ["b", "a"], ["b", "z"], ["c", "d"], ["c", "e"], ["e", "a"]] graph.make_unweighted_from_list(nodes) expected_path = ["a", "b", "c", "e"] actual_path = graph.dijkstras_with_target(start=Node("a"), target=Node("e")) assert actual_path == expected_path
def test_cyclic_graph_no_path(): graph = Graph() nodes = [["a","b"],["b","a"],["c"]] graph.make_unweighted_from_list(nodes) expected_path = [] actual_path = graph.depth_first_search(start=Node("a"), target=Node("c")) assert actual_path == expected_path
def __init__(self): """ Initializes an empty dictionary to contain Edge instances. Keys will be Edge labels as strings. Key values will be Edge instances. """ self.edges = {} self.graph = Graph()
def test_cyclic_graph_large(): graph = Graph() nodes = [["a", "b"], ["b", "c"], ["c", "d"], ["d", "e"], ["d", "a"], ["a", "d"], ["e", "z"], ["z", "a"]] graph.make_unweighted_from_list(nodes) expected_path = ["a", "d", "e", "z"] actual_path = graph.breadth_first_search(start=Node("a"), target=Node("z")) assert actual_path == expected_path
def test_straight_line_graph(): # a straight line graph is one that has only one path at each node graph = Graph() nodes = [["a","b",1],["b","c",1]] graph.make_weighted_from_list(nodes) expected_path = ["a","b","c"] actual_path = graph.dijkstras_with_target(Node("a"),Node("c")) assert actual_path == expected_path
def test_add_node(self): graph = Graph(directed=True) graph.add_node(1) graph.add_node(2) assert graph.contains_node(1) assert graph.contains_node(2) assert len(graph) == 2 assert len(graph.nodes) == 2 assert graph.adj == {1: set(), 2: set()}
def test_size_empty(): graph = Graph() expected = 0 actual = graph.size() assert actual == expected
def test_add_node(): graph = Graph() expected = 'spam' # a vertex's value that comes back actual = graph.add_node('spam').value assert actual == expected
def test_weighted_list_of_int(): graph = Graph() nodes = [[1, 2, 99], [2, 3, 26], [3, 5, 130], [5, 1, 2], [2, 5, 0]] graph.make_unweighted_from_list(nodes) test_graph = { Node(1):[Edge(1,2,99)], Node(2):[Edge(2,3,26), Edge(2,5,0)], Node(3):[Edge(3,5,130)], Node(5):[Edge(5,1,2)]} assert compare_graphs(test_graph, graph.graph) == True
def test_weighted_undirected(): graph = Graph() nodes = [["a","b",1],["b","c",2],["a","c",3]] graph.make_weighted_from_list(nodes, directed=False) test_graph = { Node("a"):[Edge("a", "b",1), Edge("a","c",3)], Node("b"):[Edge("b","a",1), Edge("b","c",2)], Node("c"):[Edge("c","b",2), Edge("c","a",3)] } assert compare_graphs(test_graph, graph.graph) == True
def test_unweighted_list_of_int(): graph = Graph() nodes = [[1, 2], [2, 3], [3, 5], [5, 1], [2,5]] graph.make_unweighted_from_list(nodes) test_graph = { Node(1):[Edge(1,2)], Node(2):[Edge(2,3), Edge(2,5)], Node(3):[Edge(3,5)], Node(5):[Edge(5,1)]} assert compare_graphs(test_graph, graph.graph) == True
def test_unweighted_directed(): graph = Graph() nodes = [["a","b"],["b","c"],["a","c"]] graph.make_unweighted_from_list(nodes) test_graph = { Node("a"):[Edge("a","b"),Edge("a","c")], Node("b"):[Edge("b","c")], Node("c"):[] } assert compare_graphs(test_graph, graph.graph) == True
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 read_graph_file(filename: str) -> (Graph, [Vertex], [tuple]): """ Read a graph file from the class specified format. Args: * filename - Read in the file specified by filename Returns: A tuple that contains a graph object and two lists """ graph = Graph() verts = [] edges = [] is_weighted = None # Open up the file and parse the graph from text with open(filename, "r") as file: counter = 0 # Iterate through the file for line in file: # Obtain the type of graph if counter == 0: graph_type = line.strip() if graph_type == "G": graph = Graph() elif graph_type == "D": graph = Digraph() else: raise ValueError("Graph type not properly specified") # Obtain the verticies for the graph. elif counter == 1: for key in line.strip().split(","): verts.append(Vertex(key)) # Obtain all the edges. elif counter > 1: edge = line.strip("()\n").split(",") if is_weighted is None: is_weighted = bool(len(edge) == 3) elif is_weighted and len(edge) < 3: raise ValueError( "You specified an edge with weights and one without. You should only do one or the other." ) if len(edge) != 3 and len(edge) != 2: raise ValueError( f"You specified an incorrect amount of args for the edge: {line}" ) edges.append(edge) counter += 1 return graph, verts, edges
def test_unweighted_edges_set(): test_graph = { Node("a"):[Edge("a","b"),Edge("a","c")], Node("b"):[Edge("b","c")], Node("c"):[] } graph = Graph() nodes = [["a","b"],["b","c"],["a","c"]] graph.make_unweighted_from_list(nodes) for node in graph.graph: assert graph.graph[node] == test_graph[node.name]
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 append(self, dwg, prefix = '', **kwargs): if self.graph and dwg.graph: g = Graph() g.attach(None, (dwg.graph, "", None), merge=False) g.dotransform(**kwargs) self.graph.attach(None, (g, prefix, None), merge=False) if prefix: prefix += '.' for e in dwg.edges.items(): self.edges[prefix + e[0]] = e[1].copy() self.edges[prefix + e[0]].transform(**kwargs) return self
class Drawing: def __init__(self): """ Initializes an empty dictionary to contain Edge instances. Keys will be Edge labels as strings. Key values will be Edge instances. """ self.edges = {} self.graph = Graph() def toDXF(self, filename, labels=False, mode="dxf"): from dxfwrite import DXFEngine as dxf if mode == "dxf": from shapes import Rectangle self.append(Rectangle(12*25.4, 12*25.4, edgetype=Reg()), "outline") dwg = dxf.drawing(filename) for e in self.edges.items(): e[1].toDrawing(dwg, e[0] if labels else "", mode=mode, engine=dxf) dwg.save() if mode == "dxf": self.edges.pop("outline.e0") self.edges.pop("outline.e1") self.edges.pop("outline.e2") self.edges.pop("outline.e3") def toSVG(self, filename, labels=False, mode=None): """ Writes all Edge instances to a SVG file. @type svg: @param svg: @type label: tuple @param label: location of point two in the form (x2,y2). @type mode: @param mode: """ import svgwrite svg = svgwrite.Drawing(filename) for e in self.edges.items(): e[1].toDrawing(svg, e[0] if labels else "", mode) svg.save() def points(self): """ @return: a non-redundant list of all endpoints in tuples """ points = [] for e in self.edges.itervalues(): coords = e.coords() p1 = tuple(coords[0]) p2 = tuple(coords[1]) points.append(p1) points.append(p2) return list(set(points)) def edgeCoords(self): """ @return: a list of all Edge instance endpoints in Drawing (can include redundant points and edges) """ edges = [] for e in self.edges.items(): edges.append(e[1].coords()) return edges def renameedge(self, fromname, toname): """ Renames an Edge instance's Key @param fromname: string of the original Edge instance name @param toname: string of the new Edge instance name """ self.edges[toname] = self.edges.pop(fromname) self.edges[toname].name = toname if self.graph: self.graph.renameEdge(fromname, toname) return self def invertEdges(self): """ Swaps the mountain/valley folds on all Edge instances of Drawing @return: Drawing with the new Edge instances. """ for e in self.edges.values(): e.invert() if self.graph: self.graph.invertEdges() return self def transform(self, scale=1, angle=0, origin=(0,0), relative=None): """ Scales, rotates, and translates the Edge instances in Drawing @type scale: float @param scale: scaling factor @type angle: float @param angle: angle to rotate in radians @type origin: tuple @param origin: origin @return: Drawing with the new Edge instances. """ if relative is not None: pts = [x[0] for x in self.edgeCoords()] + [x[1] for x in self.edgeCoords()] xs = [x[0] for x in pts] ys = [x[1] for x in pts] minx = min(xs) maxx = max(xs) miny = min(ys) maxy = max(ys) midx = minx + relative[0]*(maxx + minx) midy = miny + relative[1]*(maxy + miny) origin=(origin[0] - midx, origin[1] - midy) for e in self.edges.values(): e.transform(scale=scale, angle=angle, origin=origin) if self.graph: self.graph.transform(scale=scale, angle=angle, origin=origin) return self def mirrorY(self): """ Changes the coordinates of Edge instances in Drawing so that they are symmetric about the X axis. @return: Drawing with the new Edge instances. """ for e in self.edges.values(): e.mirrorY() if self.graph: self.graph.mirrorY() return self def mirrorX(self): """ Changes the coordinates of Edge instances in Drawing so that they are symmetric about the Y axis. @return: Drawing with the new Edge instances. """ for e in self.edges.values(): e.mirrorX() if self.graph: self.graph.mirrorX() return self def flip(self): """ Flips the directionality of Edge instances om Drawing around. @return: Drawing with the new Edge instances. """ for e in self.edges.values(): e.flip() if self.graph: self.graph.flip() return self def append(self, dwg, prefix = '', **kwargs): if self.graph and dwg.graph: g = Graph() g.attach(None, (dwg.graph, "", None), merge=False) g.dotransform(**kwargs) self.graph.attach(None, (g, prefix, None), merge=False) if prefix: prefix += '.' for e in dwg.edges.items(): self.edges[prefix + e[0]] = e[1].copy() self.edges[prefix + e[0]].transform(**kwargs) return self def duplicate(self, prefix = ''): #Creates a duplicate copy of self. c = Drawing() if prefix: prefix += '.' for e in self.edges.items(): c.edges[prefix + e[0]] = e[1].copy() return c def attach(self, label1, dwg, label2, prefix, edgetype, useOrigName = False): # XXX TODO(mehtank): check to see if attachment edges match? # XXX TOTO(mehtank): make prefix optional? if isinstance(label1, (list, tuple)): l1 = label1[0] else: l1 = label1 label1 = [label1] if isinstance(label2, (list, tuple)): l2 = label2[0] else: l2 = label2 label2 = [label2] if self.graph and dwg.graph: angle = edgetype.angle if edgetype.edgetype in (EdgeType.FLAT, EdgeType.FLEX, EdgeType.FOLD): self.graph.attach(l1, (dwg.graph, prefix, l2), useOrigEdge=useOrigName, angle=angle) for i in range(1, len(label1)): self.graph.mergeEdge(label1[i], prefix + '.' + label2[i], useOrigEdge=useOrigName, angle=angle) else: print "Unknown edgetype for graph attach" #create a copy of the new drawing to be attached d = dwg.duplicate() #move the edge of the new drawing to be attached to the origin d.transform(origin=(-d.edges[l2].x2, -d.edges[l2].y2)) #don't rescale scale = 1 #find angle to rotate new drawing to align with old drawing edge phi = self.edges[l1].angle() angle = phi - d.edges[l2].angle() + pi #align edges offset by a separation of distance between the start points d.transform(scale=scale, angle=angle, origin=(self.edges[l1].coords()[0][0], self.edges[l1].coords()[0][1])) for e in d.edges.items(): if e[0] in label2: e[1].edgetype = edgetype if useOrigName: e[1].name = label1[label2.index(e[0])] self.edges[label1[label2.index(e[0])]] = e[1] else: self.edges.pop(label1[label2.index(e[0])]) e[1].name = prefix + '.' + e[0] self.edges[prefix + '.' + e[0]] = e[1] else: e[1].name = prefix + '.' + e[0] self.edges[prefix + '.' + e[0]] = e[1] def times(self, n, fromedge, toedge, label, mode): d = Drawing() d.append(self, label+'0') for i in range(1, n): d.attach(label+repr(i-1)+'.'+toedge, self, fromedge, label+repr(i), mode) return d
from graphs.graph import Graph from graphs.path import ShortestPath import random graph = Graph() lowers = "abcdefgh" for name in lowers: adj = set(random.sample(lowers, random.randint(0, 7))) ne = {a:[round(random.random()*10, 0), 1] for a in adj - {name}} graph.add_node(name, 0, **ne) # print(graph.nodes) # print(graph.edges) S = ShortestPath(graph) S.shortest_path('a', 'e') print(graph) print(S.edge_to)
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):
a[(s,t)].add(e) aa = dict() for (s,vs) in vertices: for (t,vt) in vertices: if graph.is_adjacent(s,t): 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")
from graphs.graph import Graph data = open("graph_data/PageRank_03.txt") graph = Graph("PageRank_03.txt") graph.create_graph_from_file(data) print( """ CSCI 5330 Spring 2016 Charles Arvey 900815172 """) graph.describe_graph()
class GraphTest(unittest.TestCase): V1_LABEL = 1 V2_LABEL = 2 V3_LABEL = 3 V4_LABEL = 4 V5_LABEL = 5 E1_LABEL = 1 E2_LABEL = 2 E3_LABEL = 3 if settings.INTEGER_VERTICES: v1 = 1 v2 = 2 v3 = 3 v4 = 4 v5 = 5 else: v1 = Vertex(V1_LABEL) v2 = Vertex(V2_LABEL) v3 = Vertex(V3_LABEL) v4 = Vertex(V4_LABEL) v5 = Vertex(V5_LABEL) e1 = Edge(E1_LABEL, v1, v2, 3) e2 = Edge(E2_LABEL, v2, v1, 5) e3 = Edge(E3_LABEL, v4, v5, 10) def setUp(self): self.g = Graph() def test_get_vertex(self): self.g.add_vertex(self.v1) self.assertEqual(self.g.get_vertex(self.V1_LABEL), self.v1) def test_get_edge_ends(self): self.assertTupleEqual(self.g.get_edge_ends(self.e1), (self.v1, self.v2)) def test_get_vertices_count(self): self.assertEqual(self.g.get_vertices_count(), 0) self.g.add_vertex(self.v1) self.assertEqual(self.g.get_vertices_count(), 1) self.g.add_vertex(self.v2) self.assertEqual(self.g.get_vertices_count(), 2) def test_get_vertex_position(self): if settings.INTEGER_VERTICES: return self.g.add_vertex(self.v1) self.g.add_vertex(self.v2) self.g.add_vertex(self.v3) self.assertEqual(self.g.get_vertex_position(self.v1), 0) self.assertEqual(self.g.get_vertex_position(self.v2), 1) self.assertEqual(self.g.get_vertex_position(self.v3), 2)
def setUp(self): self.g = Graph()