def complete_binary_tree(n: int = None, h: int = None, directed=False) -> Graph: """ Construct a perfect binary tree with n nodes/height of h. :param n: number of nodes :param h: height :param directed: directed edges :return: """ if n is None and h is None: raise ValueError('One of n and h must be not-null.') if n is None and h is not None: n = 2**(h + 1) - 1 if n == 0: return Graph([], []) # check n+1 is a power of two - 1 if not (n & (n + 1)) == 0: raise ValueError( 'Number of nodes not enough for a complete binary tree.') vertices: List[Vertex] = [Vertex(label=f'{i}', index=i) for i in range(n)] edges = [Edge(vertices[i], vertices[2 * i + 1]) for i in range(n // 2)] edges += [ Edge(vertices[i], vertices[2 * i + 2]) for i in range(n // 2 - 1) ] if directed: return Graph(vertices, edges, directed=True) edges += [Edge(vertices[2 * i + 1], vertices[i]) for i in range(n // 2)] edges += [ Edge(vertices[2 * i + 2], vertices[i]) for i in range(n // 2 - 1) ] return Graph(vertices, edges)
def test_vertex_adding(self): n = 100 g = Graph([], []) vertices = [Vertex(label=f'{i}', index=i) for i in range(n)] g.add_vertices(vertices) self.assertEqual(True, True)
def path_graph(n: int, directed=False) -> Graph: vertices: List[Vertex] = [Vertex(label=f'{i}', index=i) for i in range(n)] edges = [Edge(vertices[i], vertices[i + 1]) for i in range(n - 1)] if not directed: edges += [Edge(vertices[i], vertices[i - 1]) for i in range(1, n)] return Graph(vertices, edges, directed=directed)
def complete_graph(n: int, directed=False) -> Graph: vertices: List[Vertex] = [Vertex(label=f'{i}', index=i) for i in range(n)] if directed: edges = [Edge(v, i) for v, i in itertools.combinations(vertices, 2)] else: edges = [Edge(v, i) for v, i in itertools.permutations(vertices, 2)] return Graph(vertices, edges, directed=directed)
def graph_cartesian(g1: Graph, g2: Graph): # node labels are (v1,v2) vertices = [ Vertex(label=f'{v}', index=i) for i, v in enumerate(zip(g1.vertices, g2.vertices)) ] edges = [] return Graph(vertices=vertices, edges=edges)
def empty_graph(n: int = 0) -> Graph: """ Empty graph with or without vertices. :param n: (optional) number of vertices :return: """ vertices: List[Vertex] = [Vertex(label=f'{i}', index=i) for i in range(n)] return Graph(vertices, [])
def euler_graph(n: int, cycle=True) -> Graph: # TODO """ Create a random graph with an Euler path. :param n: number of vertices :param cycle: if True, there is also an Euler cycle in the graph. :return: """ vertices: List[Vertex] = [Vertex(label=f'{i}', index=i) for i in range(n)] v2 = random.choices(vertices, k=n) edges = [Edge(v, i) for v, i in zip(vertices, v2)]