예제 #1
0
def RandomGNM(n, m, dense=False, seed=None):
    """
    Returns a graph randomly picked out of all graphs on n vertices
    with m edges.

    INPUT:


    -  ``n`` - number of vertices.

    -  ``m`` - number of edges.

    -  ``dense`` - whether to use NetworkX's
       dense_gnm_random_graph or gnm_random_graph


    EXAMPLES: We show the edge list of a random graph on 5 nodes with
    10 edges.

    ::

        sage: graphs.RandomGNM(5, 10).edges(labels=False)
        [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

    We plot a random graph on 12 nodes with m = 12.

    ::

        sage: gnm = graphs.RandomGNM(12, 12)
        sage: gnm.show()  # long time

    We view many random graphs using a graphics array::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ...    k = graphs.RandomGNM(i+3, i^2-i)
        ...    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
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    if dense:
        return graph.Graph(networkx.dense_gnm_random_graph(n, m, seed=seed))
    else:
        return graph.Graph(networkx.gnm_random_graph(n, m, seed=seed))
예제 #2
0
def GemGraph():
    """
    Return a gem graph with 5 nodes.

    A gem graph is a fan graph (4,1).

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

    EXAMPLES:

    Construct and show a gem graph::

        sage: g = graphs.GemGraph()
        sage: g.show() # long time
    """
    pos_dict = {
        0: (0.5, 0),
        1: (0, 0.75),
        2: (0.25, 1),
        3: (0.75, 1),
        4: (1, 0.75)
    }
    edges = [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (2, 3), (3, 4)]
    return graph.Graph(edges, pos=pos_dict, name="Gem Graph")
예제 #3
0
def RandomShell(constructor, seed=None):
    """
    Returns a random shell graph for the constructor given.

    INPUT:


    -  ``constructor`` - a list of 3-tuples (n,m,d), each
       representing a shell

    -  ``n`` - the number of vertices in the shell

    -  ``m`` - the number of edges in the shell

    -  ``d`` - the ratio of inter (next) shell edges to
       intra shell edges

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


    EXAMPLE::

        sage: G = graphs.RandomShell([(10,20,0.8),(20,40,0.8)])
        sage: G.edges(labels=False)
        [(0, 3), (0, 7), (0, 8), (1, 2), (1, 5), (1, 8), (1, 9), (3, 6), (3, 11), (4, 6), (4, 7), (4, 8), (4, 21), (5, 8), (5, 9), (6, 9), (6, 10), (7, 8), (7, 9), (8, 18), (10, 11), (10, 13), (10, 19), (10, 22), (10, 26), (11, 18), (11, 26), (11, 28), (12, 13), (12, 14), (12, 28), (12, 29), (13, 16), (13, 21), (13, 29), (14, 18), (16, 20), (17, 18), (17, 26), (17, 28), (18, 19), (18, 22), (18, 27), (18, 28), (19, 23), (19, 25), (19, 28), (20, 22), (24, 26), (24, 27), (25, 27), (25, 29)]
        sage: G.show()  # long time
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    return graph.Graph(networkx.random_shell_graph(constructor, seed=seed))
예제 #4
0
def IcosahedralGraph():
    """
    Returns an Icosahedral graph (with 12 nodes).

    The regular icosahedron is a 20-sided triangular polyhedron. The
    icosahedral graph corresponds to the connectivity of the vertices
    of the icosahedron. It is dual to the dodecahedral graph. The
    icosahedron is symmetric, so the spring-layout algorithm will be
    very effective for display.

    PLOTTING: The Icosahedral graph should be viewed in 3 dimensions.
    We chose to use the default spring-layout algorithm here, so that
    multiple iterations might yield a different point of reference for
    the user. We hope to add rotatable, 3-dimensional viewing in the
    future. In such a case, a string argument will be added to select
    the flat spring-layout over a future implementation.

    EXAMPLES: Construct and show an Octahedral graph

    ::

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

    Create several icosahedral graphs in a Sage graphics array. They
    will be drawn differently due to the use of the spring-layout
    algorithm.

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ...    k = graphs.IcosahedralGraph()
        ...    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
    """
    import networkx
    G = networkx.icosahedral_graph()

    pos = {}
    r1 = 5
    r2 = 2
    for i, v in enumerate([2, 8, 7, 11, 4, 6]):
        i = i + .5
        pos[v] = (r1 * cos(i * pi / 3), r1 * sin(i * pi / 3))

    for i, v in enumerate([1, 9, 0, 10, 5, 3]):
        i = i + .5
        pos[v] = (r2 * cos(i * pi / 3), r2 * sin(i * pi / 3))

    return graph.Graph(G, name="Icosahedron", pos=pos)
