Example #1
0
def IcosahedralGraph():
    """
    Return 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 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 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 = graphics_array(j)
        sage: G.show()  # long time
    """
    adj = {
        0: [1, 5, 7, 8, 11],
        1: [2, 5, 6, 8],
        2: [3, 6, 8, 9],
        3: [4, 6, 9, 10],
        4: [5, 6, 10, 11],
        5: [6, 11],
        7: [8, 9, 10, 11],
        8: [9],
        9: [10],
        10: [11]
    }
    G = Graph(adj, format='dict_of_lists', name="Icosahedron")
    G._circle_embedding([2, 8, 7, 11, 4, 6], radius=5, angle=pi / 6)
    G._circle_embedding([1, 9, 0, 10, 5, 3], radius=2, angle=pi / 6)
    return G
Example #2
0
def OctahedralGraph():
    """
    Return an Octahedral graph (with 6 nodes).

    The regular octahedron is an 8-sided polyhedron with triangular faces. The
    octahedral graph corresponds to the connectivity of the vertices of the
    octahedron. It is the line graph of the tetrahedral graph. The octahedral is
    symmetric, so the spring-layout algorithm will be very effective for
    display.

    PLOTTING: The Octahedral 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 an Octahedral graph::

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

    Create several octahedral 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.OctahedralGraph()
        ....:     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
    """
    adj = {0: [1, 2, 3, 4], 1: [2, 3, 5], 2: [4, 5], 3: [4, 5], 4: [5]}
    G = Graph(adj, format='dict_of_lists', name="Octahedron")
    G._circle_embedding([0, 1, 2], radius=5, angle=pi / 2)
    G._circle_embedding([4, 3, 5], radius=1, angle=pi / 6)
    return G
Example #3
0
def CircularLadderGraph(n):
    r"""
    Return 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.

    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.
    When `n == 2`, we rotate the outer circle by an angle of `\pi/8` to ensure
    that all edges are visible (otherwise the 4 vertices of the graph would be
    placed on a single line).

    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 = graphics_array(j)
        sage: G.show() # long time
    """
    G = Graph(2 * n, name="Circular Ladder graph")
    G._circle_embedding(list(range(n)), radius=1, angle=pi/2)
    if n == 2:
        G._circle_embedding(list(range(4)), radius=1, angle=pi/2 + pi/8)
    else:
        G._circle_embedding(list(range(n, 2*n)), radius=2, angle=pi/2)
    G.add_cycle(list(range(n)))
    G.add_cycle(list(range(n, 2 * n)))
    G.add_edges((i, i + n) for i in range(n))
    return G
Example #4
0
def CircularLadderGraph(n):
    r"""
    Return 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.

    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.
    When `n == 2`, we rotate the outer circle by an angle of `\pi/8` to ensure
    that all edges are visible (otherwise the 4 vertices of the graph would be
    placed on a single line).

    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
    """
    G = Graph(2 * n, name="Circular Ladder graph")
    G._circle_embedding(list(range(n)), radius=1, angle=pi/2)
    if n == 2:
        G._circle_embedding(list(range(4)), radius=1, angle=pi/2 + pi/8)
    else:
        G._circle_embedding(list(range(n, 2*n)), radius=2, angle=pi/2)
    G.add_cycle(list(range(n)))
    G.add_cycle(list(range(n, 2 * n)))
    G.add_edges( (i,i+n) for i in range(n) )
    return G
