Path: blob/master/src/sage/graphs/hypergraph_generators.py
8815 views
r"""1Hypergraph generators23At the moment this module only implement one method, which calls Brendan McKay's4Nauty (`<http://cs.anu.edu.au/~bdm/nauty/>`_) to enumerate hypergraphs up to5isomorphism.6"""78class HyperGraphGenerators():9r"""10A class consisting of constructors for common hypergraphs.11"""1213def nauty(self, number_of_sets, number_of_vertices,14multiple_sets = False,15vertex_min_degree = None, vertex_max_degree = None,16set_max_size = None, set_min_size = None,17regular = False, uniform = False,18max_intersection = None,19connected = False,20options="", debug=False):21r"""22Enumerates hypergraphs up to isomorphism using Nauty.2324INPUT:2526- ``number_of_sets``, ``number_of_vertices`` (integers)2728- ``multiple_sets`` (boolean) -- whether to allow several sets29of the hypergraph to be equal (set to ``False`` by default).3031- ``vertex_min_degree``, ``vertex_max_degree`` (integers) -- define the32maximum and minimum degree of an element from the ground set (i.e. the33number of sets which contain it). Set to ``None`` by default.3435- ``set_min_size``, ``set_max_size`` (integers) -- define the maximum36and minimum size of a set. Set to ``None`` by default.3738- ``regular`` (integer) -- if set to an integer value `k`, requires the39hypergraphs to be `k`-regular. It is actually a shortcut for the40corresponing min/max values.4142- ``uniform`` (integer) -- if set to an integer value `k`, requires the43hypergraphs to be `k`-uniform. It is actually a shortcut for the44corresponing min/max values.4546- ``max_intersection`` (integer) -- constraints the maximum cardinality47of the intersection of two sets fro the hypergraphs. Set to ``None``48by default.4950- ``connected`` (boolean) -- whether to require the hypergraphs to be51connected. Set to ``False`` by default.5253- ``debug`` (boolean) -- if ``True`` the first line of genbg's output to54standard error is captured and the first call to the generator's55``next()`` function will return this line as a string. A line leading56with ">A" indicates a successful initiation of the program with some57information on the arguments, while a line beginning with ">E"58indicates an error with the input.5960- ``options`` (string) -- anything else that should be forwarded as61input to Nauty's genbg. See its documentation for more information :62`<http://cs.anu.edu.au/~bdm/nauty/>`_.6364.. NOTE::6566For genbg the *first class* elements are vertices, and *second67class* elements are the hypergraph's sets.6869OUTPUT:7071A tuple of tuples.7273EXAMPLES:7475Small hypergraphs::7677sage: list(hypergraphs.nauty(4,2)) # optional - nauty78[((), (0,), (1,), (0, 1))]7980Only connected ones::8182sage: list(hypergraphs.nauty(2,2, connected = True)) # optional - nauty83[((0,), (0, 1))]8485Non-empty sets only::8687sage: list(hypergraphs.nauty(3,2, set_min_size = 1)) # optional - nauty88[((0,), (1,), (0, 1))]8990The Fano Plane, as the only 3-uniform hypergraph with 7 sets and 791vertices::9293sage: fano = hypergraphs.nauty(7,7, uniform = 3, max_intersection =1).next() # optional - nauty94sage: print fano # optional - nauty95((0, 1, 2), (0, 3, 4), (0, 5, 6), (1, 3, 5), (2, 4, 5), (2, 3, 6), (1, 4, 6))9697The Fano Plane, as the only 3-regular hypergraph with 7 sets and 798vertices::99100sage: fano = hypergraphs.nauty(7,7, regular = 3, max_intersection =1).next() # optional - nauty101sage: print fano # optional - nauty102((0, 1, 2), (0, 3, 4), (0, 5, 6), (1, 3, 5), (2, 4, 5), (2, 3, 6), (1, 4, 6))103"""104import subprocess105from sage.misc.package import is_package_installed106if not is_package_installed("nauty"):107raise TypeError("The optional nauty spkg does not seem to be installed")108109nauty_input = options110111if connected:112nauty_input += " -c"113114if not multiple_sets:115nauty_input += " -z"116117if not max_intersection is None:118nauty_input += " -Z"+str(max_intersection)119120# degrees and sizes121if not regular is False:122vertex_max_degree = vertex_min_degree = regular123if vertex_max_degree is None:124vertex_max_degree = number_of_sets125if vertex_min_degree is None:126vertex_min_degree = 0127128if not uniform is False:129set_max_size = set_min_size = uniform130if set_max_size is None:131set_max_size = number_of_vertices132if set_min_size is None:133set_min_size = 0134135nauty_input += " -d"+str(vertex_min_degree)+":"+str(set_min_size)136nauty_input += " -D"+str(vertex_max_degree)+":"+str(set_max_size)137138139nauty_input += " "+str(number_of_vertices) +" "+str(number_of_sets)+" "140141sp = subprocess.Popen("nauty-genbg {0}".format(nauty_input), shell=True,142stdin=subprocess.PIPE, stdout=subprocess.PIPE,143stderr=subprocess.PIPE, close_fds=True)144145if debug:146yield sp.stderr.readline()147148gen = sp.stdout149total = number_of_sets + number_of_vertices150while True:151try:152s = gen.next()153except StopIteration:154raise StopIteration("Exhausted list of graphs from nauty geng")155156from sage.graphs.graph import Graph157G = Graph(s[:-1], format='graph6')158159yield tuple( tuple( x for x in G.neighbors(v)) for v in range(number_of_vertices, total))160161hypergraphs = HyperGraphGenerators()162163164