예제 #5
0
def ClawGraph():
    """
    Returns a claw graph.

    A claw graph is named for its shape. It is actually a complete
    bipartite graph with (n1, n2) = (1, 3).

    PLOTTING: See CompleteBipartiteGraph.

    EXAMPLES: Show a Claw graph

    ::

        sage: (graphs.ClawGraph()).show() # long time

    Inspect a Claw graph

    ::

        sage: G = graphs.ClawGraph()
        sage: G
        Claw graph: Graph on 4 vertices
    """
    edge_list = [(0, 1), (0, 2), (0, 3)]
    pos_dict = {0:(0,1),1:(-1,0),2:(0,0),3:(1,0)}
    return graph.Graph(edge_list, pos=pos_dict, name="Claw graph")
예제 #6
0
def HouseGraph():
    """
    Returns a house graph with 5 nodes.

    A house graph is named for its shape. It is a triangle (roof) over a
    square (walls).

    This constructor depends on NetworkX numeric labeling.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, the house
    graph is drawn with the first node in the lower-left corner of the
    house, the second in the lower-right corner of the house. The third
    node is in the upper-left corner connecting the roof to the wall,
    and the fourth is in the upper-right corner connecting the roof to
    the wall. The fifth node is the top of the roof, connected only to
    the third and fourth.

    EXAMPLES: Construct and show a house graph

    ::

        sage: g = graphs.HouseGraph()
        sage: g.show() # long time
    """
    pos_dict = {0: (-1, 0), 1: (1, 0), 2: (-1, 1), 3: (1, 1), 4: (0, 2)}
    import networkx
    G = networkx.house_graph()
    return graph.Graph(G, pos=pos_dict, name="House Graph")
예제 #7
0
def DiamondGraph():
    """
    Returns a diamond graph with 4 nodes.

    A diamond graph is a square with one pair of diagonal nodes
    connected.

    This constructor depends on NetworkX numeric labeling.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, the diamond
    graph is drawn as a diamond, with the first node on top, second on
    the left, third on the right, and fourth on the bottom; with the
    second and third node connected.

    EXAMPLES: Construct and show a diamond graph

    ::

        sage: g = graphs.DiamondGraph()
        sage: g.show() # long time
    """
    pos_dict = {0: (0, 1), 1: (-1, 0), 2: (1, 0), 3: (0, -1)}
    edges = [(0, 1), (0, 2), (1, 2), (1, 3), (2, 3)]
    return graph.Graph(edges, pos=pos_dict, name="Diamond Graph")
예제 #8
0
def HouseXGraph():
    """
    Returns a house X graph with 5 nodes.

    A house X graph is a house graph with two additional edges. The
    upper-right corner is connected to the lower-left. And the
    upper-left corner is connected to the lower-right.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, the house X
    graph is drawn with the first node in the lower-left corner of the
    house, the second in the lower-right corner of the house. The third
    node is in the upper-left corner connecting the roof to the wall,
    and the fourth is in the upper-right corner connecting the roof to
    the wall. The fifth node is the top of the roof, connected only to
    the third and fourth.

    EXAMPLES: Construct and show a house X graph

    ::

        sage: g = graphs.HouseXGraph()
        sage: g.show() # long time
    """
    pos_dict = {0:(-1,0),1:(1,0),2:(-1,1),3:(1,1),4:(0,2)}
    edges = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3), (2, 4), (3, 4)]
    return graph.Graph(edges, pos=pos_dict, name="House Graph")