Example #5
0
def CompleteGraph(n):
    r"""
    Return a complete graph on `n` nodes.

    A Complete Graph is a graph in which all nodes are connected to all
    other nodes.

    PLOTTING: Upon construction, the position dictionary is filled to
    override the spring-layout algorithm. By convention, each complete
    graph will be displayed with the first (0) node at the top, with
    the rest following in a counterclockwise manner.

    In the complete graph, there is a big difference visually in using
    the spring-layout algorithm vs. the position dictionary used in
    this constructor. The position dictionary flattens the graph,
    making it clear which nodes an edge is connected to. But the
    complete graph offers a good example of how the spring-layout
    works. The edges push outward (everything is connected), causing
    the graph to appear as a 3-dimensional pointy ball. (See examples
    below).

    EXAMPLES:

    We view many Complete graphs with a Sage Graphics Array, first with this
    constructor (i.e., the position dictionary filled)::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     k = graphs.CompleteGraph(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 = graphics_array(j)
        sage: G.show()  # long time

    We compare to plotting with the spring-layout algorithm::

        sage: import networkx
        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     spr = networkx.complete_graph(i+3)
        ....:     k = Graph(spr)
        ....:     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

    Compare the constructors (results will vary)::

        sage: import networkx
        sage: t = cputime()
        sage: n = networkx.complete_graph(389); spring389 = Graph(n)
        sage: cputime(t)  # random
        0.59203700000000126
        sage: t = cputime()
        sage: posdict389 = graphs.CompleteGraph(389)
        sage: cputime(t)  # random
        0.6680419999999998

    We compare plotting::

        sage: import networkx
        sage: n = networkx.complete_graph(23)
        sage: spring23 = Graph(n)
        sage: posdict23 = graphs.CompleteGraph(23)
        sage: spring23.show()  # long time
        sage: posdict23.show()  # long time
    """
    G = Graph(n, name="Complete graph")
    if n == 1:
        G.set_pos({0: (0, 0)})
    else:
        G._circle_embedding(list(range(n)), angle=pi/2)
    G.add_edges(((i,j) for i in range(n) for j in range(i+1,n)))
    return G
Example #6
0
def CycleGraph(n):
    r"""
    Return a cycle graph with `n` nodes.

    A cycle graph is a basic structure which is also typically called an
    `n`-gon.

    PLOTTING: Upon construction, the position dictionary is filled to override
    the spring-layout algorithm. By convention, each cycle graph will be
    displayed with the first (0) node at the top, with the rest following in a
    counterclockwise manner.

    The cycle graph is a good opportunity to compare efficiency of filling a
    position dictionary vs. using the spring-layout algorithm for
    plotting. Because the cycle graph is very symmetric, the resulting plots
    should be similar (in cases of small `n`).

    Filling the position dictionary in advance adds `O(n)` to the constructor.

    EXAMPLES:

    Compare plotting using the predefined layout and networkx::

        sage: import networkx
        sage: n = networkx.cycle_graph(23)
        sage: spring23 = Graph(n)
        sage: posdict23 = graphs.CycleGraph(23)
        sage: spring23.show()  # long time
        sage: posdict23.show()  # long time

    We next view many cycle graphs as a Sage graphics array. First we use the
    ``CycleGraph`` constructor, which fills in the position dictionary::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     k = graphs.CycleGraph(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 = graphics_array(j)
        sage: G.show()  # long time

    Compare to plotting with the spring-layout algorithm::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     spr = networkx.cycle_graph(i+3)
        ....:     k = Graph(spr)
        ....:     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

    TESTS:

    The input parameter must be a positive integer::

        sage: G = graphs.CycleGraph(-1)
        Traceback (most recent call last):
        ...
        ValueError: parameter n must be a positive integer
    """
    if n < 0:
        raise ValueError("parameter n must be a positive integer")

    G = Graph(n, name="Cycle graph")
    if n == 1:
        G.set_pos({0: (0, 0)})
    else:
        G._circle_embedding(list(range(n)), angle=pi/2)
        G.add_cycle(list(range(n)))
    return G
Example #7
0
def StarGraph(n):
    r"""
    Return a star graph with `n + 1` nodes.

    A Star graph is a basic structure where one node is connected to all other
    nodes.

    PLOTTING: Upon construction, the position dictionary is filled to override
    the spring-layout algorithm. By convention, each star graph will be
    displayed with the first (0) node in the center, the second node (1) at the
    top, with the rest following in a counterclockwise manner. (0) is the node
    connected to all other nodes.

    The star graph is a good opportunity to compare efficiency of filling a
    position dictionary vs. using the spring-layout algorithm for plotting. As
    far as display, the spring-layout should push all other nodes away from the
    (0) node, and thus look very similar to this constructor's positioning.

    EXAMPLES::

        sage: import networkx

    Compare the plots::

        sage: n = networkx.star_graph(23)
        sage: spring23 = Graph(n)
        sage: posdict23 = graphs.StarGraph(23)
        sage: spring23.show()  # long time
        sage: posdict23.show()  # long time

    View many star graphs as a Sage Graphics Array

    With this constructor (i.e., the position dictionary filled)

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     k = graphs.StarGraph(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 = graphics_array(j)
        sage: G.show()  # long time

    Compared to plotting with the spring-layout algorithm

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     spr = networkx.star_graph(i+3)
        ....:     k = Graph(spr)
        ....:     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
    """
    G = Graph({0: list(range(1, n + 1))}, name="Star graph", format="dict_of_lists")
    G.set_pos({0: (0, 0)})
    G._circle_embedding(list(range(1, n + 1)), angle=pi/2)
    return G
