def Kautz(self, k, D, vertices='strings'): r""" Returns the Kautz digraph of degree `d` and diameter `D`. The Kautz digraph has been defined in [Kautz68]_. The Kautz digraph of degree `d` and diameter `D` has `d^{D-1}(d+1)` vertices. This digraph is build upon a set of vertices equal to the set of words of length `D` from an alphabet of `d+1` letters such that consecutive letters are differents. There is an arc from vertex `u` to vertex `v` if `v` can be obtained from `u` by removing the leftmost letter and adding a new letter, distinct from the rightmost letter of `u`, at the right end. The Kautz digraph of degree `d` and diameter `D` is isomorphic to the digraph of Imase and Itoh [II83]_ of degree `d` and order `d^{D-1}(d+1)`. See also the :wikipedia:`Wikipedia article on Kautz Graphs <Kautz_graph>`. INPUTS: - ``k`` -- Two possibilities for this parameter : - An integer equal to the degree of the digraph to be produced, that is the cardinality minus one of the alphabet to use. - An iterable object to be used as the set of letters. The degree of the resulting digraph is the cardinality of the set of letters minus one. - ``D`` -- An integer equal to the diameter of the digraph, and also to the length of a vertex label when ``vertices == 'strings'``. - ``vertices`` -- 'strings' (default) or 'integers', specifying whether the vertices are words build upon an alphabet or integers. EXAMPLES:: sage: K = digraphs.Kautz(2, 3) sage: K.is_isomorphic(digraphs.ImaseItoh(12, 2), certify = True) (True, {'010': 0, '012': 1, '020': 3, '021': 2, '101': 11, '102': 10, '120': 9, '121': 8, '201': 5, '202': 4, '210': 6, '212': 7}) sage: K = digraphs.Kautz([1,'a','B'], 2) sage: K.edges() [('1B', 'B1', '1'), ('1B', 'Ba', 'a'), ('1a', 'a1', '1'), ('1a', 'aB', 'B'), ('B1', '1B', 'B'), ('B1', '1a', 'a'), ('Ba', 'a1', '1'), ('Ba', 'aB', 'B'), ('a1', '1B', 'B'), ('a1', '1a', 'a'), ('aB', 'B1', '1'), ('aB', 'Ba', 'a')] sage: K = digraphs.Kautz([1,'aA','BB'], 2) sage: K.edges() [('1,BB', 'BB,1', '1'), ('1,BB', 'BB,aA', 'aA'), ('1,aA', 'aA,1', '1'), ('1,aA', 'aA,BB', 'BB'), ('BB,1', '1,BB', 'BB'), ('BB,1', '1,aA', 'aA'), ('BB,aA', 'aA,1', '1'), ('BB,aA', 'aA,BB', 'BB'), ('aA,1', '1,BB', 'BB'), ('aA,1', '1,aA', 'aA'), ('aA,BB', 'BB,1', '1'), ('aA,BB', 'BB,aA', 'aA')] TESTS: An exception is raised when the degree is less than one:: sage: G = digraphs.Kautz(0, 2) Traceback (most recent call last): ... ValueError: Kautz digraphs are defined for degree at least one. sage: G = digraphs.Kautz(['a'], 2) Traceback (most recent call last): ... ValueError: Kautz digraphs are defined for degree at least one. An exception is raised when the diameter of the graph is less than one:: sage: G = digraphs.Kautz(2, 0) Traceback (most recent call last): ... ValueError: Kautz digraphs are defined for diameter at least one. REFERENCE: .. [Kautz68] W. H. Kautz. Bounds on directed (d, k) graphs. Theory of cellular logic networks and machines, AFCRL-68-0668, SRI Project 7258, Final Rep., pp. 20-28, 1968. """ if D < 1: raise ValueError( "Kautz digraphs are defined for diameter at least one.") from sage.combinat.words.words import Words from sage.rings.integer import Integer my_alphabet = Words( [str(i) for i in range(k + 1)] if isinstance(k, Integer) else k, 1) if my_alphabet.size_of_alphabet() < 2: raise ValueError( "Kautz digraphs are defined for degree at least one.") if vertices == 'strings': # We start building the set of vertices V = [i for i in my_alphabet] for i in range(D - 1): VV = [] for w in V: VV += [w * a for a in my_alphabet if not w.has_suffix(a)] V = VV # We now build the set of arcs G = DiGraph() for u in V: for a in my_alphabet: if not u.has_suffix(a): G.add_edge(u.string_rep(), (u[1:] * a).string_rep(), a.string_rep()) else: d = my_alphabet.size_of_alphabet() - 1 G = digraphs.ImaseItoh((d + 1) * (d**(D - 1)), d) G.name("Kautz digraph (k=%s, D=%s)" % (k, D)) return G
def Kautz(self, k, D, vertices = 'strings'): r""" Returns the Kautz digraph of degree `d` and diameter `D`. The Kautz digraph has been defined in [Kautz68]_. The Kautz digraph of degree `d` and diameter `D` has `d^{D-1}(d+1)` vertices. This digraph is build upon a set of vertices equal to the set of words of length `D` from an alphabet of `d+1` letters such that consecutive letters are differents. There is an arc from vertex `u` to vertex `v` if `v` can be obtained from `u` by removing the leftmost letter and adding a new letter, distinct from the rightmost letter of `u`, at the right end. The Kautz digraph of degree `d` and diameter `D` is isomorphic to the digraph of Imase and Itoh [II83]_ of degree `d` and order `d^{D-1}(d+1)`. See also the :wikipedia:`Wikipedia article on Kautz Graphs <Kautz_graph>`. INPUTS: - ``k`` -- Two possibilities for this parameter : - An integer equal to the degree of the digraph to be produced, that is the cardinality minus one of the alphabet to use. - An iterable object to be used as the set of letters. The degree of the resulting digraph is the cardinality of the set of letters minus one. - ``D`` -- An integer equal to the diameter of the digraph, and also to the length of a vertex label when ``vertices == 'strings'``. - ``vertices`` -- 'strings' (default) or 'integers', specifying whether the vertices are words build upon an alphabet or integers. EXAMPLES:: sage: K = digraphs.Kautz(2, 3) sage: K.is_isomorphic(digraphs.ImaseItoh(12, 2), certify = True) (True, {'010': 0, '012': 1, '020': 3, '021': 2, '101': 11, '102': 10, '120': 9, '121': 8, '201': 5, '202': 4, '210': 6, '212': 7}) sage: K = digraphs.Kautz([1,'a','B'], 2) sage: K.edges() [('1B', 'B1', '1'), ('1B', 'Ba', 'a'), ('1a', 'a1', '1'), ('1a', 'aB', 'B'), ('B1', '1B', 'B'), ('B1', '1a', 'a'), ('Ba', 'a1', '1'), ('Ba', 'aB', 'B'), ('a1', '1B', 'B'), ('a1', '1a', 'a'), ('aB', 'B1', '1'), ('aB', 'Ba', 'a')] sage: K = digraphs.Kautz([1,'aA','BB'], 2) sage: K.edges() [('1,BB', 'BB,1', '1'), ('1,BB', 'BB,aA', 'aA'), ('1,aA', 'aA,1', '1'), ('1,aA', 'aA,BB', 'BB'), ('BB,1', '1,BB', 'BB'), ('BB,1', '1,aA', 'aA'), ('BB,aA', 'aA,1', '1'), ('BB,aA', 'aA,BB', 'BB'), ('aA,1', '1,BB', 'BB'), ('aA,1', '1,aA', 'aA'), ('aA,BB', 'BB,1', '1'), ('aA,BB', 'BB,aA', 'aA')] TESTS: An exception is raised when the degree is less than one:: sage: G = digraphs.Kautz(0, 2) Traceback (most recent call last): ... ValueError: Kautz digraphs are defined for degree at least one. sage: G = digraphs.Kautz(['a'], 2) Traceback (most recent call last): ... ValueError: Kautz digraphs are defined for degree at least one. An exception is raised when the diameter of the graph is less than one:: sage: G = digraphs.Kautz(2, 0) Traceback (most recent call last): ... ValueError: Kautz digraphs are defined for diameter at least one. REFERENCE: .. [Kautz68] W. H. Kautz. Bounds on directed (d, k) graphs. Theory of cellular logic networks and machines, AFCRL-68-0668, SRI Project 7258, Final Rep., pp. 20-28, 1968. """ if D < 1: raise ValueError("Kautz digraphs are defined for diameter at least one.") from sage.combinat.words.words import Words from sage.rings.integer import Integer my_alphabet = Words([str(i) for i in range(k+1)] if isinstance(k, Integer) else k, 1) if my_alphabet.size_of_alphabet() < 2: raise ValueError("Kautz digraphs are defined for degree at least one.") if vertices == 'strings': # We start building the set of vertices V = [i for i in my_alphabet] for i in range(D-1): VV = [] for w in V: VV += [w*a for a in my_alphabet if not w.has_suffix(a) ] V = VV # We now build the set of arcs G = DiGraph() for u in V: for a in my_alphabet: if not u.has_suffix(a): G.add_edge(u.string_rep(), (u[1:]*a).string_rep(), a.string_rep()) else: d = my_alphabet.size_of_alphabet()-1 G = digraphs.ImaseItoh( (d+1)*(d**(D-1)), d) G.name( "Kautz digraph (k=%s, D=%s)"%(k,D) ) return G
def DeBruijn(self, k, n, vertices='strings'): r""" Returns the De Bruijn digraph with parameters `k,n`. The De Bruijn digraph with parameters `k,n` is built upon a set of vertices equal to the set of words of length `n` from a dictionary of `k` letters. In this digraph, there is an arc `w_1w_2` if `w_2` can be obtained from `w_1` by removing the leftmost letter and adding a new letter at its right end. For more information, see the :wikipedia:`Wikipedia article on De Bruijn graph <De_Bruijn_graph>`. INPUT: - ``k`` -- Two possibilities for this parameter : - An integer equal to the cardinality of the alphabet to use, that is the degree of the digraph to be produced. - An iterable object to be used as the set of letters. The degree of the resulting digraph is the cardinality of the set of letters. - ``n`` -- An integer equal to the length of words in the De Bruijn digraph when ``vertices == 'strings'``, and also to the diameter of the digraph. - ``vertices`` -- 'strings' (default) or 'integers', specifying whether the vertices are words build upon an alphabet or integers. EXAMPLES:: sage: db=digraphs.DeBruijn(2,2); db De Bruijn digraph (k=2, n=2): Looped digraph on 4 vertices sage: db.order() 4 sage: db.size() 8 TESTS:: sage: digraphs.DeBruijn(5,0) De Bruijn digraph (k=5, n=0): Looped multi-digraph on 1 vertex sage: digraphs.DeBruijn(0,0) De Bruijn digraph (k=0, n=0): Looped multi-digraph on 0 vertices """ from sage.combinat.words.words import Words from sage.rings.integer import Integer W = Words(range(k) if isinstance(k, Integer) else k, n) A = Words(range(k) if isinstance(k, Integer) else k, 1) g = DiGraph(loops=True) if vertices == 'strings': if n == 0: g.allow_multiple_edges(True) v = W[0] for a in A: g.add_edge(v.string_rep(), v.string_rep(), a.string_rep()) else: for w in W: ww = w[1:] for a in A: g.add_edge(w.string_rep(), (ww * a).string_rep(), a.string_rep()) else: d = W.size_of_alphabet() g = digraphs.GeneralizedDeBruijn(d**n, d) g.name("De Bruijn digraph (k=%s, n=%s)" % (k, n)) return g
def DeBruijn(self, k, n, vertices = 'strings'): r""" Returns the De Bruijn digraph with parameters `k,n`. The De Bruijn digraph with parameters `k,n` is built upon a set of vertices equal to the set of words of length `n` from a dictionary of `k` letters. In this digraph, there is an arc `w_1w_2` if `w_2` can be obtained from `w_1` by removing the leftmost letter and adding a new letter at its right end. For more information, see the :wikipedia:`Wikipedia article on De Bruijn graph <De_Bruijn_graph>`. INPUT: - ``k`` -- Two possibilities for this parameter : - An integer equal to the cardinality of the alphabet to use, that is the degree of the digraph to be produced. - An iterable object to be used as the set of letters. The degree of the resulting digraph is the cardinality of the set of letters. - ``n`` -- An integer equal to the length of words in the De Bruijn digraph when ``vertices == 'strings'``, and also to the diameter of the digraph. - ``vertices`` -- 'strings' (default) or 'integers', specifying whether the vertices are words build upon an alphabet or integers. EXAMPLES:: sage: db=digraphs.DeBruijn(2,2); db De Bruijn digraph (k=2, n=2): Looped digraph on 4 vertices sage: db.order() 4 sage: db.size() 8 TESTS:: sage: digraphs.DeBruijn(5,0) De Bruijn digraph (k=5, n=0): Looped multi-digraph on 1 vertex sage: digraphs.DeBruijn(0,0) De Bruijn digraph (k=0, n=0): Looped multi-digraph on 0 vertices """ from sage.combinat.words.words import Words from sage.rings.integer import Integer W = Words(range(k) if isinstance(k, Integer) else k, n) A = Words(range(k) if isinstance(k, Integer) else k, 1) g = DiGraph(loops=True) if vertices == 'strings': if n == 0 : g.allow_multiple_edges(True) v = W[0] for a in A: g.add_edge(v.string_rep(), v.string_rep(), a.string_rep()) else: for w in W: ww = w[1:] for a in A: g.add_edge(w.string_rep(), (ww*a).string_rep(), a.string_rep()) else: d = W.size_of_alphabet() g = digraphs.GeneralizedDeBruijn(d**n, d) g.name( "De Bruijn digraph (k=%s, n=%s)"%(k,n) ) return g