예제 #9
0
def RandomLobster(n, p, q, seed=None):
    """
    Returns a random lobster.

    A lobster is a tree that reduces to a caterpillar when pruning all
    leaf vertices. A caterpillar is a tree that reduces to a path when
    pruning all leaf vertices (q=0).

    INPUT:

    -  ``n`` - expected number of vertices in the backbone

    -  ``p`` - probability of adding an edge to the
       backbone

    -  ``q`` - probability of adding an edge (claw) to the
       arms

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

    EXAMPLE: We show the edge list of a random graph with 3 backbone
    nodes and probabilities `p = 0.7` and `q = 0.3`::

        sage: graphs.RandomLobster(3, 0.7, 0.3).edges(labels=False)
        [(0, 1), (1, 2)]

    ::

        sage: G = graphs.RandomLobster(9, .6, .3)
        sage: G.show()  # long time
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    return graph.Graph(networkx.random_lobster(n, p, q, seed=seed))
예제 #10
0
def GridGraph(dim_list):
    """
    Returns an n-dimensional grid graph.

    INPUT:


    -  ``dim_list`` - a list of integers representing the
       number of nodes to extend in each dimension.


    PLOTTING: When plotting, this graph will use the default
    spring-layout algorithm, unless a position dictionary is
    specified.

    EXAMPLES::

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

    ::

        sage: C = graphs.CubeGraph(4)
        sage: G = graphs.GridGraph([2,2,2,2])
        sage: C.show()  # long time
        sage: G.show()  # long time
    """
    import networkx
    dim = [int(a) for a in dim_list]
    G = networkx.grid_graph(dim)
    return graph.Graph(G, name="Grid Graph for %s" % dim)
예제 #11
0
def DegreeSequenceExpected(deg_sequence, seed=None):
    """
    Returns a random graph with expected given degree sequence. Raises
    a NetworkX error if the proposed degree sequence cannot be that of
    a graph.

    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.

    EXAMPLE::

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

    REFERENCE:

    - [1] Chung, Fan and Lu, L. Connected components in random
      graphs with given expected degree
      sequences. Ann. Combinatorics (6), 2002 pp. 125-145.
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    return graph.Graph(networkx.expected_degree_graph(
        [int(i) for i in deg_sequence], seed=seed),
                       loops=True)
예제 #12
0
def EmptyGraph():
    """
    Returns an empty graph (0 nodes and 0 edges).

    This is useful for constructing graphs by adding edges and vertices
    individually or in a loop.

    PLOTTING: When plotting, this graph will use the default
    spring-layout algorithm, unless a position dictionary is
    specified.

    EXAMPLES: Add one vertex to an empty graph and then show::

        sage: empty1 = graphs.EmptyGraph()
        sage: empty1.add_vertex()
        0
        sage: empty1.show() # long time

    Use for loops to build a graph from an empty graph::

        sage: empty2 = graphs.EmptyGraph()
        sage: for i in range(5):
        ....:     empty2.add_vertex() # add 5 nodes, labeled 0-4
        0
        1
        2
        3
        4
        sage: for i in range(3):
        ....:     empty2.add_edge(i,i+1) # add edges {[0:1],[1:2],[2:3]}
        sage: for i in range(4)[1:]:
        ....:     empty2.add_edge(4,i) # add edges {[1:4],[2:4],[3:4]}
        sage: empty2.show() # long time
    """
    return graph.Graph(sparse=True)
예제 #13
0
def Grid2dGraph(n1, n2):
    r"""
    Returns a `2`-dimensional grid graph with `n_1n_2` nodes (`n_1` rows and
    `n_2` columns).

    A 2d grid graph resembles a `2` dimensional grid. All inner nodes are
    connected to their `4` neighbors. Outer (non-corner) nodes are
    connected to their `3` neighbors. Corner nodes are connected to their
    2 neighbors.

    This constructor depends on NetworkX numeric labels.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, nodes are
    labelled in (row, column) pairs with `(0, 0)` in the top left corner.
    Edges will always be horizontal and vertical - another advantage of
    filling the position dictionary.

    EXAMPLES: Construct and show a grid 2d graph Rows = `5`, Columns = `7`

    ::

        sage: g = graphs.Grid2dGraph(5,7)
        sage: g.show() # long time

    TESTS:

    Senseless input::

        sage: graphs.Grid2dGraph(5,0)
        Traceback (most recent call last):
        ...
        ValueError: Parameters n1 and n2 must be positive integers !
        sage: graphs.Grid2dGraph(-1,0)
        Traceback (most recent call last):
        ...
        ValueError: Parameters n1 and n2 must be positive integers !

    The graph name contains the dimension::

        sage: g = graphs.Grid2dGraph(5,7)
        sage: g.name()
        '2D Grid Graph for [5, 7]'
    """

    if n1 <= 0 or n2 <= 0:
        raise ValueError("Parameters n1 and n2 must be positive integers !")

    pos_dict = {}
    for i in range(n1):
        y = -i
        for j in range(n2):
            x = j
            pos_dict[i, j] = (x, y)
    import networkx
    G = networkx.grid_2d_graph(n1, n2)
    return graph.Graph(G,
                       pos=pos_dict,
                       name="2D Grid Graph for " + str([n1, n2]))
