Skip to content

Commit 0413366

Browse files
author
Release Manager
committed
sagemathgh-39266: add parameter immutable to generators in `sage/graphs/digraph_generators.py` (part 2) Following sagemath#39264, we add parameter immutable to `DeBruijn`, `GeneralizedDeBruijn`, `Kautz` and `ImaseItoh`. We also add parameter `name` to `GeneralizedDeBruijn` and `ImaseItoh` to ease calls from `DeBruijn` and `Kautz`. This PR is motivated by discussions in sagemath#39177. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - sagemath#12345: short description why this is a dependency --> <!-- - sagemath#34567: ... --> URL: sagemath#39266 Reported by: David Coudert Reviewer(s): David Coudert, Frédéric Chapoton
2 parents e080610 + c08051e commit 0413366

File tree

1 file changed

+71
-44
lines changed

1 file changed

+71
-44
lines changed

src/sage/graphs/digraph_generators.py

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ def Circulant(self, n, integers, immutable=False):
994994
G._circle_embedding(list(range(n)))
995995
return G
996996

997-
def DeBruijn(self, k, n, vertices='strings'):
997+
def DeBruijn(self, k, n, vertices='strings', immutable=False):
998998
r"""
999999
Return the De Bruijn digraph with parameters `k,n`.
10001000
@@ -1021,6 +1021,9 @@ def DeBruijn(self, k, n, vertices='strings'):
10211021
are words over an alphabet (default) or integers
10221022
(``vertices='string'``)
10231023
1024+
- ``immutable`` -- boolean (default: ``False``); whether to return
1025+
an immutable or mutable digraph
1026+
10241027
EXAMPLES:
10251028
10261029
de Bruijn digraph of degree 2 and diameter 2::
@@ -1074,40 +1077,48 @@ def DeBruijn(self, k, n, vertices='strings'):
10741077
"""
10751078
from sage.rings.integer import Integer
10761079

1080+
name = f"De Bruijn digraph (k={k}, n={n})"
10771081
if vertices == 'strings':
10781082
from sage.combinat.words.words import Words
10791083

10801084
W = Words(list(range(k)) if isinstance(k, Integer) else k, n)
10811085
A = Words(list(range(k)) if isinstance(k, Integer) else k, 1)
1082-
g = DiGraph(loops=True)
10831086

10841087
if not n:
1085-
g.allow_multiple_edges(True)
1086-
v = W[0]
1087-
vs = v.string_rep()
1088-
for a in A:
1089-
g.add_edge(vs, vs, a.string_rep())
1088+
multiedges = True
1089+
1090+
def edges():
1091+
v = W[0]
1092+
vs = v.string_rep()
1093+
return ((vs, vs, a.string_rep()) for a in A)
1094+
10901095
else:
1091-
for w in W:
1092-
ww = w[1:]
1093-
ws = w.string_rep()
1094-
for a in A:
1095-
g.add_edge(ws, (ww * a).string_rep(), a.string_rep())
1096+
multiedges = False
1097+
1098+
def edges():
1099+
for w in W:
1100+
ww = w[1:]
1101+
ws = w.string_rep()
1102+
yield from ((ws, (ww * a).string_rep(), a.string_rep())
1103+
for a in A)
1104+
1105+
return DiGraph(edges(), format='list_of_edges', name=name,
1106+
loops=True, multiedges=multiedges,
1107+
immutable=immutable)
10961108

10971109
elif vertices == 'integers':
10981110
d = k if isinstance(k, Integer) else len(list(k))
10991111
if not d:
1100-
g = DiGraph(loops=True, multiedges=True)
1101-
else:
1102-
g = digraphs.GeneralizedDeBruijn(d ** n, d)
1112+
return DiGraph(loops=True, multiedges=True, name=name,
1113+
immutable=immutable)
1114+
1115+
return digraphs.GeneralizedDeBruijn(d ** n, d, immutable=immutable,
1116+
name=name)
11031117

11041118
else:
11051119
raise ValueError('unknown type for vertices')
11061120

