Skip to content

Commit 28e546b

Browse files
committed
add parameter immutable to DeBruijn, Kautz and ImaseItoh
1 parent c9dd1e8 commit 28e546b

File tree

1 file changed

+69
-44
lines changed

1 file changed

+69
-44
lines changed

src/sage/graphs/digraph_generators.py

Lines changed: 69 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ def Circulant(self, n, integers):
950950

951951
return G
952952

953-
def DeBruijn(self, k, n, vertices='strings'):
953+
def DeBruijn(self, k, n, vertices='strings', immutable=True):
954954
r"""
955955
Return the De Bruijn digraph with parameters `k,n`.
956956
@@ -977,6 +977,9 @@ def DeBruijn(self, k, n, vertices='strings'):
977977
are words over an alphabet (default) or integers
978978
(``vertices='string'``)
979979
980+
- ``immutable`` -- boolean (default: ``False``); whether to return
981+
an immutable or mutable digraph.
982+
980983
EXAMPLES:
981984
982985
de Bruijn digraph of degree 2 and diameter 2::
@@ -1030,40 +1033,46 @@ def DeBruijn(self, k, n, vertices='strings'):
10301033
"""
10311034
from sage.rings.integer import Integer
10321035

1036+
name = f"De Bruijn digraph (k={k}, n={n})"
10331037
if vertices == 'strings':
10341038
from sage.combinat.words.words import Words
10351039

10361040
W = Words(list(range(k)) if isinstance(k, Integer) else k, n)
10371041
A = Words(list(range(k)) if isinstance(k, Integer) else k, 1)
1038-
g = DiGraph(loops=True)
10391042

10401043
if not n:
1041-
g.allow_multiple_edges(True)
1042-
v = W[0]
1043-
vs = v.string_rep()
1044-
for a in A:
1045-
g.add_edge(vs, vs, a.string_rep())
1044+
multiedges = True
1045+
def edges():
1046+
v = W[0]
1047+
vs = v.string_rep()
1048+
return ((vs, vs, a.string_rep()) for a in A)
1049+
10461050
else:
1047-
for w in W:
1048-
ww = w[1:]
1049-
ws = w.string_rep()
1050-
for a in A:
1051-
g.add_edge(ws, (ww * a).string_rep(), a.string_rep())
1051+
multiedges = False
1052+
def edges():
1053+
for w in W:
1054+
ww = w[1:]
1055+
ws = w.string_rep()
1056+
yield from ((ws, (ww * a).string_rep(), a.string_rep())
1057+
for a in A)
1058+
1059+
return DiGraph(edges(), format='list_of_edges', name=name,
1060+
loops=True, multiedges=multiedges,
1061+
immutable=immutable)
10521062

10531063
elif vertices == 'integers':
10541064
d = k if isinstance(k, Integer) else len(list(k))
10551065
if not d:
1056-
g = DiGraph(loops=True, multiedges=True)
1057-
else:
1058-
g = digraphs.GeneralizedDeBruijn(d ** n, d)
1066+
return DiGraph(loops=True, multiedges=True, name=name,
1067+
immutable=immutable)
1068+
1069+
return digraphs.GeneralizedDeBruijn(d ** n, d, immutable=immutable,
1070+
name=name)
10591071

10601072
else:
10611073
raise ValueError('unknown type for vertices')
10621074