예제 #14
0
def RandomHolmeKim(n, m, p, seed=None):
    """
    Returns a random graph generated by the Holme and Kim algorithm for
    graphs with power law degree distribution and approximate average
    clustering.

    INPUT:


    -  ``n`` - number of vertices.

    -  ``m`` - number of random edges to add for each new
       node.

    -  ``p`` - probability of adding a triangle after
       adding a random edge.

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


    From the NetworkX documentation: The average clustering has a hard
    time getting above a certain cutoff that depends on m. This cutoff
    is often quite low. Note that the transitivity (fraction of
    triangles to possible triangles) seems to go down with network
    size. It is essentially the Barabasi-Albert growth model with an
    extra step that each random edge is followed by a chance of making
    an edge to one of its neighbors too (and thus a triangle). This
    algorithm improves on B-A in the sense that it enables a higher
    average clustering to be attained if desired. It seems possible to
    have a disconnected graph with this algorithm since the initial m
    nodes may not be all linked to a new node on the first iteration
    like the BA model.

    EXAMPLE: We show the edge list of a random graph on 8 nodes with 2
    random edges per node and a probability `p = 0.5` of
    forming triangles.

    ::

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

    ::

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

    REFERENCE:

    - [1] Holme, P. and Kim, B.J. Growing scale-free networks with
      tunable clustering, Phys. Rev. E (2002). vol 65, no 2,
      026107.
    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    return graph.Graph(networkx.powerlaw_cluster_graph(n, m, p, seed=seed))
예제 #15
0
    def white_graph(self):
        """
        Return the white graph of a non-split link projection.

        This method generates a multigraph whose vertices correspond
        to the faces of the diagram, with an edge joining two
        vertices whenever the corresponding faces contain opposite
        corners at some crossing.  To avoid hashability issues, the
        vertex corresponding to a face is the index of the face in the
        list returned by Link.faces().

        According to the conventions of "Gordon, C. McA. and
        Litherland, R. A, 'On the signature of a link', Inventiones
        math. 47, 23-69 (1978)", in a checkerboard coloring of a link
        diagram the unbounded region is always the first white region.
        Of course, the choice of which region is unbounded is
        arbitrary; it is just a matter of which region on S^2 contains
        the point at infinity.  In this method an equivalent arbitrary
        choice is made by just returning the second component of the
        multigraph, as determined by Graph.connected_components().
        (Empirically, the second component tends to be smaller than
        the first.)

        Note that this may produce a meaningless result in the case of
        a split link diagram.  Consequently if the diagram is split,
        i.e if the multigraph has more than 2 components, a ValueError
        is raised::

            sage: K=Link('5_1')           
            sage: K.white_graph()
            Subgraph of (): Multi-graph on 2 vertices
        """
        # Map corners (i.e. CrossingStrands) to faces.
        face_of = dict((corner, n) for n, face in enumerate(self.faces())
                       for corner in face)

        # Create the edges, labeled with crossing and sign.
        edges = []
        for c in self.crossings:
            edges.append(
                (face_of[CrossingStrand(c,
                                        0)], face_of[CrossingStrand(c, 2)], {
                                            'crossing': c,
                                            'sign': 1
                                        }))
            edges.append(
                (face_of[CrossingStrand(c,
                                        1)], face_of[CrossingStrand(c, 3)], {
                                            'crossing': c,
                                            'sign': -1
                                        }))

        # Build the graph.
        G = graph.Graph(edges, multiedges=True)
        components = G.connected_components()
        if len(components) > 2:
            raise ValueError('The link diagram is split.')
        return G.subgraph(components[1])
예제 #16
0
def LollipopGraph(n1, n2):
    """
    Returns a lollipop graph with n1+n2 nodes.

    A lollipop graph is a path graph (order n2) connected to a complete
    graph (order n1). (A barbell graph minus one of the bells).

    This constructor depends on NetworkX numeric labels.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, the complete
    graph will be drawn in the lower-left corner with the (n1)th node
    at a 45 degree angle above the right horizontal center of the
    complete graph, leading directly into the path graph.

    EXAMPLES: Construct and show a lollipop graph Candy = 13, Stick =
    4

    ::

        sage: g = graphs.LollipopGraph(13,4)
        sage: g.show() # long time

    Create several lollipop graphs in a Sage graphics array

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(6):
        ....:     k = graphs.LollipopGraph(i+3,4)
        ....:     g.append(k)
        sage: for i in range(2):
        ....:     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(n1):
        x = float(cos((pi / 4) - ((2 * pi) / n1) * i) - n2 / 2 - 1)
        y = float(sin((pi / 4) - ((2 * pi) / n1) * i) - n2 / 2 - 1)
        j = n1 - 1 - i
        pos_dict[j] = (x, y)
    for i in range(n1, n1 + n2):
        x = float(i - n1 - n2 / 2 + 1)
        y = float(i - n1 - n2 / 2 + 1)
        pos_dict[i] = (x, y)
    G = graph.Graph(dict((i, range(i + 1, n1)) for i in range(n1)),
                    pos=pos_dict,
                    name="Lollipop Graph")
    G.add_vertices(range(n1 + n2))
    G.add_path(range(n1 - 1, n1 + n2))
    return G
