Skip to content

Commit 679065d

Browse files
committed
#39753: redo the PR
1 parent 871ba9d commit 679065d

File tree

9 files changed

+954
-845
lines changed

9 files changed

+954
-845
lines changed

src/doc/en/reference/graphs/index.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,17 @@ Constructors and databases
2828
sage/graphs/graph_generators_pyx
2929
sage/graphs/graph_database
3030
sage/graphs/strongly_regular_db
31-
sage/graphs/generators/distance_regular
32-
sage/graphs/generators/classical_geometries
33-
sage/graphs/generators/families
3431
sage/graphs/generators/basic
3532
sage/graphs/generators/chessboard
33+
sage/graphs/generators/classical_geometries
34+
sage/graphs/generators/degree_sequence
35+
sage/graphs/generators/distance_regular
36+
sage/graphs/generators/families
3637
sage/graphs/generators/intersection
3738
sage/graphs/generators/platonic_solids
3839
sage/graphs/generators/random
3940
sage/graphs/generators/smallgraphs
41+
sage/graphs/generators/trees
4042
sage/graphs/generators/world_map
4143

4244
sage/graphs/isgci
@@ -84,7 +86,6 @@ Libraries of algorithms
8486
sage/graphs/line_graph
8587
sage/graphs/spanning_tree
8688
sage/graphs/pq_trees
87-
sage/graphs/trees
8889
sage/graphs/matching
8990
sage/graphs/matchpoly
9091
sage/graphs/genus

src/sage/graphs/generators/families.py

Lines changed: 1 addition & 336 deletions
Original file line numberDiff line numberDiff line change
@@ -491,107 +491,6 @@ def HammingGraph(n, q, X=None):
491491
return g
492492

493493