1063-
g.name("De Bruijn digraph (k={}, n={})".format(k, n))
1064-
return g
1065-
1066-
def GeneralizedDeBruijn(self, n, d):
1075+
def GeneralizedDeBruijn(self, n, d, immutable=False, name=None):
10671076
r"""
10681077
Return the generalized de Bruijn digraph of order `n` and degree `d`.
10691078
@@ -1082,6 +1091,12 @@ def GeneralizedDeBruijn(self, n, d):
10821091
10831092
- ``d`` -- integer; degree of the digraph (must be at least one)
10841093
1094+
- ``immutable`` -- boolean (default: ``False``); whether to return
1095+
an immutable or mutable digraph.
1096+
1097+
- ``name`` -- string (default: ``None``); when set, the specified name
1098+
is used instead of the default one.
1099+
10851100
.. SEEALSO::
10861101
10871102
* :meth:`sage.graphs.generic_graph.GenericGraph.is_circulant` --
@@ -1115,15 +1130,15 @@ def GeneralizedDeBruijn(self, n, d):
11151130
raise ValueError("order must be greater than or equal to one")
11161131
if d < 1:
11171132
raise ValueError("degree must be greater than or equal to one")
1133+
if name is None:
1134+
name = f"Generalized de Bruijn digraph (n={n}, d={d})"
11181135

1119-
GB = DiGraph(n, loops=True, multiedges=True,
1120-
name="Generalized de Bruijn digraph (n={}, d={})".format(n, d))
1121-
for u in range(n):
1122-
for a in range(u * d, u * d + d):
1123-
GB.add_edge(u, a % n)
1124-
return GB
1136+
edges = ((u, a % n) for u in range(n) for a in range(u * d, u * d + d))
1137+
return DiGraph([range(n), edges], format='vertices_and_edges',
1138+
loops=True, multiedges=True, immutable=immutable,
1139+
name=name)
11251140

1126-
def ImaseItoh(self, n, d):
1141+
def ImaseItoh(self, n, d, immutable=False, name=None):
11271142
r"""
11281143
Return the Imase-Itoh digraph of order `n` and degree `d`.
11291144
@@ -1145,6 +1160,12 @@ def ImaseItoh(self, n, d):
11451160
- ``d`` -- integer; degree of the digraph (must be greater than or
11461161
equal to one)
11471162
1163+
- ``immutable`` -- boolean (default: ``False``); whether to return
1164+
an immutable or mutable digraph.
1165+
1166+
- ``name`` -- string (default: ``None``); when set, the specified name
1167+
is used instead of the default one.
1168+
11481169
EXAMPLES::
11491170
11501171
sage: II = digraphs.ImaseItoh(8, 2)
@@ -1181,15 +1202,15 @@ def ImaseItoh(self, n, d):
11811202
raise ValueError("order must be greater than or equal to two")
11821203
if d < 1:
11831204
raise ValueError("degree must be greater than or equal to one")
1205+
if name is None:
1206+
name = f"Imase and Itoh digraph (n={n}, d={d})"
11841207

1185-
II = DiGraph(n, loops=True, multiedges=True,
1186-
name="Imase and Itoh digraph (n={}, d={})".format(n, d))
1187-
for u in range(n):
1188-
for a in range(-u * d - d, -u * d):
1189-
II.add_edge(u, a % n)
1190-
return II
1208+
edges = ((u, a % n) for u in range(n) for a in range(-u * d - d, -u * d))
1209+
return DiGraph([range(n), edges], format='vertices_and_edges',
1210+
loops=True, multiedges=True, immutable=immutable,
1211+
name=name)
11911212

1192-
def Kautz(self, k, D, vertices='strings'):
1213+
def Kautz(self, k, D, vertices='strings', immutable=False):
11931214
r"""
11941215
Return the Kautz digraph of degree `d` and diameter `D`.
11951216
@@ -1224,6 +1245,9 @@ def Kautz(self, k, D, vertices='strings'):
12241245
are words over an alphabet (default) or integers
12251246
(``vertices='strings'``)
12261247
1248+
- ``immutable`` -- boolean (default: ``False``); whether to return
1249+
an immutable or mutable digraph.
1250+
12271251
EXAMPLES::
12281252
12291253
sage: # needs sage.combinat
@@ -1298,6 +1322,8 @@ def Kautz(self, k, D, vertices='strings'):
12981322

12991323
from sage.rings.integer import Integer
13001324

1325+
name = f"Kautz digraph (k={k}, D={D})"
1326+
13011327
if vertices == 'strings':
13021328
from sage.combinat.words.words import Words
13031329

@@ -1315,26 +1341,25 @@ def Kautz(self, k, D, vertices='strings'):
13151341
V = VV
13161342

13171343
# We now build the set of arcs
1318-
G = DiGraph()
1319-
for u in V:
1320-
us = u.string_rep()
1321-
for a in my_alphabet:
1322-
if not u.has_suffix(a):
1323-
G.add_edge(us, (u[1:] * a).string_rep(),
1324-
a.string_rep())
1344+
def edges():
1345+
for u in V:
1346+
us = u.string_rep()
1347+
yield from ((us, (u[1:] * a).string_rep(), a.string_rep())
1348+
for a in my_alphabet if not u.has_suffix(a))
1349+
1350+
return DiGraph(edges(), format='list_of_edges',
1351+
name=name, immutable=immutable)
13251352

13261353
elif vertices == 'integers':
13271354
d = k if isinstance(k, Integer) else (len(list(k)) - 1)
13281355
if d < 1:
13291356
raise ValueError("degree must be greater than or equal to one")
1330-
G = digraphs.ImaseItoh((d + 1) * (d ** (D - 1)), d)
1357+
return digraphs.ImaseItoh((d + 1) * (d ** (D - 1)), d,
1358+
name=name, immutable=immutable)
13311359

13321360
else:
13331361
raise ValueError('unknown type for vertices')
13341362

1335-
G.name("Kautz digraph (k={}, D={})".format(k, D))
1336-
return G
1337-
13381363
def RandomDirectedAcyclicGraph(self, n, p, weight_max=None):
13391364
r"""
13401365
Return a random (weighted) directed acyclic graph of order `n`.

0 commit comments

Comments
 (0)