예제 #17
0
def ButterflyGraph():
    r"""
    Returns 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`.
    For more information, see this
    `Wikipedia article on the butterfly graph <http://en.wikipedia.org/wiki/Butterfly_graph>`_.

    .. 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.Graph(edge_dict, pos=pos_dict, name="Butterfly graph")
예제 #18
0
def HexahedralGraph():
    """
    Returns a hexahedral graph (with 8 nodes).

    A regular hexahedron is a 6-sided cube. The hexahedral graph
    corresponds to the connectivity of the vertices of the hexahedron.
    This graph is equivalent to a 3-cube.

    PLOTTING: The hexahedral graph should be viewed in 3 dimensions. We
    chose to use the default spring-layout algorithm here, so that
    multiple iterations might yield a different point of reference for
    the user. We hope to add rotatable, 3-dimensional viewing in the
    future. In such a case, a string argument will be added to select
    the flat spring-layout over a future implementation.

    EXAMPLES: Construct and show a Hexahedral graph

    ::

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

    Create several hexahedral graphs in a Sage graphics array. They
    will be drawn differently due to the use of the spring-layout
    algorithm.

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ...    k = graphs.HexahedralGraph()
        ...    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
    """
    return graph.Graph({0:[1,3,4], 1:[2,5], 2:[3,6], 3:[7], 4:[5,7],\
                        5:[6], 6:[7]},
                       name="Hexahedron",
                       pos = {
                          0 : (0,0),
                          1 : (1,0),
                          3 : (0,1),
                          2 : (1,1),
                          4 : (.5,.5),
                          5 : (1.5,.5),
                          7 : (.5,1.5),
                          6 : (1.5,1.5)
                          })
예제 #19
0
def TetrahedralGraph():
    """
    Returns 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 chose to use the default spring-layout algorithm here, so that
    multiple iterations might yield a different point of reference for
    the user. We hope to add rotatable, 3-dimensional viewing in the
    future. In such a case, a string argument will be added to select
    the flat spring-layout over a future implementation.

    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 = sage.plot.graphics.GraphicsArray(j)
        sage: G.show() # long time
    """
    import networkx
    G = networkx.tetrahedral_graph()
    return graph.Graph(G,
                       name="Tetrahedron",
                       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))
                       })
예제 #20
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)
    import networkx
    G = networkx.circular_ladder_graph(n)
    return graph.Graph(G, pos=pos_dict, name="Circular Ladder graph")
예제 #21
0
def GridGraph(dim_list):
    """
    Returns an n-dimensional grid graph.

    INPUT:


    -  ``dim_list`` - a list of integers representing the
       number of nodes to extend in each dimension.


    PLOTTING: When plotting, this graph will use the default
    spring-layout algorithm, unless a position dictionary is
    specified.

    EXAMPLES::

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

    ::

        sage: C = graphs.CubeGraph(4)
        sage: G = graphs.GridGraph([2,2,2,2])
        sage: C.show()  # long time
        sage: G.show()  # long time

    TESTS:

    The graph name contains the dimension::

        sage: g = graphs.GridGraph([5, 7])
        sage: g.name()
        'Grid Graph for [5, 7]'
        sage: g = graphs.GridGraph([2, 3, 4])
        sage: g.name()
        'Grid Graph for [2, 3, 4]'
        sage: g = graphs.GridGraph([2, 4, 3])
        sage: g.name()
        'Grid Graph for [2, 4, 3]'

    All dimensions must be positive integers::

        sage: g = graphs.GridGraph([2,-1,3])
        Traceback (most recent call last):
        ...
        ValueError: All dimensions must be positive integers !
    """
    import networkx
    dim = [int(a) for a in dim_list]
    if any(a <= 0 for a in dim):
        raise ValueError("All dimensions must be positive integers !")
    # We give a copy of dim to networkx because it modifies the list
    G = networkx.grid_graph(list(dim))
    return graph.Graph(G, name="Grid Graph for " + str(dim))
예제 #22
0
def RandomBarabasiAlbert(n, m, seed=None):
    u"""
    Return a random graph created using the Barabasi-Albert preferential
    attachment model.

    A graph with m vertices and no edges is initialized, and a graph of n
    vertices is grown by attaching new vertices each with m edges that are
    attached to existing vertices, preferentially with high degree.

    INPUT:

    - ``n`` - number of vertices in the graph

    - ``m`` - number of edges to attach from each new node

    - ``seed`` - for random number generator

    EXAMPLES:

    We show the edge list of a random graph on 6 nodes with m = 2.

    ::

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

    We plot a random graph on 12 nodes with m = 3.

    ::

        sage: ba = graphs.RandomBarabasiAlbert(12,3)
        sage: ba.show()  # long time

    We view many random graphs using a graphics array::

        sage: g = []
        sage: j = []
        sage: for i in range(1,10):
        ...    k = graphs.RandomBarabasiAlbert(i+3, 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

    """
    if seed is None:
        seed = current_randstate().long_seed()
    import networkx
    return graph.Graph(networkx.barabasi_albert_graph(n, m, seed=seed))
예제 #23
0
def spanning_trees(G):
    """
    Function 'span' from Read paper
    """

    if G.is_connected():
        part_G = graph.Graph([])
        part_G.add_vertices(G.vertices())
        part_G.add_edges(bridge_finding.find_bridges(G))
        return rec(part_G, G)
    else:
        return []
예제 #24
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:

    - [1] 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

    - [2] 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.Graph(N, sparse=True)
    except StandardError:
        return False
예제 #25
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:

    - [1] 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.Graph(networkx.newman_watts_strogatz_graph(n, k, p,
                                                            seed=seed))
예제 #26
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)
    import networkx
    G = networkx.ladder_graph(n)
    return graph.Graph(G, pos=pos_dict, name="Ladder graph")
예제 #27
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
    [1].

    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:

    - [1] Chartrand, G. and Lesniak, L. Graphs and Digraphs.
      Chapman and Hall/CRC, 1996.
    """
    import networkx
    return graph.Graph(networkx.havel_hakimi_graph([int(i) for i in deg_sequence]))
예제 #28
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:

    - [1] 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.Graph(networkx.configuration_model(
        [int(i) for i in deg_sequence], seed=seed),
                       loops=True,
                       multiedges=True,
                       sparse=True)
예제 #29
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.Graph(
            networkx.random_powerlaw_tree(n, gamma, seed=seed, tries=tries))
    except networkx.NetworkXError:
        return False
예제 #30
0
    def black_graph(self):
        """
        Returns the black graph of K. If the black graph is disconnected
        (which can only happen for a split link diagram), returns one
        connected component. The edges are labeled by the crossings
        they correspond to.  Example::

            sage: K=Link('5_1')                                                                                
            sage: K.black_graph()
            Subgraph of (): Multi-graph on 2 vertices

        WARNING: While there is also a "white_graph" method, it need
        not be the case that these two graphs are complementary in the
        expected way.
        """

        faces = []
        for x in self.faces():
            l = []
            for y in x:
                l.append((y[0], y[1]))
                l.append((y[0], (y[1] + 1) % 4))
            faces.append(l)

        coords = list()
        for i in range(len(faces) - 1):
            for j in range(i + 1, len(faces)):
                a = set(faces[i])
                b = set(faces[j])
                s = a.union(b)
                for x in range(len(self.crossings)):
                    crossings = [
                        self.crossings[x][0], self.crossings[x][1],
                        self.crossings[x][2], self.crossings[x][3]
                    ]
                    total = set(crossings)
                    if total.issubset(s):
                        coords.append(
                            (tuple(faces[i]), tuple(faces[j]),
                             self.crossings[x]))  #label by the crossing.

        G = graph.Graph(coords, multiedges=True)
        component = G.connected_components(sort=False)[1]
        G = G.subgraph(component)
        return G