Example #8
0
def PathGraph(n, pos=None):
    r"""
    Return a path graph with `n` nodes.

    A path graph is a graph where all inner nodes are connected to their two
    neighbors and the two end-nodes are connected to their one inner neighbors
    (i.e.: a cycle graph without the first and last node connected).

    INPUT:

    - ``n`` -- number of nodes of the path graph

    - ``pos`` -- string (default: ``None``); indicates the embedding to use
      between 'circle', 'line' or the default algorithm. See the plotting
      section below for more detail.

    PLOTTING: Upon construction, the position dictionary is filled to override
    the spring-layout algorithm. By convention, the graph may be drawn in one of
    two ways: The 'line' argument will draw the graph in a horizontal line (left
    to right) if there are less than 11 nodes. Otherwise the 'line' argument
    will append horizontal lines of length 10 nodes below, alternating left to
    right and right to left. The 'circle' argument will cause the graph to be
    drawn in a cycle-shape, with the first node at the top and then about the
    circle in a clockwise manner. By default (without an appropriate string
    argument) the graph will be drawn as a 'circle' if `10 < n < 41` and as a
    'line' for all other `n`.

    EXAMPLES: Show default drawing by size: 'line': `n \leq 10`

    ::

        sage: p = graphs.PathGraph(10)
        sage: p.show()  # long time

    'circle': `10 < n < 41`

    ::

        sage: q = graphs.PathGraph(25)
        sage: q.show()  # long time

    'line': `n \geq 41`

    ::

        sage: r = graphs.PathGraph(55)
        sage: r.show()  # long time

    Override the default drawing::

        sage: s = graphs.PathGraph(5,'circle')
        sage: s.show()  # long time
    """
    G = Graph(n, name="Path graph")

    pos_dict = {}

    # Choose appropriate drawing pattern
    circle = False
    if pos == "circle":
        circle = True
    elif pos == "line":
        circle = False
    # Otherwise use default by size of n
    elif 10 < n < 41:
        circle = True

    # Draw 'circle'
    if circle:
        if n == 1:
            G.set_pos({0: (0, 0)})
        else:
            G._circle_embedding(list(range(n)), angle=pi/2)
    # Draw 'line'
    else:
        counter = 0  # node index
        rem = n % 10  # remainder to appear on last row
        rows = n // 10  # number of rows (not counting last row)
        lr = True  # left to right

        for i in range(rows):  # note that rows doesn't include last row
            y = -i
            for j in range(10):
                if lr:
                    x = j
                else:
                    x = 9 - j
                pos_dict[counter] = (x, y)
                counter += 1
            if lr:
                lr = False
            else:
                lr = True
        y = -rows
        for j in range(rem):  # last row
            if lr:
                x = j
            else:
                x = 9 - j
            pos_dict[counter] = (x, y)
            counter += 1
        G.set_pos(pos_dict)

    G.add_edges((i, i + 1) for i in range(n - 1))
    return G
