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
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
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
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
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
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
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
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
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
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
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