| 1 | r""" |
| 2 | Families of graphs |
| 3 | ================== |
| 4 | |
| 5 | This file gathers generators for some families of graphs. |
| 6 | - :meth:`RingedTree <GraphGenerators.RingedTree>` |
| 7 | |
| 8 | |
| 9 | AUTHORS: |
| 10 | |
| 11 | - David Coudert (2012) Ringed Trees |
| 12 | """ |
| 13 | |
| 14 | ################################################################################ |
| 15 | # Copyright (C) 2012 David Coudert <david.coudert@inria.fr> |
| 16 | # |
| 17 | # Distributed under the terms of the GNU General Public License (GPL) |
| 18 | # http://www.gnu.org/licenses/ |
| 19 | ################################################################################ |
| 20 | |
| 21 | # import from Python standard library |
| 22 | from math import sin, cos, pi |
| 23 | |
| 24 | # import from Sage library |
| 25 | from sage.graphs.graph import Graph |
| 26 | |
| 27 | |
| 28 | def RingedTree(self, k): |
| 29 | r""" |
| 30 | Return the ringed tree on k-levels. |
| 31 | |
| 32 | A ringed tree of level `k` is a fully binary tree with `k` levels (counting |
| 33 | the root as a level), in which all vertices at the same level are connected |
| 34 | by a ring. More precisely, we can use a binary string to represent each |
| 35 | vertex in the tree, such that the root (at level 0) is represented by an |
| 36 | empty string, and the left child and the right child of a vertex with string |
| 37 | `\sigma` are represented as `\sigma0` and \sigma1`, respectively. Then, at |
| 38 | each level `i = 1, 2, \cdots , k-1`, we connect two vertices `u` and `v` |
| 39 | represented by binary strings `\sigma_u` and `\sigma_v` if `(\sigma_u + 1) |
| 40 | \pmod{2^i}\equiv \sigma_v`, where the addition treats the binary strings as |
| 41 | the integers they represent. |
| 42 | |
| 43 | INPUT: |
| 44 | |
| 45 | - ``k`` -- the number of levels of the ringed tree. |
| 46 | |
| 47 | EXAMPLE: |
| 48 | |
| 49 | sage: G = graphs.RingedTree(5) |
| 50 | sage: P = G.plot(vertex_labels=False, vertex_size=10) |
| 51 | sage: P.show() # long time |
| 52 | |
| 53 | TEST: |
| 54 | |
| 55 | sage: G = graphs.RingedTree(-1) |
| 56 | Traceback (most recent call last): |
| 57 | ... |
| 58 | ValueError: The number of levels must be >= 1. |
| 59 | """ |
| 60 | if k<1: |
| 61 | raise ValueError('The number of levels must be >= 1.') |
| 62 | |
| 63 | E = [] |
| 64 | W = {} |
| 65 | # We first add the tree edges |
| 66 | W[0] = [''] |
| 67 | for l in xrange(k-1): |
| 68 | W[l+1] = [] |
| 69 | for r in W[l]: |
| 70 | E.append( (r,r+'0') ) |
| 71 | E.append( (r,r+'1') ) |
| 72 | W[l+1].append(r+'0') |
| 73 | W[l+1].append(r+'1') |
| 74 | |
| 75 | # We then add the ring edges and fix positions of vertices for nice drawing |
| 76 | pos_dict = {'':(0,0.2)} |
| 77 | for l in xrange(1,k): |
| 78 | twol = 1<<l |
| 79 | r = 1 if l==1 else 1.5**l |
| 80 | theta0 = pi/twol |
| 81 | pos_dict[ W[l][twol-1] ] = ( r*sin(-theta0), r*cos(-theta0) ) |
| 82 | if l>1: # to avoid adding twice edge ('0','1') |
| 83 | E.append( (W[l][0],W[l][twol-1]) ) |
| 84 | for i in xrange(twol-1): |
| 85 | theta = (2*i+1)*theta0 |
| 86 | pos_dict[ W[l][i] ] = ( r*sin(theta), r*cos(theta) ) |
| 87 | E.append( (W[l][i],W[l][i+1]) ) |
| 88 | |
| 89 | return Graph(E, pos=pos_dict, name='Ringed Tree on '+str(k)+' levels' ) |
| 90 | |