def irreducible_component_index_sets(self):
            r"""
            Return a list containing the index sets of the irreducible components of
            ``self`` as finite reflection groups.

            EXAMPLES::

                sage: W = ReflectionGroup([1,1,3], [3,1,3], 4); W       # optional - gap3
                Reducible complex reflection group of rank 7 and type A2 x G(3,1,3) x ST4
                sage: sorted(W.irreducible_component_index_sets())      # optional - gap3
                [[1, 2], [3, 4, 5], [6, 7]]

            ALGORITHM:

                Take the connected components of the graph on the
                index set with edges (i,j) where s[i] and s[j] don't
                commute.
            """
            I = self.index_set()
            s = self.simple_reflections()
            from sage.graphs.graph import Graph
            G = Graph([I,
                       [[i,j]
                        for i,j in itertools.combinations(I,2)
                        if s[i]*s[j] != s[j]*s[i] ]],
                      format="vertices_and_edges")
            return G.connected_components()
Exemplo n.º 2
0
    def coxeter_diagram(self):
        """
        Returns a Coxeter diagram for type H.

        EXAMPLES::

             sage: ct = CartanType(['H',3])
             sage: ct.coxeter_diagram()
             Graph on 3 vertices
             sage: sorted(ct.coxeter_diagram().edges())
             [(1, 2, 3), (2, 3, 5)]
             sage: ct.coxeter_matrix()
             [1 3 2]
             [3 1 5]
             [2 5 1]

             sage: ct = CartanType(['H',4])
             sage: ct.coxeter_diagram()
             Graph on 4 vertices
             sage: sorted(ct.coxeter_diagram().edges())
             [(1, 2, 3), (2, 3, 3), (3, 4, 5)]
             sage: ct.coxeter_matrix()
             [1 3 2 2]
             [3 1 3 2]
             [2 3 1 5]
             [2 2 5 1]
        """
        from sage.graphs.graph import Graph
        n = self.n
        g = Graph(multiedges=False)
        for i in range(1, n):
            g.add_edge(i, i+1, 3)
        g.set_edge_label(n-1, n, 5)
        return g
Exemplo n.º 3
0
    def __classcall_private__(cls, G):
        """
        Normalize input to ensure a unique representation.

        TESTS::

            sage: G1 = RightAngledArtinGroup(graphs.CycleGraph(5))
            sage: Gamma = Graph([(0,1),(1,2),(2,3),(3,4),(4,0)])
            sage: G2 = RightAngledArtinGroup(Gamma)
            sage: G3 = RightAngledArtinGroup([(0,1),(1,2),(2,3),(3,4),(4,0)])
            sage: G1 is G2 and G2 is G3
            True

        Handle the empty graph::

            sage: RightAngledArtinGroup(Graph())
            Traceback (most recent call last):
            ...
            ValueError: the graph must not be empty
        """
        if not isinstance(G, Graph):
            G = Graph(G, immutable=True)
        else:
            G = G.copy(immutable=True)
        if G.num_verts() == 0:
            raise ValueError("the graph must not be empty")
        return super(RightAngledArtinGroup, cls).__classcall__(cls, G)
Exemplo n.º 4
0
 def hamiltonian_cycle(self, algorithm = "tsp", *largs, **kargs):
     store = lookup(kargs, "store", default = discretezoo.WRITE_TO_DB,
                    destroy = True)
     cur = lookup(kargs, "cur", default = None, destroy = True)
     default = len(largs) + len(kargs) == 0 and \
         algorithm in ["tsp", "backtrack"]
     if default:
         if algorithm == "tsp":
             try:
                 out = Graph.hamiltonian_cycle(self, algorithm, *largs,
                                               **kargs)
                 h = True
             except EmptySetError as out:
                 h = False
         elif algorithm == "backtrack":
             out = Graph.hamiltonian_cycle(self, algorithm, *largs, **kargs)
             h = out[0]
         try:
             lookup(self._graphprops, "is_hamiltonian")
         except KeyError:
             if store:
                 self._update_rows(ZooGraph, {"is_hamiltonian": h},
                                   {self._spec["primary_key"]: self._zooid},
                                   cur = cur)
             update(self._graphprops, "is_hamiltonian", h)
         if isinstance(out, BaseException):
             raise out
         else:
             return out
     else:
         return Graph.hamiltonian_cycle(self, algorithm, *largs, **kargs)
Exemplo n.º 5
0
    def edge_coloring(self):
        r"""
        Compute a proper edge-coloring.

        A proper edge-coloring is an assignment of colors to the sets of the
        incidence structure such that two sets with non-empty intersection
        receive different colors. The coloring returned minimizes the number of
        colors.

        OUTPUT:

        A partition of the sets into color classes.

        EXAMPLES::

            sage: H = Hypergraph([{1,2,3},{2,3,4},{3,4,5},{4,5,6}]); H
            Incidence structure with 6 points and 4 blocks
            sage: C = H.edge_coloring()
            sage: C # random
            [[[3, 4, 5]], [[2, 3, 4]], [[4, 5, 6], [1, 2, 3]]]
            sage: Set(map(Set,sum(C,[]))) == Set(map(Set,H.blocks()))
            True
        """
        from sage.graphs.graph import Graph
        blocks = self.blocks()
        blocks_sets = map(frozenset,blocks)
        g = Graph([range(self.num_blocks()),lambda x,y : len(blocks_sets[x]&blocks_sets[y])],loops = False)
        return [[blocks[i] for i in C] for C in g.coloring(algorithm="MILP")]
Exemplo n.º 6
0
def CompleteMultipartiteGraph(l):
    r"""
    Returns a complete multipartite graph.

    INPUT:

    - ``l`` -- a list of integers : the respective sizes
      of the components.

    EXAMPLE:

    A complete tripartite graph with sets of sizes
    `5, 6, 8`::

        sage: g = graphs.CompleteMultipartiteGraph([5, 6, 8]); g
        Multipartite Graph with set sizes [5, 6, 8]: Graph on 19 vertices

    It clearly has a chromatic number of 3::

        sage: g.chromatic_number()
        3
    """
    g = Graph()
    for i in l:
        g = g + CompleteGraph(i)

    g = g.complement()
    g.name("Multipartite Graph with set sizes "+str(l))

    return g
Exemplo n.º 7
0
    def coxeter_diagram(self):
        """
        Return the Coxeter diagram for ``self``.

        EXAMPLES::

            sage: cd = CartanType("A2xB2xF4").coxeter_diagram()
            sage: cd
            Graph on 8 vertices
            sage: cd.edges()
            [(1, 2, 3), (3, 4, 4), (5, 6, 3), (6, 7, 4), (7, 8, 3)]

            sage: CartanType("F4xA2").coxeter_diagram().edges()
            [(1, 2, 3), (2, 3, 4), (3, 4, 3), (5, 6, 3)]

            sage: cd = CartanType("A1xH3").coxeter_diagram(); cd
            Graph on 4 vertices
            sage: cd.edges()
            [(2, 3, 3), (3, 4, 5)]
        """
        from sage.graphs.graph import Graph
        relabelling = self._index_relabelling
        g = Graph(multiedges=False)
        g.add_vertices(self.index_set())
        for i,t in enumerate(self._types):
            for [e1, e2, l] in t.coxeter_diagram().edges():
                g.add_edge(relabelling[i,e1], relabelling[i,e2], label=l)
        return g
Exemplo n.º 8
0
    def to_bipartite_graph(self, with_partition=False):
        r"""
        Returns the associated bipartite graph

        INPUT:

        - with_partition -- boolean (default: False)

        OUTPUT:

        - a graph or a pair (graph, partition)

        EXAMPLES::

            sage: H = designs.steiner_triple_system(7).blocks()
            sage: H = Hypergraph(H)
            sage: g = H.to_bipartite_graph(); g
            Graph on 14 vertices
            sage: g.is_regular()
            True
        """
        from sage.graphs.graph import Graph

        G = Graph()
        domain = list(self.domain())
        G.add_vertices(domain)
        for s in self._sets:
            for i in s:
                G.add_edge(s, i)
        if with_partition:
            return (G, [domain, list(self._sets)])
        else:
            return G
