def __init__(self, R, names=None): """ Initialize ``self``. TESTS:: sage: A = algebras.FreeDendriform(QQ, '@'); A Free Dendriform algebra on one generator ['@'] over Rational Field sage: TestSuite(A).run() # long time (3s) sage: F = algebras.FreeDendriform(QQ, 'xy') sage: TestSuite(F).run() # long time (3s) """ if names is None: Trees = BinaryTrees() key = BinaryTree._sort_key self._alphabet = Alphabet(['o']) else: Trees = LabelledBinaryTrees() key = LabelledBinaryTree._sort_key self._alphabet = names # Here one would need LabelledBinaryTrees(names) # so that one can restrict the labels to some fixed set cat = HopfAlgebras(R).WithBasis().Graded().Connected() CombinatorialFreeModule.__init__(self, R, Trees, latex_prefix="", sorting_key=key, category=cat)
def RandomBicubicPlanar(n): """ Return the graph of a random bipartite cubic map with `3 n` edges. INPUT: `n` -- an integer (at least `1`) OUTPUT: a graph with multiple edges (no embedding is provided) The algorithm used is described in [Schaeffer99]_. This samples a random rooted bipartite cubic map, chosen uniformly at random. First one creates a random binary tree with `n` vertices. Next one turns this into a blossoming tree (at random) and reads the contour word of this blossoming tree. Then one performs a rotation on this word so that this becomes a balanced word. There are three ways to do that, one is picked at random. Then a graph is build from the balanced word by iterated closure (adding edges). In the returned graph, the three edges incident to any given vertex are colored by the integers 0, 1 and 2. .. SEEALSO:: the auxiliary method :func:`blossoming_contour` EXAMPLES:: sage: n = randint(200, 300) sage: G = graphs.RandomBicubicPlanar(n) sage: G.order() == 2*n True sage: G.size() == 3*n True sage: G.is_bipartite() and G.is_planar() and G.is_regular(3) True sage: dic = {'red':[v for v in G.vertices() if v[0] == 'n'], ....: 'blue': [v for v in G.vertices() if v[0] != 'n']} sage: G.plot(vertex_labels=False,vertex_size=20,vertex_colors=dic) Graphics object consisting of ... graphics primitives .. PLOT:: :width: 300 px G = graphs.RandomBicubicPlanar(200) V0 = [v for v in G.vertices() if v[0] == 'n'] V1 = [v for v in G.vertices() if v[0] != 'n'] dic = {'red': V0, 'blue': V1} sphinx_plot(G.plot(vertex_labels=False,vertex_colors=dic)) REFERENCES: .. [Schaeffer99] Gilles Schaeffer, *Random Sampling of Large Planar Maps and Convex Polyhedra*, Annual ACM Symposium on Theory of Computing (Atlanta, GA, 1999) """ from sage.combinat.binary_tree import BinaryTrees from sage.rings.finite_rings.integer_mod_ring import Zmod if not n: raise ValueError("n must be at least 1") # first pick a random binary tree t = BinaryTrees(n).random_element() # next pick a random blossoming of this tree, compute its contour contour = blossoming_contour(t) + [('xb', )] # adding the final xb # first step : rotate the contour word to one of 3 balanced N = len(contour) double_contour = contour + contour pile = [] not_touched = [i for i in range(N) if contour[i][0] in ['x', 'xb']] for i, w in enumerate(double_contour): if w[0] == 'x' and i < N: pile.append(i) elif w[0] == 'xb' and (i % N) in not_touched: if pile: j = pile.pop() not_touched.remove(i % N) not_touched.remove(j) # random choice among 3 possibilities for a balanced word idx = not_touched[randint(0, 2)] w = contour[idx + 1:] + contour[:idx + 1] # second step : create the graph by closure from the balanced word G = Graph(multiedges=True) pile = [] Z3 = Zmod(3) colour = Z3.zero() not_touched = [i for i, v in enumerate(w) if v[0] in ['x', 'xb']] for i, v in enumerate(w): # internal edges if v[0] == 'i': colour += 1 if w[i + 1][0] == 'n': G.add_edge((w[i], w[i + 1], colour)) elif v[0] == 'n': colour += 2 elif v[0] == 'x': pile.append(i) elif v[0] == 'xb' and i in not_touched: if pile: j = pile.pop() G.add_edge((w[i + 1], w[j - 1], colour)) not_touched.remove(i) not_touched.remove(j) # there remains to add three edges to elements of "not_touched" # from a new vertex labelled "n" for i in not_touched: taken_colours = [edge[2] for edge in G.edges_incident(w[i - 1])] colour = [u for u in Z3 if u not in taken_colours][0] G.add_edge((('n', -1), w[i - 1], colour)) return G