1107-
g.name("De Bruijn digraph (k={}, n={})".format(k, n))
1108-
return g
1109-
1110-
def GeneralizedDeBruijn(self, n, d):
1121+
def GeneralizedDeBruijn(self, n, d, immutable=False, name=None):
11111122
r"""
11121123
Return the generalized de Bruijn digraph of order `n` and degree `d`.
11131124
@@ -1126,6 +1137,12 @@ def GeneralizedDeBruijn(self, n, d):
11261137
11271138
- ``d`` -- integer; degree of the digraph (must be at least one)
11281139
1140+
- ``immutable`` -- boolean (default: ``False``); whether to return
1141+
an immutable or mutable digraph
1142+
1143+
- ``name`` -- string (default: ``None``); when set, the specified name
1144+
is used instead of the default one
1145+
11291146
.. SEEALSO::
11301147
11311148
* :meth:`sage.graphs.generic_graph.GenericGraph.is_circulant` --
@@ -1159,15 +1176,15 @@ def GeneralizedDeBruijn(self, n, d):
11591176
raise ValueError("order must be greater than or equal to one")
11601177
if d < 1:
11611178
raise ValueError("degree must be greater than or equal to one")
1179+
if name is None:
1180+
name = f"Generalized de Bruijn digraph (n={n}, d={d})"
11621181

1163-
GB = DiGraph(n, loops=True, multiedges=True,
1164-
name="Generalized de Bruijn digraph (n={}, d={})".format(n, d))
1165-
for u in range(n):
1166-
for a in range(u * d, u * d + d):
1167-
GB.add_edge(u, a % n)
1168-
return GB
1182+
edges = ((u, a % n) for u in range(n) for a in range(u * d, u * d + d))
1183+
return DiGraph([range(n), edges], format='vertices_and_edges',
1184+
loops=True, multiedges=True, immutable=immutable,
1185+
name=name)
11691186

1170-
def ImaseItoh(self, n, d):
1187+
def ImaseItoh(self, n, d, immutable=False, name=None):
11711188
r"""
11721189
Return the Imase-Itoh digraph of order `n` and degree `d`.
11731190
@@ -1189,6 +1206,12 @@ def ImaseItoh(self, n, d):
11891206
- ``d`` -- integer; degree of the digraph (must be greater than or
11901207
equal to one)
11911208
1209+
- ``immutable`` -- boolean (default: ``False``); whether to return
1210+
an immutable or mutable digraph
1211+
1212+
- ``name`` -- string (default: ``None``); when set, the specified name
1213+
is used instead of the default one
1214+
11921215
EXAMPLES::
11931216
11941217
sage: II = digraphs.ImaseItoh(8, 2)
@@ -1225,15 +1248,15 @@ def ImaseItoh(self, n, d):
12251248
raise ValueError("order must be greater than or equal to two")
12261249
if d < 1:
12271250
raise ValueError("degree must be greater than or equal to one")
1251+
if name is None:
1252+
name = f"Imase and Itoh digraph (n={n}, d={d})"
12281253

1229-
II = DiGraph(n, loops=True, multiedges=True,
1230-
name="Imase and Itoh digraph (n={}, d={})".format(n, d))
1231-
for u in range(n):
1232-
for a in range(-u * d - d, -u * d):
1233-
II.add_edge(u, a % n)
1234-
return II
1254+
edges = ((u, a % n) for u in range(n) for a in range(-u * d - d, -u * d))
1255+
return DiGraph([range(n), edges], format='vertices_and_edges',
1256+
loops=True, multiedges=True, immutable=immutable,
1257+
name=name)
12351258

1236-
def Kautz(self, k, D, vertices='strings'):
1259+
def Kautz(self, k, D, vertices='strings', immutable=False):
12371260
r"""
12381261
Return the Kautz digraph of degree `d` and diameter `D`.
12391262
@@ -1268,6 +1291,9 @@ def Kautz(self, k, D, vertices='strings'):
12681291
are words over an alphabet (default) or integers
12691292
(``vertices='strings'``)
12701293
1294+
- ``immutable`` -- boolean (default: ``False``); whether to return
1295+
an immutable or mutable digraph
1296+
12711297
EXAMPLES::
12721298
12731299
sage: # needs sage.combinat
@@ -1342,6 +1368,8 @@ def Kautz(self, k, D, vertices='strings'):
13421368

13431369
from sage.rings.integer import Integer
13441370

1371+
name = f"Kautz digraph (k={k}, D={D})"
1372+
13451373
if vertices == 'strings':
13461374
from sage.combinat.words.words import Words
13471375

@@ -1359,26 +1387,25 @@ def Kautz(self, k, D, vertices='strings'):
13591387
V = VV
13601388

13611389
# We now build the set of arcs
1362-
G = DiGraph()
1363-
for u in V:
1364-
us = u.string_rep()
1365-
for a in my_alphabet:
1366-
if not u.has_suffix(a):
1367-
G.add_edge(us, (u[1:] * a).string_rep(),
1368-
a.string_rep())
1390+
def edges():
1391+
for u in V:
1392+
us = u.string_rep()
1393+
yield from ((us, (u[1:] * a).string_rep(), a.string_rep())
1394+
for a in my_alphabet if not u.has_suffix(a))
1395+
1396+
return DiGraph(edges(), format='list_of_edges',
1397+
name=name, immutable=immutable)
13691398

13701399
elif vertices == 'integers':
13711400
d = k if isinstance(k, Integer) else (len(list(k)) - 1)
13721401
if d < 1:
13731402
raise ValueError("degree must be greater than or equal to one")
1374-
G = digraphs.ImaseItoh((d + 1) * (d ** (D - 1)), d)
1403+
return digraphs.ImaseItoh((d + 1) * (d ** (D - 1)), d,
1404+
name=name, immutable=immutable)
13751405

13761406
else:
13771407
raise ValueError('unknown type for vertices')
13781408

1379-
G.name("Kautz digraph (k={}, D={})".format(k, D))
1380-
return G
1381-
13821409
def RandomDirectedAcyclicGraph(self, n, p, weight_max=None):
13831410
r"""
13841411
Return a random (weighted) directed acyclic graph of order `n`.

0 commit comments

Comments
 (0)