Exemplo n.º 9
0
    def cluster_in_box(self, m, pt=None):
        r"""
        Return the cluster (as a list) in the primal box [-m,m]^d
        containing the point pt.

        INPUT:

        - ``m`` - integer
        - ``pt`` - tuple, point in Z^d. If None, pt=zero is considered.

        EXAMPLES::

            sage: from slabbe import BondPercolationSample
            sage: S = BondPercolationSample(0.3,2)
            sage: S.cluster_in_box(2)         # random
            [(-2, -2), (-2, -1), (-1, -2), (-1, -1), (-1, 0), (0, 0)]
        """
        G = Graph()
        G.add_edges(self.edges_in_box(m))
        if pt is None:
            pt = self.zero()
        if pt in G:
            return G.connected_component_containing_vertex(pt)
        else:
            return []
Exemplo n.º 10
0
    def edge_coloring(self):
        r"""
        Compute a proper edge-coloring.

        A proper edge-coloring is an assignment of colors to the sets of the
        hypergraph such that two sets with non-empty intersection receive
        different colors. The coloring returned minimizes the number of colors.

        OUTPUT:

        A partition of the sets into color classes.

        EXAMPLES::

            sage: H = Hypergraph([{1,2,3},{2,3,4},{3,4,5},{4,5,6}]); H
            Hypergraph on 6 vertices containing 4 sets
            sage: C = H.edge_coloring()
            sage: C # random
            [[{3, 4, 5}], [{4, 5, 6}, {1, 2, 3}], [{2, 3, 4}]]
            sage: Set(sum(C,[])) == Set(H._sets)
            True
        """
        from sage.graphs.graph import Graph
        g = Graph([self._sets,lambda x,y : len(x&y)],loops = False)
        return g.coloring(algorithm="MILP")
Exemplo n.º 11
0
    def coxeter_graph(self):
        """
        Return the Coxeter graph of ``self``.

        EXAMPLES::

            sage: C = CoxeterMatrix(['A',3])
            sage: C.coxeter_graph()
            Graph on 3 vertices

            sage: C = CoxeterMatrix([['A',3],['A',1]])
            sage: C.coxeter_graph()
            Graph on 4 vertices
        """
        n = self.rank()
        I = self.index_set()
        val = lambda x: infinity if x == -1 else x
        G = Graph(
            [
                (I[i], I[j], val((self._matrix)[i, j]))
                for i in range(n)
                for j in range(i)
                if self._matrix[i, j] not in [1, 2]
            ]
        )
        G.add_vertices(I)
        return G.copy(immutable=True)
Exemplo n.º 12
0
    def to_undirected_graph(self):
        r"""
        Return the undirected graph obtained from the tree nodes and edges.

        The graph is endowed with an embedding, so that it will be displayed
        correctly.

        EXAMPLES::

            sage: t = OrderedTree([])
            sage: t.to_undirected_graph()
            Graph on 1 vertex
            sage: t = OrderedTree([[[]],[],[]])
            sage: t.to_undirected_graph()
            Graph on 5 vertices

        If the tree is labelled, we use its labelling to label the graph. This
        will fail if the labels are not all distinct.
        Otherwise, we use the graph canonical labelling which means that
        two different trees can have the same graph.

        EXAMPLES::

            sage: t = OrderedTree([[[]],[],[]])
            sage: t.canonical_labelling().to_undirected_graph()
            Graph on 5 vertices

        TESTS::

            sage: t.canonical_labelling().to_undirected_graph() == t.to_undirected_graph()
            False
            sage: OrderedTree([[],[]]).to_undirected_graph() == OrderedTree([[[]]]).to_undirected_graph()
            True
            sage: OrderedTree([[],[],[]]).to_undirected_graph() == OrderedTree([[[[]]]]).to_undirected_graph()
            False
        """
        from sage.graphs.graph import Graph
        g = Graph()
        if self in LabelledOrderedTrees():
            relabel = False
        else:
            self = self.canonical_labelling()
            relabel = True
        roots = [self]
        g.add_vertex(name=self.label())
        emb = {self.label(): []}
        while roots:
            node = roots.pop()
            children = reversed([child.label() for child in node])
            emb[node.label()].extend(children)
            for child in node:
                g.add_vertex(name=child.label())
                emb[child.label()] = [node.label()]
                g.add_edge(child.label(), node.label())
                roots.append(child)
        g.set_embedding(emb)
        if relabel:
            g = g.canonical_label()
        return g
Exemplo n.º 13
0
def import_graphs(file, cl = ZooGraph, db = None, format = "sparse6",
                  index = "index", verbose = False):
    r"""
    Import graphs from ``file`` into the database.

    This function is used to import new censuses of graphs and is not meant
    to be used by users of DiscreteZOO.

    To properly import the graphs, all graphs of the same order must be
    together in the file, and no graph of this order must be present in the
    database.

    INPUT:

    - ``file`` - the filename containing a graph in each line.

    - ``cl`` - the class to be used for imported graphs
      (default: ``ZooGraph``).

    - ``db`` - the database to import into. The default value of ``None`` means
      that the default database should be used.

    - ``format`` - the format the graphs are given in. If ``format`` is
      ``'graph6'`` or ``'sparse6'`` (default), then the graphs are read as
      strings, otherwised they are evaluated as Python expressions before
      being passed to Sage's ``Graph``.

    - ``index``: the name of the parameter of the constructor of ``cl``
      to which the serial number of the graph of a given order is passed.

    - ``verbose``: whether to print information about the progress of importing
      (default: ``False``).
    """
    info = ZooInfo(cl)
    if db is None:
        db = info.getdb()
    info.initdb(db = db, commit = False)
    previous = 0
    i = 0
    cur = db.cursor()
    with open(file) as f:
        for line in f:
            data = line.strip()
            if format not in ["graph6", "sparse6"]:
                data = eval(data)
            g = Graph(data)
            n = g.order()
            if n > previous:
                if verbose and previous > 0:
                    print "Imported %d graphs of order %d" % (i, previous)
                previous = n
                i = 0
            i += 1
            cl(graph = g, order = n, cur = cur, db = db, **{index: i})
        if verbose:
            print "Imported %d graphs of order %d" % (i, n)
        f.close()
    cur.close()
    db.commit()
Exemplo n.º 14
0
 def create_graph_from_model(self, solver, model):
     """
     Given a model from the SAT solver, construct the graph.
     """
     g = Graph()
     on_vertices = solver.get_objects_in_model(model, self, self.internal_graph.vertices())
     on_edges = solver.get_objects_in_model(model, self, self.internal_graph.edges(labels=False))
     g.add_vertices(on_vertices)
     g.add_edges(on_edges)
     return g
Exemplo n.º 15
0
    def coxeter_graph(self):
        """
        Return the Coxeter graph of ``self``.

        EXAMPLES::

            sage: W = CoxeterGroup(['H',3], implementation="reflection")
            sage: G = W.coxeter_graph(); G
            Graph on 3 vertices
            sage: G.edges()
            [(1, 2, None), (2, 3, 5)]
            sage: CoxeterGroup(G) is W
            True
            sage: G = Graph([(0, 1, 3), (1, 2, oo)])
            sage: W = CoxeterGroup(G)
            sage: W.coxeter_graph() == G
            True
            sage: CoxeterGroup(W.coxeter_graph()) is W
            True
        """
        G = Graph()
        G.add_vertices(self.index_set())
        for i, row in enumerate(self._matrix.rows()):
            for j, val in enumerate(row[i + 1 :]):
                if val == 3:
                    G.add_edge(self._index_set[i], self._index_set[i + 1 + j])
                elif val > 3:
                    G.add_edge(self._index_set[i], self._index_set[i + 1 + j], val)
                elif val == -1:  # FIXME: Hack because there is no ZZ\cup\{\infty\}
                    G.add_edge(self._index_set[i], self._index_set[i + 1 + j], infinity)
        return G