494-
def BalancedTree(r, h):
495-
r"""
496-
Return the perfectly balanced tree of height `h \geq 1`,
497-
whose root has degree `r \geq 2`.
498-
499-
The number of vertices of this graph is
500-
`1 + r + r^2 + \cdots + r^h`, that is,
501-
`\frac{r^{h+1} - 1}{r - 1}`. The number of edges is one
502-
less than the number of vertices.
503-
504-
INPUT:
505-
506-
- ``r`` -- positive integer `\geq 2`; the degree of the root node
507-
508-
- ``h`` -- positive integer `\geq 1`; the height of the balanced tree
509-
510-
OUTPUT:
511-
512-
The perfectly balanced tree of height `h \geq 1` and whose root has
513-
degree `r \geq 2`.
514-
515-
EXAMPLES:
516-
517-
A balanced tree whose root node has degree `r = 2`, and of height
518-
`h = 1`, has order 3 and size 2::
519-
520-
sage: G = graphs.BalancedTree(2, 1); G
521-
Balanced tree: Graph on 3 vertices
522-
sage: G.order()
523-
3
524-
sage: G.size()
525-
2
526-
sage: r = 2; h = 1
527-
sage: v = 1 + r
528-
sage: v; v - 1
529-
3
530-
2
531-
532-
Plot a balanced tree of height 5, whose root node has degree `r = 3`::
533-
534-
sage: G = graphs.BalancedTree(3, 5)
535-
sage: G.plot() # long time # needs sage.plot
536-
Graphics object consisting of 728 graphics primitives
537-
538-
A tree is bipartite. If its vertex set is finite, then it is planar. ::
539-
540-
sage: # needs networkx
541-
sage: r = randint(2, 5); h = randint(1, 7)
542-
sage: T = graphs.BalancedTree(r, h)
543-
sage: T.is_bipartite()
544-
True
545-
sage: T.is_planar()
546-
True
547-
sage: v = (r^(h + 1) - 1) / (r - 1)
548-
sage: T.order() == v
549-
True
550-
sage: T.size() == v - 1
551-
True
552-
553-
TESTS:
554-
555-
Normally we would only consider balanced trees whose root node
556-
has degree `r \geq 2`, but the construction degenerates
557-
gracefully::
558-
559-
sage: graphs.BalancedTree(1, 10)
560-
Balanced tree: Graph on 11 vertices
561-
562-
Similarly, we usually want the tree must have height `h \geq 1`
563-
but the algorithm also degenerates gracefully here::
564-
565-
sage: graphs.BalancedTree(3, 0)
566-
Balanced tree: Graph on 1 vertex
567-
568-
The construction is the same as the one of networkx::
569-
570-
sage: # needs networkx
571-
sage: import networkx
572-
sage: r = randint(2, 4); h = randint(1, 5)
573-
sage: T = graphs.BalancedTree(r, h)
574-
sage: N = Graph(networkx.balanced_tree(r, h), name="Balanced tree")
575-
sage: T.is_isomorphic(N)
576-
True
577-
"""
578-
# Compute the number of vertices per level of the tree
579-
order = [r**l for l in range(h + 1)]
580-
# Compute the first index of the vertices of a level
581-
begin = [0]
582-
begin.extend(begin[-1] + val for val in order)
583-
# The number of vertices of the tree is the first index of level h + 1
584-
T = Graph(begin[-1], name="Balanced tree")
585-
586-
# Add edges of the r-ary tree
587-
for level in range(h):
588-
start = begin[level + 1]
589-
for u in range(begin[level], begin[level + 1]):
590-
T.add_edges((u, v) for v in range(start, start + r))
591-
start += r
592-
return T
593-
594-
595494
def BarbellGraph(n1, n2):
596495
r"""
597496
Return a barbell graph with `2 n_1 + n_2` nodes.
@@ -1608,68 +1507,6 @@ def FuzzyBallGraph(partition, q):
16081507
return g
16091508

16101509

1611-
def FibonacciTree(n):
1612-
r"""
1613-
Return the graph of the Fibonacci Tree `F_{i}` of order `n`.
1614-
1615-
The Fibonacci tree `F_{i}` is recursively defined as the tree
1616-
with a root vertex and two attached child trees `F_{i-1}` and
1617-
`F_{i-2}`, where `F_{1}` is just one vertex and `F_{0}` is empty.
1618-
1619-
INPUT:
1620-
1621-
- ``n`` -- the recursion depth of the Fibonacci Tree
1622-
1623-
EXAMPLES::
1624-
1625-
sage: g = graphs.FibonacciTree(3) # needs sage.libs.pari
1626-
sage: g.is_tree() # needs sage.libs.pari
1627-
True
1628-
1629-
::
1630-
1631-
sage: l1 = [ len(graphs.FibonacciTree(_)) + 1 for _ in range(6) ] # needs sage.libs.pari
1632-
sage: l2 = list(fibonacci_sequence(2,8)) # needs sage.libs.pari
1633-
sage: l1 == l2 # needs sage.libs.pari
1634-
True
1635-
1636-
AUTHORS:
1637-
1638-
- Harald Schilly and Yann Laigle-Chapuy (2010-03-25)
1639-
"""
1640-
T = Graph(name="Fibonacci-Tree-%d" % n)
1641-
if n == 1:
1642-
T.add_vertex(0)
1643-
if n < 2:
1644-
return T
1645-
1646-
from sage.combinat.combinat import fibonacci_sequence
1647-
F = list(fibonacci_sequence(n + 2))
1648-
s = 1.618 ** (n / 1.618 - 1.618)
1649-
pos = {}
1650-
1651-
def fib(level, node, y):
1652-
pos[node] = (node, y)
1653-
if level < 2:
1654-
return
1655-
level -= 1
1656-
y -= s
1657-
diff = F[level]
1658-
T.add_edge(node, node - diff)
1659-
if level == 1: # only one child
1660-
pos[node - diff] = (node, y)
1661-
return
1662-
T.add_edge(node, node + diff)
1663-
fib(level, node - diff, y)
1664-
fib(level - 1, node + diff, y)
1665-
1666-
T.add_vertices(range(sum(F[:-1])))
1667-
fib(n, F[n + 1] - 1, 0)
1668-
T.set_pos(pos)
1669-
1670-
return T
1671-
1672-
16731510
def GeneralizedPetersenGraph(n, k):
16741511
r"""
16751512
Return a generalized Petersen graph with `2n` nodes. The variables
@@ -3564,179 +3401,6 @@ def WindmillGraph(k, n):
35643401
return G
35653402

35663403