Example #9
0
def DodecahedralGraph():
    """
    Return a Dodecahedral graph (with 20 nodes)

    The dodecahedral graph is cubic symmetric, so the spring-layout algorithm
    will be very effective for display. It is dual to the icosahedral graph.

    PLOTTING: The Dodecahedral 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 Dodecahedral graph::

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

    Create several dodecahedral 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.DodecahedralGraph()
        ....:     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
    """
    adj = {
        0: [1, 10, 19],
        1: [2, 8],
        2: [3, 6],
        3: [4, 19],
        4: [5, 17],
        5: [6, 15],
        6: [7],
        7: [8, 14],
        8: [9],
        9: [10, 13],
        10: [11],
        11: [12, 18],
        12: [13, 16],
        13: [14],
        14: [15],
        15: [16],
        16: [17],
        17: [18],
        18: [19]
    }
    G = Graph(adj, format='dict_of_lists', name="Dodecahedron")
    G._circle_embedding([19, 0, 1, 2, 3], radius=7, angle=pi / 10)
    G._circle_embedding([18, 10, 8, 6, 4], radius=4.7, angle=pi / 10)
    G._circle_embedding([11, 9, 7, 5, 17], radius=3.8, angle=3 * pi / 10)
    G._circle_embedding([12, 13, 14, 15, 16], radius=1.5, angle=3 * pi / 10)
    return G
Example #10
0
def CycleGraph(n):
    r"""
    Return a cycle graph with n nodes.

    A cycle graph is a basic structure which is also typically called an
    `n`-gon.

    PLOTTING: Upon construction, the position dictionary is filled to override
    the spring-layout algorithm. By convention, each cycle graph will be
    displayed with the first (0) node at the top, with the rest following in a
    counterclockwise manner.

    The cycle graph is a good opportunity to compare efficiency of filling a
    position dictionary vs. using the spring-layout algorithm for
    plotting. Because the cycle graph is very symmetric, the resulting plots
    should be similar (in cases of small `n`).

    Filling the position dictionary in advance adds `O(n)` to the constructor.

    EXAMPLES: Compare plotting using the predefined layout and networkx::

        sage: import networkx
        sage: n = networkx.cycle_graph(23)
        sage: spring23 = Graph(n)
        sage: posdict23 = graphs.CycleGraph(23)
        sage: spring23.show() # long time
        sage: posdict23.show() # long time

    We next view many cycle graphs as a Sage graphics array. First we use the
    ``CycleGraph`` constructor, which fills in the position dictionary::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     k = graphs.CycleGraph(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

    Compare to plotting with the spring-layout algorithm::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     spr = networkx.cycle_graph(i+3)
        ....:     k = Graph(spr)
        ....:     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

    TESTS:

    The input parameter must be a positive integer::

        sage: G = graphs.CycleGraph(-1)
        Traceback (most recent call last):
        ...
        ValueError: parameter n must be a positive integer
    """
    if n < 0:
        raise ValueError("parameter n must be a positive integer")

    G = Graph(n, name="Cycle graph")
    if n == 1:
        G.set_pos({0:(0, 0)})
    else:
        G._circle_embedding(list(range(n)), angle=pi/2)
        G.add_cycle(list(range(n)))
    return G
Example #11
0
def StarGraph(n):
    r"""
    Return a star graph with `n+1` nodes.

    A Star graph is a basic structure where one node is connected to all other
    nodes.

    PLOTTING: Upon construction, the position dictionary is filled to override
    the spring-layout algorithm. By convention, each star graph will be
    displayed with the first (0) node in the center, the second node (1) at the
    top, with the rest following in a counterclockwise manner. (0) is the node
    connected to all other nodes.

    The star graph is a good opportunity to compare efficiency of filling a
    position dictionary vs. using the spring-layout algorithm for plotting. As
    far as display, the spring-layout should push all other nodes away from the
    (0) node, and thus look very similar to this constructor's positioning.

    EXAMPLES::

        sage: import networkx

    Compare the plots::

        sage: n = networkx.star_graph(23)
        sage: spring23 = Graph(n)
        sage: posdict23 = graphs.StarGraph(23)
        sage: spring23.show() # long time
        sage: posdict23.show() # long time

    View many star graphs as a Sage Graphics Array

    With this constructor (i.e., the position dictionary filled)

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     k = graphs.StarGraph(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

    Compared to plotting with the spring-layout algorithm

    ::

        sage: g = []
        sage: j = []
        sage: for i in range(9):
        ....:     spr = networkx.star_graph(i+3)
        ....:     k = Graph(spr)
        ....:     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
    """
    G = Graph({0: list(range(1, n + 1))}, name="Star graph")
    G.set_pos({0:(0, 0)})
    G._circle_embedding(list(range(1, n + 1)), angle=pi/2)
    return G