Exemplo n.º 16
0
def CircularLadderGraph(n):
    """
    Returns a circular ladder graph with 2\*n nodes.

    A Circular ladder graph is a ladder graph that is connected at the
    ends, i.e.: a ladder bent around so that top meets bottom. Thus it
    can be described as two parallel cycle graphs connected at each
    corresponding node pair.

    This constructor depends on NetworkX numeric labels.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, the circular
    ladder graph is displayed as an inner and outer cycle pair, with
    the first n nodes drawn on the inner circle. The first (0) node is
    drawn at the top of the inner-circle, moving clockwise after that.
    The outer circle is drawn with the (n+1)th node at the top, then
    counterclockwise as well.

    EXAMPLES: Construct and show a circular ladder graph with 26 nodes

    ::

        sage: g = graphs.CircularLadderGraph(13)
        sage: g.show() # long time

    Create several circular ladder graphs in a Sage graphics array

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:    k = graphs.CircularLadderGraph(i+3)
        ....:    g.append(k)
        sage: for i in range(3):
        ....:    n = []
        ....:    for m in range(3):
        ....:        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
        ....:    j.append(n)
        sage: G = sage.plot.graphics.GraphicsArray(j)
        sage: G.show() # long time
    """
    pos_dict = {}
    for i in range(n):
        x = float(cos((pi/2) + ((2*pi)/n)*i))
        y = float(sin((pi/2) + ((2*pi)/n)*i))
        pos_dict[i] = [x,y]
    for i in range(n,2*n):
        x = float(2*(cos((pi/2) + ((2*pi)/n)*(i-n))))
        y = float(2*(sin((pi/2) + ((2*pi)/n)*(i-n))))
        pos_dict[i] = (x,y)

    G = Graph(pos=pos_dict, name="Circular Ladder graph")
    G.add_vertices( range(2*n) )
    G.add_cycle( range(n) )
    G.add_cycle( range(n,2*n) )
    G.add_edges( (i,i+n) for i in range(n) )
    return G
Exemplo n.º 17
0
    def __init__(
        self, data=None, zooid=None, props=None, graph=None, vertex_labels=None, name=None, cur=None, db=None, **kargs
    ):
        ZooObject.__init__(self, db)
        kargs["immutable"] = True
        kargs["data_structure"] = "static_sparse"
        if isinteger(data):
            zooid = Integer(data)
            data = None
        elif isinstance(data, GenericGraph):
            graph = data
            data = None
        elif isinstance(data, dict):
            props = data
            data = None
        if props is not None:
            if "id" in props:
                zooid = props["id"]
            if "data" in props:
                data = props["data"]
            props = {k: v for k, v in props.items() if k not in ["id", "data"]}

        if graph is not None:
            if not isinstance(graph, GenericGraph):
                raise TypeError("not a graph")
            data = graph
            if name is None:
                name = graph.name()
            if isinstance(graph, ZooGraph):
                zooid = graph._zooid
                self._props = graph._props
            if cur is not None:
                if self._props is None:
                    self._props = {}
                self._props["diameter"] = graph.diameter()
                self._props["girth"] = graph.girth()
                self._props["order"] = graph.order()
            elif zooid is None:
                raise IndexError("graph id not given")
        else:
            cur = None
            if props is not None:
                self._props = self._todict(props, skip=ZooGraph._spec["skip"], fields=ZooGraph._spec["fields"])

        self._zooid = zooid
        if data is None:
            data = self._db_read()["data"]
        if vertex_labels is not None:
            data = Graph(data).relabel(vertex_labels, inplace=False)
        Graph.__init__(self, data=data, name=name, **kargs)
        if cur is not None:
            self._db_write(cur)