3567-
def trees(vertices):
3568-
r"""
3569-
Return a generator of the distinct trees on a fixed number of vertices.
3570-
3571-
INPUT:
3572-
3573-
- ``vertices`` -- the size of the trees created
3574-
3575-
OUTPUT:
3576-
3577-
A generator which creates an exhaustive, duplicate-free listing
3578-
of the connected free (unlabeled) trees with ``vertices`` number
3579-
of vertices. A tree is a graph with no cycles.
3580-
3581-
ALGORITHM:
3582-
3583-
Uses an algorithm that generates each new tree
3584-
in constant time. See the documentation for, and implementation
3585-
of, the :mod:`sage.graphs.trees` module, including a citation.
3586-
3587-
EXAMPLES:
3588-
3589-
We create an iterator, then loop over its elements. ::
3590-
3591-
sage: tree_iterator = graphs.trees(7)
3592-
sage: for T in tree_iterator:
3593-
....: print(T.degree_sequence())
3594-
[2, 2, 2, 2, 2, 1, 1]
3595-
[3, 2, 2, 2, 1, 1, 1]
3596-
[3, 2, 2, 2, 1, 1, 1]
3597-
[4, 2, 2, 1, 1, 1, 1]
3598-
[3, 3, 2, 1, 1, 1, 1]
3599-
[3, 3, 2, 1, 1, 1, 1]
3600-
[4, 3, 1, 1, 1, 1, 1]
3601-
[3, 2, 2, 2, 1, 1, 1]
3602-
[4, 2, 2, 1, 1, 1, 1]
3603-
[5, 2, 1, 1, 1, 1, 1]
3604-
[6, 1, 1, 1, 1, 1, 1]
3605-
3606-
The number of trees on the first few vertex counts.
3607-
This is sequence A000055 in Sloane's OEIS. ::
3608-
3609-
sage: [len(list(graphs.trees(i))) for i in range(0, 15)]
3610-
[1, 1, 1, 1, 2, 3, 6, 11, 23, 47, 106, 235, 551, 1301, 3159]
3611-
"""
3612-
from sage.graphs.trees import TreeIterator
3613-
return iter(TreeIterator(vertices))
3614-
3615-
3616-
def nauty_gentreeg(options='', debug=False):
3617-
r"""
3618-
Return a generator which creates non-isomorphic trees from nauty's gentreeg
3619-
program.
3620-
3621-
INPUT:
3622-
3623-
- ``options`` -- string (default: ``""``); a string passed to ``gentreeg``
3624-
as if it was run at a system command line. At a minimum, you *must* pass
3625-
the number of vertices you desire. Sage expects the graphs to be in
3626-
nauty's "sparse6" format, do not set an option to change this default or
3627-
results will be unpredictable.
3628-
3629-
- ``debug`` -- boolean (default: ``False``); if ``True`` the first line of
3630-
``gentreeg``'s output to standard error is captured and the first call to
3631-
the generator's ``next()`` function will return this line as a string. A
3632-
line leading with ">A" indicates a successful initiation of the program
3633-
with some information on the arguments, while a line beginning with ">E"
3634-
indicates an error with the input.
3635-
3636-
The possible options, obtained as output of ``gentreeg -help``::
3637-
3638-
n : the number of vertices. Must be in range 1..128
3639-
res/mod : only generate subset res out of subsets 0..mod-1
3640-
-D<int> : an upper bound for the maximum degree
3641-
-Z<int>:<int> : bounds on the diameter
3642-
-q : suppress auxiliary output
3643-
3644-
Options which cause ``gentreeg`` to use an output format different than the
3645-
sparse6 format are not listed above (-p, -l, -u) as they will confuse the
3646-
creation of a Sage graph. The res/mod option can be useful when using the
3647-
output in a routine run several times in parallel.
3648-
3649-
OUTPUT:
3650-
3651-
A generator which will produce the graphs as Sage graphs. These will be
3652-
simple graphs: no loops, no multiple edges, no directed edges.
3653-
3654-
.. SEEALSO::
3655-
3656-
:meth:`trees` -- another generator of trees
3657-
3658-
EXAMPLES:
3659-
3660-
The generator can be used to construct trees for testing, one at a time
3661-
(usually inside a loop). Or it can be used to create an entire list all at
3662-
once if there is sufficient memory to contain it::
3663-
3664-
sage: gen = graphs.nauty_gentreeg("4")
3665-
sage: next(gen)
3666-
Graph on 4 vertices
3667-
sage: next(gen)
3668-
Graph on 4 vertices
3669-
sage: next(gen)
3670-
Traceback (most recent call last):
3671-
...
3672-
StopIteration
3673-
3674-
The number of trees on the first few vertex counts. This agrees with
3675-
:oeis:`A000055`::
3676-
3677-
sage: [len(list(graphs.nauty_gentreeg(str(i)))) for i in range(1, 15)]
3678-
[1, 1, 1, 2, 3, 6, 11, 23, 47, 106, 235, 551, 1301, 3159]
3679-
3680-
The ``debug`` switch can be used to examine ``gentreeg``'s reaction to the
3681-
input in the ``options`` string. We illustrate success. (A failure will be
3682-
a string beginning with ">E".) Passing the "-q" switch to ``gentreeg`` will
3683-
suppress the indicator of a successful initiation, and so the first returned
3684-
value might be an empty string if ``debug`` is ``True``::
3685-
3686-
sage: gen = graphs.nauty_gentreeg("4", debug=True)
3687-
sage: print(next(gen))
3688-
>A ...gentreeg ...
3689-
sage: gen = graphs.nauty_gentreeg("4 -q", debug=True)
3690-
sage: next(gen)
3691-
''
3692-
3693-
TESTS:
3694-
3695-
The number `n` of vertices must be in range 1..128::
3696-
3697-
sage: list(graphs.nauty_gentreeg("0", debug=False))
3698-
Traceback (most recent call last):
3699-
...
3700-
ValueError: wrong format of parameter options
3701-
sage: list(graphs.nauty_gentreeg("0", debug=True))
3702-
['>E gentreeg: n must be in the range 1..128\n']
3703-
sage: list(graphs.nauty_gentreeg("200", debug=True))
3704-
['>E gentreeg: n must be in the range 1..128\n']
3705-
3706-
Wrong input::
3707-
3708-
sage: list(graphs.nauty_gentreeg("3 -x", debug=False))
3709-
Traceback (most recent call last):
3710-
...
3711-
ValueError: wrong format of parameter options
3712-
sage: list(graphs.nauty_gentreeg("3 -x", debug=True))
3713-
['>E Usage: ...gentreeg [-D#] [-Z#:#] [-ulps] [-q] n... [res/mod] ...
3714-
sage: list(graphs.nauty_gentreeg("3", debug=True))
3715-
['>A ...gentreeg ...\n', Graph on 3 vertices]
3716-
"""
3717-
import shlex
3718-
from sage.features.nauty import NautyExecutable
3719-
gen_path = NautyExecutable("gentreeg").absolute_filename()
3720-
sp = subprocess.Popen(shlex.quote(gen_path) + " {0}".format(options), shell=True,
3721-
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
3722-
stderr=subprocess.PIPE, close_fds=True,
3723-
encoding='latin-1')
3724-
msg = sp.stderr.readline()
3725-
if debug:
3726-
yield msg
3727-
elif msg.startswith('>E'):
3728-
raise ValueError('wrong format of parameter options')
3729-
gen = sp.stdout
3730-
while True:
3731-
try:
3732-
s = next(gen)
3733-
except StopIteration:
3734-
# Exhausted list of graphs from nauty geng
3735-
return
3736-
G = Graph(s[:-1], format='sparse6', loops=False, multiedges=False)
3737-
yield G
3738-
3739-
37403404
def RingedTree(k, vertex_labels=True):
37413405
r"""
37423406
Return the ringed tree on k-levels.
@@ -3785,6 +3449,7 @@ def RingedTree(k, vertex_labels=True):
37853449
raise ValueError('The number of levels must be >= 1.')
37863450

37873451
# Creating the Balanced tree, which contains most edges already
3452+
from sage.graphs.generators.trees import BalancedTree
37883453
g = BalancedTree(2, k - 1)
37893454
g.name('Ringed Tree on ' + str(k) + ' levels')
37903455

0 commit comments

Comments
 (0)