Exemplo n.º 18
0
def _polar_graph(m, q, g, intersection_size=None):
    r"""
    The helper function to build graphs `(D)U(m,q)` and `(D)Sp(m,q)`

    Building a graph on an orbit of a group `g` of `m\times m` matrices over `GF(q)` on
    the points (or subspaces of dimension ``m//2``) isotropic w.r.t. the form `F`
    left invariant by the group `g`.

    The only constraint is that the first ``m//2`` elements of the standard
    basis must generate a totally isotropic w.r.t. `F` subspace; this is the case with
    these groups coming from GAP; namely, `F` has the anti-diagonal all-1 matrix.

    INPUT:

    - ``m`` -- the dimension of the underlying vector space

    - ``q`` -- the size of the field

    - ``g`` -- the group acting

    - ``intersection_size`` -- if ``None``, build the graph on the isotropic points, with
      adjacency being orthogonality w.r.t. `F`. Otherwise, build the graph on the maximal
      totally isotropic subspaces, with adjacency specified by ``intersection_size`` being
      as given.

    TESTS::

        sage: from sage.graphs.generators.classical_geometries import _polar_graph
        sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2))
        Graph on 45 vertices
        sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2), intersection_size=1)
        Graph on 27 vertices
    """
    from sage.libs.gap.libgap import libgap
    from itertools import combinations
    W=libgap.FullRowSpace(libgap.GF(q), m)  # F_q^m
    B=libgap.Elements(libgap.Basis(W))      # the standard basis of W
    V = libgap.Orbit(g,B[0],libgap.OnLines) # orbit on isotropic points
    gp = libgap.Action(g,V,libgap.OnLines)  # make a permutation group
    s = libgap.Subspace(W,[B[i] for i in range(m//2)]) # a totally isotropic subspace
    # and the points there
    sp = [libgap.Elements(libgap.Basis(x))[0] for x in libgap.Elements(s.Subspaces(1))]
    h = libgap.Set(map(lambda x: libgap.Position(V, x), sp)) # indices of the points in s
    L = libgap.Orbit(gp, h, libgap.OnSets) # orbit on these subspaces
    if intersection_size == None:
        G = Graph()
        for x in L: # every pair of points in the subspace is adjacent to each other in G
            G.add_edges(combinations(x, 2))
        return G
    else:
        return Graph([L, lambda i,j: libgap.Size(libgap.Intersection(i,j))==intersection_size],
                        loops=False)
Exemplo n.º 19
0
def CayleyGraph(vspace, gens, directed=False):
  """
  Generate a Cayley Graph over given vector space with edges
  generated by given generators. The graph is optionally directed.
  Try e.g. CayleyGraph(VectorSpace(GF(2), 3), [(1,0,0), (0,1,0), (0,0,1)])
  """
  G = Graph()
  for v in vspace:
    G.add_vertex(tuple(v))
    for g in gens:
      g2 = vspace(g)
      G.add_edge(tuple(v), tuple(v + g2))
  return G
Exemplo n.º 20
0
def graph6_to_plot(graph6):
    """
    Constructs a graph from a graph6 string and returns a Graphics
    object with arguments preset for show function.

    EXAMPLE::

        sage: from sage.graphs.graph_database import graph6_to_plot
        sage: type(graph6_to_plot('D??'))
        <class 'sage.plot.graphics.Graphics'>
    """
    g = Graph(str(graph6))
    return g.plot(layout='circular',vertex_size=30,vertex_labels=False,graph_border=False)
Exemplo n.º 21
0
def IntersectionGraph(S):
    r"""
    Returns the intersection graph of the family `S`

    The intersection graph of a family `S` is a graph `G` with `V(G)=S` such
    that two elements `s_1,s_2\in S` are adjacent in `G` if and only if `s_1\cap
    s_2\neq \emptyset`.

    INPUT:

    - ``S`` -- a list of sets/tuples/iterables

        .. NOTE::

            The elements of `S` must be finite, hashable, and the elements of
            any `s\in S` must be hashable too.

    EXAMPLE::

        sage: graphs.IntersectionGraph([(1,2,3),(3,4,5),(5,6,7)])
        Intersection Graph: Graph on 3 vertices

    TESTS::

        sage: graphs.IntersectionGraph([(1,2,[1])])
        Traceback (most recent call last):
        ...
        TypeError: The elements of S must be hashable, and this one is not: (1, 2, [1])
    """
    from itertools import combinations

    for s in S:
        try:
            hash(s)
        except TypeError:
            raise TypeError("The elements of S must be hashable, and this one is not: {}".format(s))

    ground_set_to_sets = {}
    for s in S:
        for x in s:
            if x not in ground_set_to_sets:
                ground_set_to_sets[x] = []
            ground_set_to_sets[x].append(s)

    g = Graph(name="Intersection Graph")
    g.add_vertices(S)
    for clique in ground_set_to_sets.itervalues():
        g.add_edges((u,v) for u,v in combinations(clique,2))

    return g
Exemplo n.º 22
0
 def is_regular(self, k = None, *largs, **kargs):
     store = lookup(kargs, "store", default = discretezoo.WRITE_TO_DB,
                    destroy = True)
     cur = lookup(kargs, "cur", default = None, destroy = True)
     default = len(largs) + len(kargs) == 0
     try:
         if not default:
             raise NotImplementedError
         r = lookup(self._graphprops, "is_regular")
         return r and (True if k is None
                       else k == self.average_degree(store = store,
                                                     cur = cur))
     except (KeyError, NotImplementedError):
         r = Graph.is_regular(self, k, *largs, **kargs)
         if default:
             if store:
                 row = {"is_regular": r}
                 if r and k is not None:
                     row["average_degree"] = k
                 self._update_rows(ZooGraph, row,
                                   {self._spec["primary_key"]: self._zooid},
                                   cur = cur)
             update(self._graphprops, "is_regular", r)
             if r and k is not None:
                 update(self._graphprops, "average_degree", k)
         return r
Exemplo n.º 23
0
    def _spring_layout(self):
        r"""
        Return a spring layout for the vertices.

        The layout is computed by creating a graph `G` on the vertices *and*
        sets of the hypergraph. Each set is then made adjacent in `G` with all
        vertices it contains before a spring layout is computed for this
        graph. The position of the vertices in the hypergraph is the position of
        the same vertices in the graph's layout.

        .. NOTE::

            This method also returns the position of the "fake" vertices,
            i.e. those representing the sets.

        EXAMPLES::

            sage: H = Hypergraph([{1,2,3},{2,3,4},{3,4,5},{4,5,6}]); H
            Hypergraph on 6 vertices containing 4 sets
            sage: L = H._spring_layout()
            sage: L # random
            {1: (0.238, -0.926),
             2: (0.672, -0.518),
             3: (0.449, -0.225),
             4: (0.782, 0.225),
             5: (0.558, 0.518),
             6: (0.992, 0.926),
             {3, 4, 5}: (0.504, 0.173),
             {2, 3, 4}: (0.727, -0.173),
             {4, 5, 6}: (0.838, 0.617),
             {1, 2, 3}: (0.393, -0.617)}
            sage: all(v in L for v in H.domain())
            True
            sage: all(v in L for v in H._sets)
            True
        """
        from sage.graphs.graph import Graph

        g = Graph()
        for s in self._sets:
            for x in s:
                g.add_edge(s,x)

        _ = g.plot(iterations = 50000,save_pos=True)

        # The values are rounded as TikZ does not like accuracy.
        return {k:(round(x,3),round(y,3)) for k,(x,y) in g.get_pos().items()}
Exemplo n.º 24
0
def LadderGraph(n):
    """
    Returns a ladder graph with 2\*n nodes.

    A ladder graph is a basic structure that is typically displayed as
    a ladder, i.e.: two parallel path graphs connected at each
    corresponding node pair.

    This constructor depends on NetworkX numeric labels.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, each ladder
    graph will be displayed horizontally, with the first n nodes
    displayed left to right on the top horizontal line.

    EXAMPLES: Construct and show a ladder graph with 14 nodes

    ::

        sage: g = graphs.LadderGraph(7)
        sage: g.show() # long time

    Create several ladder graphs in a Sage graphics array

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     k = graphs.LadderGraph(i+2)
        ....:     g.append(k)
        sage: for i in range(3):
        ....:     n = []
        ....:     for m in range(3):
        ....:         n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
        ....:     j.append(n)
        sage: G = sage.plot.graphics.GraphicsArray(j)
        sage: G.show() # long time
    """
    pos_dict = {}
    for i in range(n):
        pos_dict[i] = (i,1)
    for i in range(n,2*n):
        x = i - n
        pos_dict[i] = (x,0)
    G = Graph(pos=pos_dict, name="Ladder graph")
    G.add_vertices( range(2*n) )
    G.add_path( range(n) )
    G.add_path( range(n,2*n) )
    G.add_edges( (i,i+n) for i in range(n) )
    return G
Exemplo n.º 25
0
def read_mtx(f):
    contents = f.readlines()
    edges = []
    first = 0
    for i in range(len(contents)):
        words = contents[i].split()
        if words[0][0] != '%':
            if first == 0:
                first = 1
            else:
                if(len(words) == 3):
                    edges.append((int(words[0]), int(words[1]), float(words[2])))
                else:
                    edges.append((int(words[0]), int(words[1]), None))

    g = Graph()
    g.add_edges(edges)
    return g
Exemplo n.º 26
0
 def relabel(self, perm = None, inplace = True, return_map = False,
             check_input = True, complete_partial_function = True,
             immutable = True):
     r"""
     This method has been overridden by DiscreteZOO to ensure that a mutable
     copy will have type ``Graph``.
     """
     if inplace:
         raise ValueError("To relabel an immutable graph use inplace=False")
     G = Graph(self, immutable = False)
     perm = G.relabel(perm, return_map = True, check_input = check_input,
                      complete_partial_function = complete_partial_function)
     if immutable is not False:
         G = self.__class__(self, vertex_labels = perm)
     if return_map:
         return G, perm
     else:
         return G
Exemplo n.º 27
0
Arquivo: raag.py Projeto: Babyll/sage
    def __init__(self, G):
        """
        Initialize ``self``.

        INPUT:

        - ``G`` -- a graph

        TESTS::

            sage: G = RightAngledArtinGroup(graphs.CycleGraph(5))
            sage: TestSuite(G).run()
        """
        self._graph = G
        F = FreeGroup(names=['v{}'.format(v) for v in self._graph.vertices()])
        CG = Graph(G).complement() # Make sure it's mutable
        CG.relabel() # Standardize the labels
        rels = tuple(F([i+1, j+1, -i-1, -j-1]) for i,j in CG.edges(False)) #+/- 1 for indexing
        FinitelyPresentedGroup.__init__(self, F, rels)
Exemplo n.º 28
0
def second_dist_to_set(G, v, W):
  """
  For vertices adjacent to W, return the lenght of the second shortest
  path to W. Otherwise return G.order(). WARNING: Not very efficient.
  """
  if v in W:
    return 0
  # Neighbors in W 
  nw = set(G.neighbors(v)).intersection(set(W))
  if len(nw) == 0:
    return G.order()
  if len(nw) >= 2:
    return 1
  G2 = Graph(G) # always undirected, copy
  G2.delete_edge(v, nw.pop())
  ds2 = G2.distance_all_pairs()
  dist2 = min([ds2[v][u] for u in W])
  assert dist2 >= 2
  return dist2
Exemplo n.º 29
0
def underlying_graph(G):
    r"""
    Given a graph `G` with multi-edges, returns a graph where all the
    multi-edges are replaced with a single edge.

    EXAMPLES::

        sage: from sage.graphs.tutte_polynomial import underlying_graph
        sage: G = Graph(multiedges=True)
        sage: G.add_edges([(0,1,'a'),(0,1,'b')])
        sage: G.edges()
        [(0, 1, 'a'), (0, 1, 'b')]
        sage: underlying_graph(G).edges()
        [(0, 1, None)]
    """
    g = Graph()
    g.allow_loops(True)
    for edge in set(G.edges(labels=False)):
        g.add_edge(edge)
    return g
Exemplo n.º 30
0
 def _graphattr(store=False, *largs, **kargs):
     default = len(largs) + len(kargs) == 0
     try:
         if not default:
             raise NotImplementedError
         return lookup(self._props, name)
     except (KeyError, NotImplementedError):
         a = Graph.__getattribute__(self, name)(*largs, **kargs)
         if default and store:
             update(self._props, attr, d)
         return a
Exemplo n.º 31
0
def _spanning_tree(base, verts):
    graph = Graph([list(verts), lambda x, y: x is not y])

    def length(edge):
        x, y, _ = edge
        return abs(CC(x.value) - CC(y.value))

    tree = graph.min_spanning_tree(length)
    tree = Graph(tree)
    tree.add_vertex(base)
    return tree
Exemplo n.º 32
0
    def to_graph(self):
        r"""
        Returns the graph corresponding to the perfect matching.

        OUTPUT:

            The realization of ``self`` as a graph.

        EXAMPLES::

            sage: PerfectMatching([[1,3], [4,2]]).to_graph().edges(labels=False)
            [(1, 3), (2, 4)]
            sage: PerfectMatching([[1,4], [3,2]]).to_graph().edges(labels=False)
            [(1, 4), (2, 3)]
            sage: PerfectMatching([]).to_graph().edges(labels=False)
            []
        """
        from sage.graphs.graph import Graph
        G = Graph()
        for a, b in self.value:
            G.add_edge((a, b))
        return G
Exemplo n.º 33
0
    def is_connected(self, force_computation=False):
        if not force_computation and self._connected:
            return True

        from sage.graphs.graph import Graph
        G = Graph(loops=True, multiedges=True)
        for i in range(self._total_darts):
            if self._active_darts[i]:
                G.add_edge(i,self._vertices[i])
                G.add_edge(i,self._edges[i])
                G.add_edge(i,self._faces[i])
        return G.is_connected()
Exemplo n.º 34
0
def TetrahedralGraph():
    """
    Return a tetrahedral graph (with 4 nodes).

    A tetrahedron is a 4-sided triangular pyramid. The tetrahedral graph
    corresponds to the connectivity of the vertices of the tetrahedron. This
    graph is equivalent to a wheel graph with 4 nodes and also a complete graph
    on four nodes. (See examples below).

    PLOTTING: The Tetrahedral graph should be viewed in 3 dimensions. We choose
    to use a planar embedding of the graph. We hope to add rotatable,
    3-dimensional viewing in the future. In such a case, a argument will be
    added to select the desired layout.

    EXAMPLES:

    Construct and show a Tetrahedral graph::

        sage: g = graphs.TetrahedralGraph()
        sage: g.show()  # long time

    The following example requires networkx::

        sage: import networkx as NX

    Compare this Tetrahedral, Wheel(4), Complete(4), and the Tetrahedral plotted
    with the spring-layout algorithm below in a Sage graphics array::

        sage: tetra_pos = graphs.TetrahedralGraph()
        sage: tetra_spring = Graph(NX.tetrahedral_graph())
        sage: wheel = graphs.WheelGraph(4)
        sage: complete = graphs.CompleteGraph(4)
        sage: g = [tetra_pos, tetra_spring, wheel, complete]
        sage: j = []
        sage: for i in range(2):
        ....:     n = []
        ....:     for m in range(2):
        ....:         n.append(g[i + m].plot(vertex_size=50, vertex_labels=False))
        ....:     j.append(n)
        sage: G = graphics_array(j)
        sage: G.show()  # long time
    """
    edges = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
    pos = {
        0: (0, 0),
        1: (0, 1),
        2: (cos(3.5 * pi / 3), sin(3.5 * pi / 3)),
        3: (cos(5.5 * pi / 3), sin(5.5 * pi / 3))
    }
    return Graph(edges, name="Tetrahedron", pos=pos)
Exemplo n.º 35
0
def graph6_to_plot(graph6):
    """
    Return a ``Graphics`` object from a ``graph6`` string.

    This method constructs a graph from a ``graph6`` string and returns a
    :class:`sage.plot.graphics.Graphics` object with arguments preset for the
    :meth:`sage.plot.graphics.Graphics.show` method.

    INPUT:

    - ``graph6`` -- a ``graph6`` string

    EXAMPLES::

        sage: from sage.graphs.graph_database import graph6_to_plot
        sage: type(graph6_to_plot('D??'))
        <class 'sage.plot.graphics.Graphics'>
    """
    g = Graph(str(graph6))
    return g.plot(layout='circular',
                  vertex_size=30,
                  vertex_labels=False,
                  graph_border=False)
Exemplo n.º 36
0
def construct_spx(spx, max=Integer(1280)):
    for r in range(3, max / 4 + 1):
        spx[r] = {}
        s = Integer(1)
        m = Integer(4) * r
        while m <= max:
            c = sum([[(tuple(v), n) for n in Integers(r)]
                     for v in Integers(2)**Integer(s)], [])
            c = [(v, n, Integer(1)) for v, n in c] + [(v, n, Integer(-1))
                                                      for v, n in c]
            spx[r][s] = Graph([c, spx_adj])
            s += 1
            m *= 2
        print "Finished r = %d, constructed %d graphs" % (r, len(spx[r]))
Exemplo n.º 37
0
def RandomRegular(d, n, seed=None):
    """
    Returns a random d-regular graph on n vertices, or returns False on
    failure.

    Since every edge is incident to two vertices, n\*d must be even.

    INPUT:

    -  ``n`` - number of vertices

    -  ``d`` - degree

    -  ``seed`` - for the random number generator


    EXAMPLE: We show the edge list of a random graph with 8 nodes each
    of degree 3.

    ::

        sage: graphs.RandomRegular(3, 8).edges(labels=False)
        [(0, 1), (0, 4), (0, 7), (1, 5), (1, 7), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (4, 5), (6, 7)]

    ::

        sage: G = graphs.RandomRegular(3, 20)
        sage: if G:
        ....:     G.show()  # random output, long time

    REFERENCES:

    .. [KimVu2003] Kim, Jeong Han and Vu, Van H. Generating random regular
      graphs. Proc. 35th ACM Symp. on Thy. of Comp. 2003, pp
      213-222. ACM Press, San Diego, CA, USA.
      http://doi.acm.org/10.1145/780542.780576

    .. [StegerWormald1999] Steger, A. and Wormald, N. Generating random
      regular graphs quickly. Prob. and Comp. 8 (1999), pp 377-396.
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    try:
        N = networkx.random_regular_graph(d, n, seed=seed)
        if N is False: return False
        return Graph(N, sparse=True)
    except Exception:
        return False
Exemplo n.º 38
0
 def relabel(self,
             perm=None,
             inplace=True,
             return_map=False,
             check_input=True,
             complete_partial_function=True,
             immutable=True):
     r"""
     This method has been overridden by DiscreteZOO to ensure that a mutable
     copy will have type ``Graph``.
     """
     if inplace:
         raise ValueError("To relabel an immutable graph use inplace=False")
     G = Graph(self, immutable=False)
     perm = G.relabel(perm,
                      return_map=True,
                      check_input=check_input,
                      complete_partial_function=complete_partial_function)
     if immutable is not False:
         G = self.__class__(self, vertex_labels=perm)
     if return_map:
         return G, perm
     else:
         return G
Exemplo n.º 39
0
def DegreeSequenceConfigurationModel(deg_sequence, seed=None):
    """
    Returns a random pseudograph with the given degree sequence. Raises
    a NetworkX error if the proposed degree sequence cannot be that of
    a graph with multiple edges and loops.

    One requirement is that the sum of the degrees must be even, since
    every edge must be incident with two vertices.

    INPUT:

    - ``deg_sequence`` - a list of integers with each entry corresponding to the
      expected degree of a different vertex.

    - ``seed`` - a ``random.Random`` seed or a Python ``int`` for the random
      number generator (default: ``None``).


    EXAMPLES::

        sage: G = graphs.DegreeSequenceConfigurationModel([1,1])
        sage: G.adjacency_matrix()
        [0 1]
        [1 0]

    Note: as of this writing, plotting of loops and multiple edges is
    not supported, and the output is allowed to contain both types of
    edges.

    ::

        sage: G = graphs.DegreeSequenceConfigurationModel([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3])
        sage: len(G.edges())
        30
        sage: G.show()  # long time

    REFERENCE:

    [New2003]_
    """
    if seed is None:
        seed = int(current_randstate().long_seed() % sys.maxsize)
    import networkx
    return Graph(networkx.configuration_model([int(i) for i in deg_sequence],
                                              seed=seed),
                 loops=True,
                 multiedges=True,
                 sparse=True)
Exemplo n.º 40
0
def DegreeSequenceConfigurationModel(deg_sequence, seed=None):
    """
    Returns a random pseudograph with the given degree sequence. Raises
    a NetworkX error if the proposed degree sequence cannot be that of
    a graph with multiple edges and loops.

    One requirement is that the sum of the degrees must be even, since
    every edge must be incident with two vertices.

    INPUT:

    -  ``deg_sequence`` - a list of integers with each
       entry corresponding to the expected degree of a different vertex.

    -  ``seed`` - for the random number generator.


    EXAMPLES::

        sage: G = graphs.DegreeSequenceConfigurationModel([1,1])
        sage: G.adjacency_matrix()
        [0 1]
        [1 0]

    Note: as of this writing, plotting of loops and multiple edges is
    not supported, and the output is allowed to contain both types of
    edges.

    ::

        sage: G = graphs.DegreeSequenceConfigurationModel([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3])
        sage: G.edges(labels=False)
        [(0, 2), (0, 10), (0, 15), (1, 6), (1, 16), (1, 17), (2, 5), (2, 19), (3, 7), (3, 14), (3, 14), (4, 9), (4, 13), (4, 19), (5, 6), (5, 15), (6, 11), (7, 11), (7, 17), (8, 11), (8, 18), (8, 19), (9, 12), (9, 13), (10, 15), (10, 18), (12, 13), (12, 16), (14, 17), (16, 18)]
        sage: G.show()  # long time

    REFERENCE:

    .. [Newman2003] Newman, M.E.J. The Structure and function of complex
      networks, SIAM Review vol. 45, no. 2 (2003), pp. 167-256.
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    return Graph(networkx.configuration_model([int(i) for i in deg_sequence],
                                              seed=seed),
                 loops=True,
                 multiedges=True,
                 sparse=True)
Exemplo n.º 41
0
def LadderGraph(n):
    r"""
    Return a ladder graph with `2 * n` nodes.

    A ladder graph is a basic structure that is typically displayed as a ladder,
    i.e.: two parallel path graphs connected at each corresponding node pair.

    PLOTTING: Upon construction, the position dictionary is filled to override
    the spring-layout algorithm. By convention, each ladder graph will be
    displayed horizontally, with the first n nodes displayed left to right on
    the top horizontal line.

    EXAMPLES:

    Construct and show a ladder graph with 14 nodes::

        sage: g = graphs.LadderGraph(7)
        sage: g.show()  # long time

    Create several ladder graphs in a Sage graphics array::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     k = graphs.LadderGraph(i+2)
        ....:     g.append(k)
        sage: for i in range(3):
        ....:     n = []
        ....:     for m in range(3):
        ....:         n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
        ....:     j.append(n)
        sage: G = graphics_array(j)
        sage: G.show()  # long time
    """
    pos_dict = {}
    for i in range(n):
        pos_dict[i] = (i, 1)
    for i in range(n, 2 * n):
        x = i - n
        pos_dict[i] = (x, 0)
    G = Graph(2 * n, pos=pos_dict, name="Ladder graph")
    G.add_path(list(range(n)))
    G.add_path(list(range(n, 2 * n)))
    G.add_edges((i, i + n) for i in range(n))
    return G
Exemplo n.º 42
0
    def automorphism_group(self):
        r"""
        The automorphism group of the graph.

        EXAMPLES:

        ::

            sage: from boolean_cayley_graphs.royle_x_graph import royle_x_graph
            sage: g = royle_x_graph()
            sage: from boolean_cayley_graphs.strongly_regular_graph import StronglyRegularGraph
            sage: srg = StronglyRegularGraph(g)
            sage: srg.automorphism_group
            Permutation Group with generators [(11,21)(12,22)(13,23)(14,24)(15,25)(16,26)(17,27)(18,28)(19,29)(20,30)(36,37)(44,49)(45,50)(46,51)(47,52)(48,53), (5,11)(6,12)(7,13)(8,14)(9,15)(10,16)(27,31)(28,32)(29,33)(30,34)(37,38)(43,44)(50,54)(51,55)(52,56)(53,57), (3,4)(6,7)(8,9)(12,13)(14,15)(17,18)(22,23)(24,25)(27,28)(31,32)(41,42)(47,48)(52,53)(56,57)(59,60)(61,62), (2,3)(5,6)(9,10)(11,12)(15,16)(18,19)(21,22)(25,26)(28,29)(32,33)(40,41)(46,47)(51,52)(55,56)(58,59)(62,63), (2,5)(3,6)(4,7)(14,17)(15,18)(16,19)(24,27)(25,28)(26,29)(34,35)(38,39)(44,45)(49,50)(55,58)(56,59)(57,60), (1,2)(6,8)(7,9)(12,14)(13,15)(19,20)(22,24)(23,25)(29,30)(33,34)(39,40)(45,46)(50,51)(54,55)(59,61)(60,62), (1,20)(2,19)(3,18)(4,17)(5,16)(6,15)(7,14)(8,13)(9,12)(10,11)(37,43)(38,44)(39,45)(40,46)(41,47)(42,48), (0,1)(2,38,4,36)(3,37)(5,57,23,46)(6,53,22,51)(7,48,21,55)(8,17,26,33)(9,27,25,29)(10,31,24,19)(11,56,13,47)(12,52)(14,18,16,32)(15,28)(20,58,34,60)(30,59)(35,39)(40,43,42,49)(41,44)(45,63,54,61)(50,62)]
        """
        return Graph.automorphism_group(self)
Exemplo n.º 43
0
def RandomNewmanWattsStrogatz(n, k, p, seed=None):
    """
    Returns a Newman-Watts-Strogatz small world random graph on n
    vertices.

    From the NetworkX documentation: First create a ring over n nodes.
    Then each node in the ring is connected with its k nearest
    neighbors. Then shortcuts are created by adding new edges as
    follows: for each edge u-v in the underlying "n-ring with k nearest
    neighbors"; with probability p add a new edge u-w with
    randomly-chosen existing node w. In contrast with
    watts_strogatz_graph(), no edges are removed.

    INPUT:

    -  ``n`` - number of vertices.

    -  ``k`` - each vertex is connected to its k nearest
       neighbors

    -  ``p`` - the probability of adding a new edge for
       each edge

    -  ``seed`` - for the random number generator


    EXAMPLE: We show the edge list of a random graph on 7 nodes with 2
    "nearest neighbors" and probability `p = 0.2`::

        sage: graphs.RandomNewmanWattsStrogatz(7, 2, 0.2).edges(labels=False)
        [(0, 1), (0, 2), (0, 3), (0, 6), (1, 2), (2, 3), (2, 4), (3, 4), (3, 6), (4, 5), (5, 6)]

    ::

        sage: G = graphs.RandomNewmanWattsStrogatz(12, 2, .3)
        sage: G.show()  # long time

    REFERENCE:

    .. [NWS99] Newman, M.E.J., Watts, D.J. and Strogatz, S.H.  Random
      graph models of social networks. Proc. Nat. Acad. Sci. USA
      99, 2566-2572.
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    return Graph(networkx.newman_watts_strogatz_graph(n, k, p, seed=seed))
Exemplo n.º 44
0
def ButterflyGraph():
    r"""
    Return the butterfly graph.

    Let `C_3` be the cycle graph on 3 vertices. The butterfly or bowtie
    graph is obtained by joining two copies of `C_3` at a common vertex,
    resulting in a graph that is isomorphic to the friendship graph `F_2`.
    See the :wikipedia:`Butterfly_graph` for more information.

    .. SEEALSO::

        - :meth:`GraphGenerators.FriendshipGraph`

    EXAMPLES:

    The butterfly graph is a planar graph on 5 vertices and having 6 edges::

        sage: G = graphs.ButterflyGraph(); G
        Butterfly graph: Graph on 5 vertices
        sage: G.show()  # long time
        sage: G.is_planar()
        True
        sage: G.order()
        5
        sage: G.size()
        6

    It has diameter 2, girth 3, and radius 1::

        sage: G.diameter()
        2
        sage: G.girth()
        3
        sage: G.radius()
        1

    The butterfly graph is Eulerian, with chromatic number 3::

        sage: G.is_eulerian()
        True
        sage: G.chromatic_number()
        3
    """
    edge_dict = {0: [3, 4], 1: [2, 4], 2: [4], 3: [4]}
    pos_dict = {0: [-1, 1], 1: [1, 1], 2: [1, -1], 3: [-1, -1], 4: [0, 0]}
    return Graph(edge_dict, pos=pos_dict, name="Butterfly graph")
Exemplo n.º 45
0
def DegreeSequence(deg_sequence):
    """
    Returns a graph with the given degree sequence. Raises a NetworkX
    error if the proposed degree sequence cannot be that of a graph.

    Graph returned is the one returned by the Havel-Hakimi algorithm,
    which constructs a simple graph by connecting vertices of highest
    degree to other vertices of highest degree, resorting the remaining
    vertices by degree and repeating the process. See Theorem 1.4 in
    [CharLes1996]_.

    INPUT:

    -  ``deg_sequence`` - a list of integers with each
       entry corresponding to the degree of a different vertex.


    EXAMPLES::

        sage: G = graphs.DegreeSequence([3,3,3,3])
        sage: G.edges(labels=False)
        [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
        sage: G.show()  # long time

    ::

        sage: G = graphs.DegreeSequence([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3])
        sage: G.show()  # long time

    ::

        sage: G = graphs.DegreeSequence([4,4,4,4,4,4,4,4])
        sage: G.show()  # long time

    ::

        sage: G = graphs.DegreeSequence([1,2,3,4,3,4,3,2,3,2,1])
        sage: G.show()  # long time

    REFERENCE:

    .. [CharLes1996] Chartrand, G. and Lesniak, L.: Graphs and Digraphs.
      Chapman and Hall/CRC, 1996.
    """
    import networkx
    return Graph(networkx.havel_hakimi_graph([int(i) for i in deg_sequence]))
Exemplo n.º 46
0
    def coxeter_diagram(self):
        """
        Returns the Coxeter matrix for this type.

        EXAMPLES::

            sage: ct = CartanType(['I', 4])
            sage: ct.coxeter_diagram()
            Graph on 2 vertices
            sage: ct.coxeter_diagram().edges()
            [(1, 2, 4)]
            sage: ct.coxeter_matrix()
            [1 4]
            [4 1]
        """
        from sage.graphs.graph import Graph
        return Graph([[1, 2, self.n]], multiedges=False)
Exemplo n.º 47
0
 def create_graph_from_model(self, solver, model):
     '''
     Given a model from the SAT solver, construct the graph.
     '''
     g = Graph()
     on_vertices = solver.get_objects_in_model(
         model, self, self.internal_graph.vertices())
     on_edges = solver.get_objects_in_model(
         model, self, self.internal_graph.edges(labels=False))
     g.add_vertices(on_vertices)
     g.add_edges(on_edges)
     return g
Exemplo n.º 48
0
def DegreeSequenceConfigurationModel(deg_sequence, seed=None):
    """
    Return a random pseudograph with the given degree sequence.

    This method raises a NetworkX error if the proposed degree sequence cannot
    be that of a graph with multiple edges and loops.

    One requirement is that the sum of the degrees must be even, since every
    edge must be incident with two vertices.

    INPUT:

    - ``deg_sequence`` -- list of integers with each entry corresponding to the
      expected degree of a different vertex

    - ``seed`` -- (optional) a ``random.Random`` seed or a Python ``int`` for
      the random number generator

    EXAMPLES::

        sage: G = graphs.DegreeSequenceConfigurationModel([1,1])
        sage: G.adjacency_matrix()
        [0 1]
        [1 0]

    The output is allowed to contain both loops and multiple edges::

        sage: deg_sequence = [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
        sage: G = graphs.DegreeSequenceConfigurationModel(deg_sequence)
        sage: G.order(), G.size()
        (20, 30)
        sage: G.has_loops() or G.has_multiple_edges()  # random
        True
        sage: G.show()  # long time

    REFERENCE:

    [New2003]_
    """
    if seed is None:
        seed = int(current_randstate().long_seed() % sys.maxsize)
    import networkx
    deg_sequence = [int(i) for i in deg_sequence]
    return Graph(networkx.configuration_model(deg_sequence, seed=seed),
                     loops=True, multiedges=True, sparse=True)
Exemplo n.º 49
0
    def _parse_db(self, directory):
        r"""
        Parses the ISGCI database and stores its content in ``self``.

        INPUT:

        - ``directory`` -- the name of the directory containing the latest
          version of the database.

        EXAMPLE::

            sage: from sage.env import SAGE_SHARE
            sage: graph_classes._parse_db(os.path.join(SAGE_SHARE,'graphs'))
        """
        import xml.etree.cElementTree as ET
        import os.path
        from sage.graphs.graph import Graph

        xml_file = os.path.join(SAGE_SHARE, 'graphs', _XML_FILE)
        tree = ET.ElementTree(file=xml_file)
        root = tree.getroot()
        DB = _XML_to_dict(root)

        giveme = lambda x, y: str(x.getAttribute(y))

        classes = {c['id']: c for c in DB['GraphClasses']["GraphClass"]}
        for c in classes.itervalues():
            c["problem"] = {pb.pop("name"): pb for pb in c["problem"]}

        inclusions = DB['Inclusions']['incl']

        # Parses the list of ISGCI small graphs
        smallgraph_file = open(
            os.path.join(SAGE_SHARE, 'graphs', _SMALLGRAPHS_FILE), 'r')
        smallgraphs = {}

        for l in smallgraph_file.readlines():
            key, string = l.split("\t")
            smallgraphs[key] = Graph(string)

        smallgraph_file.close()

        self.inclusions.set_cache(inclusions)
        self.classes.set_cache(classes)
        self.smallgraphs.set_cache(smallgraphs)
Exemplo n.º 50
0
    def get_graphs_list(self):
        """
        Return a list of Sage Graph objects that satisfy the query.

        EXAMPLES::

            sage: Q = GraphQuery(display_cols=['graph6', 'num_vertices', 'degree_sequence'], num_edges=['<=', 5], min_degree=1)
            sage: L = Q.get_graphs_list()
            sage: L[0]
            Graph on 2 vertices
            sage: len(L)
            35
        """
        s = self.__query_string__
        re.sub('SELECT.*FROM ', 'SELECT graph6 FROM ', s)
        q = GenericGraphQuery(s, self.__database__, self.__param_tuple__)
        graph6_list = q.query_results()
        return [Graph(str(g[0])) for g in graph6_list]
Exemplo n.º 51
0
def IntersectionGraph(S):
    r"""
    Returns the intersection graph of the family `S`

    The intersection graph of a family `S` is a graph `G` with `V(G)=S` such
    that two elements `s_1,s_2\in S` are adjacent in `G` if and only if `s_1\cap
    s_2\neq \emptyset`.

    INPUT:

    - ``S`` -- a list of sets/tuples/iterables

        .. NOTE::

            The elements of `S` must be finite, hashable, and the elements of
            any `s\in S` must be hashable too.

    EXAMPLES::

        sage: graphs.IntersectionGraph([(1,2,3),(3,4,5),(5,6,7)])
        Intersection Graph: Graph on 3 vertices

    TESTS::

        sage: graphs.IntersectionGraph([(1,2,[1])])
        Traceback (most recent call last):
        ...
        TypeError: The elements of S must be hashable, and this one is not: (1, 2, [1])
    """
    from itertools import combinations

    for s in S:
        try:
            hash(s)
        except TypeError:
            raise TypeError(
                "The elements of S must be hashable, and this one is not: {}".
                format(s))

    ground_set_to_sets = {}
    for s in S:
        for x in s:
            if x not in ground_set_to_sets:
                ground_set_to_sets[x] = []
            ground_set_to_sets[x].append(s)

    g = Graph(name="Intersection Graph")
    g.add_vertices(S)
    for clique in itervalues(ground_set_to_sets):
        g.add_clique(set(clique))

    return g
Exemplo n.º 52
0
def DartGraph():
    """
    Return a dart graph with 5 nodes.

    PLOTTING: Upon construction, the position dictionary is filled to override
    the spring-layout algorithm. By convention, the dart graph is drawn as a
    dart, with the sharp part on the bottom.

    EXAMPLES:

    Construct and show a dart graph::

        sage: g = graphs.DartGraph()
        sage: g.show()  # long time
    """
    pos_dict = {0: (0, 1), 1: (-1, 0), 2: (1, 0), 3: (0, -1), 4: (0, 0)}
    edges = [(0, 1), (0, 2), (1, 4), (2, 4), (0, 4), (3, 4)]
    return Graph(edges, pos=pos_dict, name="Dart Graph")
Exemplo n.º 53
0
def CayleyGraph(vspace, gens, directed=False):
    """
  Generate a Cayley Graph over given vector space with edges
  generated by given generators. The graph is optionally directed.
  Try e.g. CayleyGraph(VectorSpace(GF(2), 3), [(1,0,0), (0,1,0), (0,0,1)])
  """
    G = Graph()
    for v in vspace:
        G.add_vertex(tuple(v))
        for g in gens:
            g2 = vspace(g)
            G.add_edge(tuple(v), tuple(v + g2))
    return G
Exemplo n.º 54
0
def RandomTreePowerlaw(n, gamma=3, tries=100, seed=None):
    """
    Returns a tree with a power law degree distribution. Returns False
    on failure.

    From the NetworkX documentation: A trial power law degree sequence
    is chosen and then elements are swapped with new elements from a
    power law distribution until the sequence makes a tree (size = order
    - 1).

    INPUT:

    -  ``n`` - number of vertices

    -  ``gamma`` - exponent of power law

    -  ``tries`` - number of attempts to adjust sequence to
       make a tree

    -  ``seed`` - for the random number generator


    EXAMPLE: We show the edge list of a random graph with 10 nodes and
    a power law exponent of 2.

    ::

        sage: graphs.RandomTreePowerlaw(10, 2).edges(labels=False)
        [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (6, 8), (6, 9)]

    ::

        sage: G = graphs.RandomTreePowerlaw(15, 2)
        sage: if G:
        ....:     G.show()  # random output, long time
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    try:
        return Graph(
            networkx.random_powerlaw_tree(n, gamma, seed=seed, tries=tries))
    except networkx.NetworkXError:
        return False
Exemplo n.º 55
0
def _check_pbd(B, v, S):
    r"""
    Checks that ``B`` is a PBD on `v` points with given block sizes.

    INPUT:

    - ``bibd`` -- a list of blocks

    - ``v`` (integer) -- number of points

    - ``S`` -- list of integers

    EXAMPLE::

        sage: designs.BalancedIncompleteBlockDesign(40,4).blocks() # indirect doctest
        [[0, 1, 2, 12], [0, 3, 6, 9], [0, 4, 8, 11], [0, 5, 7, 10],
         [0, 13, 26, 39], [0, 14, 28, 38], [0, 15, 25, 27],
         [0, 16, 32, 35], [0, 17, 34, 37], [0, 18, 33, 36],
        ...
    """
    from itertools import combinations
    from sage.graphs.graph import Graph

    if not all(len(X) in S for X in B):
        raise RuntimeError(
            "This is not a nice honest PBD from the good old days !")

    g = Graph()
    m = 0
    for X in B:
        g.add_edges(list(combinations(X, 2)))
        if g.size() != m + binomial(len(X), 2):
            raise RuntimeError(
                "This is not a nice honest PBD from the good old days !")
        m = g.size()

    if not (g.is_clique() and g.vertices() == range(v)):
        raise RuntimeError(
            "This is not a nice honest PBD from the good old days !")

    return B
def boolean_cayley_graph(dim, f):
    r"""
    Construct the Cayley graph of a Boolean function.

    Given the non-negative integer ``dim`` and the function ``f``,
    a Boolean function that takes a non-negative integer argument,
    the function ``Boolean_Cayley_graph`` constructs the Cayley graph of ``f``
    as a Boolean function on :math:`\mathbb{F}_2^{dim}`,
    with the lexicographica ordering.
    The value ``f(0)`` is assumed to be ``0``, so the graph is always simple.

    INPUT:

    - ``dim`` -- integer. The Boolean dimension of the given function.
    - ``f`` -- function. A Boolean function expressed as a Python function
      taking non-negative integer arguments.

    OUTPUT:

    A ``Graph`` object representing the Cayley graph of ``f``.

    .. SEEALSO:
        :module:`sage.graphs.graph`

    EXAMPLES:

    The Cayley graph of the function ``f`` where :math:`f(n) = n \mod 2`.

    ::

        sage: from boolean_cayley_graphs.boolean_cayley_graph import boolean_cayley_graph
        sage: f = lambda n: n % 2
        sage: g = boolean_cayley_graph(2, f)
        sage: g.adjacency_matrix()
        [0 1 0 1]
        [1 0 1 0]
        [0 1 0 1]
        [1 0 1 0]

    """
    return Graph([srange(2 ** dim), lambda i, j: f(i ^ j)],
                 format="rule",
                 immutable=True)
Exemplo n.º 57
0
    def to_graph(self):
        r"""
        Return the graph corresponding to the perfect matching.

        OUTPUT:

        The realization of ``self`` as a graph.

        EXAMPLES::

            sage: PerfectMatching([[1,3], [4,2]]).to_graph().edges(labels=False)
            [(1, 3), (2, 4)]
            sage: PerfectMatching([[1,4], [3,2]]).to_graph().edges(labels=False)
            [(1, 4), (2, 3)]
            sage: PerfectMatching([]).to_graph().edges(labels=False)
            []
        """
        from sage.graphs.graph import Graph
        return Graph([list(p) for p in self], format='list_of_edges')
Exemplo n.º 58
0
 def _subgraph_by_adding(self,
                         vertices=None,
                         edges=None,
                         edge_property=None,
                         immutable=None,
                         *largs,
                         **kargs):
     r"""
     This method has been overridden by DiscreteZOO to ensure that the
     subgraph will have type ``Graph``.
     """
     if immutable is None:
         immutable = True
     return Graph(self)._subgraph_by_adding(vertices=vertices,
                                            edges=edges,
                                            edge_property=edge_property,
                                            immutable=immutable,
                                            *largs,
                                            **kargs)
Exemplo n.º 59
0
    def independence_graph(self):
        r"""
        Return the digraph of independence relations.

        OUTPUT:

        Independence graph with generators as vertices.

        TESTS::

            sage: from sage.monoids.trace_monoid import TraceMonoid
            sage: F.<a,b,c> = FreeMonoid()
            sage: M.<ai,bi,ci> = TraceMonoid(F, I=((a,c), (c,a)))
            sage: M.independence_graph() == Graph({a:[c], b:[], c:[]})
            True
        """
        verts = list(self._free_monoid.gens())
        edges = list(map(list, self.independence()))
        return Graph([verts, edges], immutable=True)
Exemplo n.º 60
0
    def _spring_layout(self):
        r"""
        Return a spring layout for the vertices.

        The layout is computed by creating a graph `G` on the vertices *and*
        sets of the hypergraph. Each set is then made adjacent in `G` with all
        vertices it contains before a spring layout is computed for this
        graph. The position of the vertices in the hypergraph is the position of
        the same vertices in the graph's layout.

        .. NOTE::

            This method also returns the position of the "fake" vertices,
            i.e. those representing the sets.

        EXAMPLES::

            sage: H = Hypergraph([{1,2,3},{2,3,4},{3,4,5},{4,5,6}]); H
            Hypergraph on 6 vertices containing 4 sets
            sage: L = H._spring_layout()
            sage: L # random
            {1: (0.238, -0.926),
             2: (0.672, -0.518),
             3: (0.449, -0.225),
             4: (0.782, 0.225),
             5: (0.558, 0.518),
             6: (0.992, 0.926),
             {3, 4, 5}: (0.504, 0.173),
             {2, 3, 4}: (0.727, -0.173),
             {4, 5, 6}: (0.838, 0.617),
             {1, 2, 3}: (0.393, -0.617)}
            sage: all(v in L for v in H.domain())
            True
            sage: all(v in L for v in H._sets)
            True
        """
        from sage.graphs.graph import Graph

        g = Graph()
        for s in self._sets:
            for x in s:
                g.add_edge(s, x)

        _ = g.plot(iterations=50000, save_pos=True)

        # The values are rounded as TikZ does not like accuracy.
        return {
            k: (round(x, 3), round(y, 3))
            for k, (x, y) in g.get_pos().items()
        }