passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
- passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
- passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
- passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
- passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_graphs.py +39 -0
- sage/combinat/abstract_tree.py +2723 -0
- sage/combinat/all__sagemath_graphs.py +34 -0
- sage/combinat/binary_tree.py +5306 -0
- sage/combinat/cluster_algebra_quiver/all.py +22 -0
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
- sage/combinat/cluster_algebra_quiver/interact.py +124 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
- sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
- sage/combinat/designs/MOLS_handbook_data.py +570 -0
- sage/combinat/designs/all.py +58 -0
- sage/combinat/designs/bibd.py +1655 -0
- sage/combinat/designs/block_design.py +1071 -0
- sage/combinat/designs/covering_array.py +269 -0
- sage/combinat/designs/covering_design.py +530 -0
- sage/combinat/designs/database.py +5615 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/designs_pyx.pxd +21 -0
- sage/combinat/designs/designs_pyx.pyx +993 -0
- sage/combinat/designs/difference_family.py +3951 -0
- sage/combinat/designs/difference_matrices.py +279 -0
- sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
- sage/combinat/designs/ext_rep.py +1064 -0
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
- sage/combinat/designs/group_divisible_designs.py +361 -0
- sage/combinat/designs/incidence_structures.py +2357 -0
- sage/combinat/designs/latin_squares.py +581 -0
- sage/combinat/designs/orthogonal_arrays.py +2244 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
- sage/combinat/designs/resolvable_bibd.py +815 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +530 -0
- sage/combinat/designs/twographs.py +306 -0
- sage/combinat/finite_state_machine.py +14874 -0
- sage/combinat/finite_state_machine_generators.py +2006 -0
- sage/combinat/graph_path.py +448 -0
- sage/combinat/interval_posets.py +3908 -0
- sage/combinat/nu_tamari_lattice.py +269 -0
- sage/combinat/ordered_tree.py +1446 -0
- sage/combinat/posets/all.py +46 -0
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/cartesian_product.py +493 -0
- sage/combinat/posets/d_complete.py +182 -0
- sage/combinat/posets/elements.py +273 -0
- sage/combinat/posets/forest.py +30 -0
- sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3672 -0
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +794 -0
- sage/combinat/posets/lattices.py +5117 -0
- sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1037 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2178 -0
- sage/combinat/posets/posets.py +9360 -0
- sage/combinat/rooted_tree.py +1070 -0
- sage/combinat/shard_order.py +239 -0
- sage/combinat/tamari_lattices.py +384 -0
- sage/combinat/yang_baxter_graph.py +923 -0
- sage/databases/all__sagemath_graphs.py +1 -0
- sage/databases/knotinfo_db.py +1231 -0
- sage/ext_data/all__sagemath_graphs.py +1 -0
- sage/ext_data/graphs/graph_plot_js.html +330 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/all.py +42 -0
- sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +320 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/boost_graph.pxd +106 -0
- sage/graphs/base/boost_graph.pyx +3045 -0
- sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/c_graph.pxd +106 -0
- sage/graphs/base/c_graph.pyx +5096 -0
- sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +28 -0
- sage/graphs/base/dense_graph.pyx +801 -0
- sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/graph_backends.pxd +5 -0
- sage/graphs/base/graph_backends.pyx +797 -0
- sage/graphs/base/overview.py +85 -0
- sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/sparse_graph.pxd +90 -0
- sage/graphs/base/sparse_graph.pyx +1653 -0
- sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_dense_graph.pxd +5 -0
- sage/graphs/base/static_dense_graph.pyx +1032 -0
- sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1583 -0
- sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1375 -0
- sage/graphs/bipartite_graph.py +2732 -0
- sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +1038 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +851 -0
- sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +870 -0
- sage/graphs/digraph.py +4754 -0
- sage/graphs/digraph_generators.py +1993 -0
- sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/distances_all_pairs.pxd +12 -0
- sage/graphs/distances_all_pairs.pyx +2938 -0
- sage/graphs/domination.py +1363 -0
- sage/graphs/dot2tex_utils.py +100 -0
- sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/edge_connectivity.pyx +1215 -0
- sage/graphs/generators/all.py +1 -0
- sage/graphs/generators/basic.py +1769 -0
- sage/graphs/generators/chessboard.py +538 -0
- sage/graphs/generators/classical_geometries.py +1611 -0
- sage/graphs/generators/degree_sequence.py +235 -0
- sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4759 -0
- sage/graphs/generators/intersection.py +565 -0
- sage/graphs/generators/platonic_solids.py +262 -0
- sage/graphs/generators/random.py +2623 -0
- sage/graphs/generators/smallgraphs.py +5741 -0
- sage/graphs/generators/world_map.py +724 -0
- sage/graphs/generic_graph.py +26867 -0
- sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1673 -0
- sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +622 -0
- sage/graphs/graph.py +9645 -0
- sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1177 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
- sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +508 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
- sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
- sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
- sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
- sage/graphs/graph_editor.py +82 -0
- sage/graphs/graph_generators.py +3314 -0
- sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +95 -0
- sage/graphs/graph_input.py +812 -0
- sage/graphs/graph_latex.py +2064 -0
- sage/graphs/graph_list.py +410 -0
- sage/graphs/graph_plot.py +1756 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1704 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/independent_sets.pxd +13 -0
- sage/graphs/independent_sets.pyx +402 -0
- sage/graphs/isgci.py +1033 -0
- sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +489 -0
- sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +743 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3590 -0
- sage/graphs/orientations.py +1489 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/path_enumeration.pyx +2040 -0
- sage/graphs/pq_trees.py +1129 -0
- sage/graphs/print_graphs.py +201 -0
- sage/graphs/schnyder.py +865 -0
- sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1872 -0
- sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/trees.pxd +15 -0
- sage/graphs/trees.pyx +310 -0
- sage/graphs/tutte_polynomial.py +713 -0
- sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +604 -0
- sage/groups/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
- sage/knots/all.py +6 -0
- sage/knots/free_knotinfo_monoid.py +507 -0
- sage/knots/gauss_code.py +291 -0
- sage/knots/knot.py +682 -0
- sage/knots/knot_table.py +284 -0
- sage/knots/knotinfo.py +2900 -0
- sage/knots/link.py +4715 -0
- sage/sandpiles/all.py +13 -0
- sage/sandpiles/examples.py +225 -0
- sage/sandpiles/sandpile.py +6365 -0
- sage/topology/all.py +22 -0
- sage/topology/cell_complex.py +1214 -0
- sage/topology/cubical_complex.py +1976 -0
- sage/topology/delta_complex.py +1806 -0
- sage/topology/filtered_simplicial_complex.py +744 -0
- sage/topology/moment_angle_complex.py +823 -0
- sage/topology/simplicial_complex.py +5160 -0
- sage/topology/simplicial_complex_catalog.py +92 -0
- sage/topology/simplicial_complex_examples.py +1680 -0
- sage/topology/simplicial_complex_homset.py +205 -0
- sage/topology/simplicial_complex_morphism.py +836 -0
- sage/topology/simplicial_set.py +4102 -0
- sage/topology/simplicial_set_catalog.py +55 -0
- sage/topology/simplicial_set_constructions.py +2954 -0
- sage/topology/simplicial_set_examples.py +865 -0
- sage/topology/simplicial_set_morphism.py +1464 -0
@@ -0,0 +1,530 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
r"""
|
3
|
+
Covering designs: coverings of `t`-element subsets of a `v`-set by `k`-sets
|
4
|
+
|
5
|
+
A `(v, k, t)` covering design `C` is an incidence structure consisting of a
|
6
|
+
set of points `P` of order `v`, and a set of blocks `B`, where each
|
7
|
+
block contains `k` points of `P`. Every `t`-element subset of `P`
|
8
|
+
must be contained in at least one block.
|
9
|
+
|
10
|
+
If every `t`-set is contained in exactly one block of `C`, then we
|
11
|
+
have a block design. Following the block design implementation, the
|
12
|
+
standard representation of a covering design uses `P = [0, 1, ..., v-1]`.
|
13
|
+
|
14
|
+
In addition to the parameters and incidence structure for a covering
|
15
|
+
design from this database, we include extra information:
|
16
|
+
|
17
|
+
* Best known lower bound on the size of a `(v, k, t)`-covering design
|
18
|
+
* Name of the person(s) who produced the design
|
19
|
+
* Method of construction used
|
20
|
+
* Date when the design was added to the database
|
21
|
+
|
22
|
+
REFERENCES:
|
23
|
+
|
24
|
+
.. [1] La Jolla Covering Repository,
|
25
|
+
https://dmgordon.org/cover
|
26
|
+
|
27
|
+
.. [2] Daniel M. Gordon and Douglas R. Stinson, *Coverings*,
|
28
|
+
Chapter 1 in: Charles J. Colbourn and Jeffrey H. Dinitz,
|
29
|
+
*Handbook of Combinatorial Designs*, 2nd Edition, 2006.
|
30
|
+
https://www.dmgordon.org/papers/hcd.pdf
|
31
|
+
|
32
|
+
AUTHORS:
|
33
|
+
|
34
|
+
- Daniel M. Gordon (2008-12-22): initial version
|
35
|
+
|
36
|
+
Classes and methods
|
37
|
+
-------------------
|
38
|
+
"""
|
39
|
+
# ****************************************************************************
|
40
|
+
# Copyright (C) 2008 Daniel M. Gordon <dmgordo@gmail.com>
|
41
|
+
#
|
42
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
43
|
+
#
|
44
|
+
# The full text of the GPL is available at:
|
45
|
+
#
|
46
|
+
# https://www.gnu.org/licenses/
|
47
|
+
# ****************************************************************************
|
48
|
+
|
49
|
+
from urllib.request import urlopen
|
50
|
+
from ssl import create_default_context as default_context
|
51
|
+
|
52
|
+
from sage.structure.sage_object import SageObject
|
53
|
+
from sage.rings.rational import Rational
|
54
|
+
from sage.arith.misc import binomial
|
55
|
+
from sage.combinat.combination import Combinations
|
56
|
+
from sage.combinat.designs.incidence_structures import IncidenceStructure
|
57
|
+
|
58
|
+
|
59
|
+
def schonheim(v, k, t):
|
60
|
+
r"""
|
61
|
+
Return the Schonheim lower bound for the size of such a covering design.
|
62
|
+
|
63
|
+
INPUT:
|
64
|
+
|
65
|
+
- ``v`` -- integer; size of point set
|
66
|
+
|
67
|
+
- ``k`` -- integer; cardinality of each block
|
68
|
+
|
69
|
+
- ``t`` -- integer; cardinality of sets being covered
|
70
|
+
|
71
|
+
OUTPUT:
|
72
|
+
|
73
|
+
The Schonheim lower bound for such a covering design's size:
|
74
|
+
`C(v, k, t) \leq \lceil(\frac{v}{k} \lceil \frac{v-1}{k-1} \cdots
|
75
|
+
\lceil \frac{v-t+1}{k-t+1} \rceil \cdots \rceil \rceil`
|
76
|
+
|
77
|
+
EXAMPLES::
|
78
|
+
|
79
|
+
sage: from sage.combinat.designs.covering_design import schonheim
|
80
|
+
sage: schonheim(10, 3, 2)
|
81
|
+
17
|
82
|
+
sage: schonheim(32, 16, 8)
|
83
|
+
930
|
84
|
+
"""
|
85
|
+
bound = 1
|
86
|
+
for i in range(t - 1, -1, -1):
|
87
|
+
bound = Rational((bound * (v - i), k - i)).ceil()
|
88
|
+
return bound
|
89
|
+
|
90
|
+
|
91
|
+
def trivial_covering_design(v, k, t):
|
92
|
+
r"""
|
93
|
+
Construct a trivial covering design.
|
94
|
+
|
95
|
+
INPUT:
|
96
|
+
|
97
|
+
- ``v`` -- integer; size of point set
|
98
|
+
|
99
|
+
- ``k`` -- integer; cardinality of each block
|
100
|
+
|
101
|
+
- ``t`` -- integer; cardinality of sets being covered
|
102
|
+
|
103
|
+
OUTPUT:
|
104
|
+
|
105
|
+
A trivial `(v, k, t)` covering design
|
106
|
+
|
107
|
+
EXAMPLES::
|
108
|
+
|
109
|
+
sage: C = trivial_covering_design(8, 3, 1)
|
110
|
+
sage: print(C)
|
111
|
+
C(8, 3, 1) = 3
|
112
|
+
Method: Trivial
|
113
|
+
0 1 2
|
114
|
+
0 6 7
|
115
|
+
3 4 5
|
116
|
+
sage: C = trivial_covering_design(5, 3, 2)
|
117
|
+
sage: print(C)
|
118
|
+
4 <= C(5, 3, 2) <= 10
|
119
|
+
Method: Trivial
|
120
|
+
0 1 2
|
121
|
+
0 1 3
|
122
|
+
0 1 4
|
123
|
+
0 2 3
|
124
|
+
0 2 4
|
125
|
+
0 3 4
|
126
|
+
1 2 3
|
127
|
+
1 2 4
|
128
|
+
1 3 4
|
129
|
+
2 3 4
|
130
|
+
|
131
|
+
.. NOTE::
|
132
|
+
|
133
|
+
Cases are:
|
134
|
+
|
135
|
+
* `t=0`: This could be empty, but it's a useful convention to have
|
136
|
+
one block (which is empty if `k=0`).
|
137
|
+
|
138
|
+
* `t=1` : This contains `\lceil v/k \rceil` blocks:
|
139
|
+
`[0, ..., k-1], [k, ..., 2k-1], ...`. The last block wraps around if
|
140
|
+
`k` does not divide `v`.
|
141
|
+
|
142
|
+
* anything else: Just use every `k`-subset of `[0, 1,..., v-1]`.
|
143
|
+
"""
|
144
|
+
if t == 0: # single block [0, ..., k-1]
|
145
|
+
blk = list(range(k))
|
146
|
+
return CoveringDesign(v, k, t, 1, range(v), [blk], 1, "Trivial")
|
147
|
+
if t == 1: # blocks [0, ..., k-1], [k, ..., 2k-1], ...
|
148
|
+
size = Rational((v, k)).ceil()
|
149
|
+
blocks = [list(range(i * k, (i + 1) * k))
|
150
|
+
for i in range(size - 1)]
|
151
|
+
# last block: if k does not divide v, wrap around
|
152
|
+
blk = list(range((size - 1) * k, v))
|
153
|
+
for j in range(k - len(blk)):
|
154
|
+
blk.append(j)
|
155
|
+
blk.sort()
|
156
|
+
blocks.append(blk)
|
157
|
+
return CoveringDesign(v, k, t, size, range(v), blocks, size, "Trivial")
|
158
|
+
# default case, all k-subsets
|
159
|
+
return CoveringDesign(v, k, t, binomial(v, k), range(v),
|
160
|
+
Combinations(range(v), k), schonheim(v, k, t),
|
161
|
+
"Trivial")
|
162
|
+
|
163
|
+
|
164
|
+
class CoveringDesign(SageObject):
|
165
|
+
"""
|
166
|
+
Covering design.
|
167
|
+
|
168
|
+
INPUT:
|
169
|
+
|
170
|
+
- ``v``, ``k``, ``t`` -- integer parameters of the covering design
|
171
|
+
|
172
|
+
- ``size`` -- integer
|
173
|
+
|
174
|
+
- ``points`` -- list of points (default: `[0, ..., v-1]`)
|
175
|
+
|
176
|
+
- ``blocks``
|
177
|
+
|
178
|
+
- ``low_bd`` -- integer; lower bound for such a design
|
179
|
+
|
180
|
+
- ``method``, ``creator``, ``timestamp`` -- database information
|
181
|
+
"""
|
182
|
+
|
183
|
+
def __init__(self, v=0, k=0, t=0, size=0, points=None, blocks=None,
|
184
|
+
low_bd=0, method='', creator='', timestamp=''):
|
185
|
+
"""
|
186
|
+
EXAMPLES::
|
187
|
+
|
188
|
+
sage: C = CoveringDesign(5, 4, 3, 4, range(5), [[0, 1, 2, 3],
|
189
|
+
....: [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4]], 4,
|
190
|
+
....: 'Lexicographic Covering')
|
191
|
+
sage: print(C)
|
192
|
+
C(5, 4, 3) = 4
|
193
|
+
Method: Lexicographic Covering
|
194
|
+
0 1 2 3
|
195
|
+
0 1 2 4
|
196
|
+
0 1 3 4
|
197
|
+
0 2 3 4
|
198
|
+
"""
|
199
|
+
self.__v = v
|
200
|
+
self.__k = k
|
201
|
+
self.__t = t
|
202
|
+
self.__size = size
|
203
|
+
if low_bd > 0:
|
204
|
+
self.__low_bd = low_bd
|
205
|
+
else:
|
206
|
+
self.__low_bd = schonheim(v, k, t)
|
207
|
+
self.__method = method
|
208
|
+
self.__creator = creator
|
209
|
+
self.__timestamp = timestamp
|
210
|
+
if points is None:
|
211
|
+
points = []
|
212
|
+
if blocks is None:
|
213
|
+
blocks = []
|
214
|
+
self.__incidence_structure = IncidenceStructure(points, blocks)
|
215
|
+
|
216
|
+
def __repr__(self):
|
217
|
+
"""
|
218
|
+
Return the representation of this covering design.
|
219
|
+
|
220
|
+
This has the parameters but not the blocks.
|
221
|
+
|
222
|
+
EXAMPLES::
|
223
|
+
|
224
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
225
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
226
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
227
|
+
sage: C
|
228
|
+
(7, 3, 2)-covering design of size 7
|
229
|
+
Lower bound: 7
|
230
|
+
Method: Projective Plane
|
231
|
+
"""
|
232
|
+
repr = ('(%d, %d, %d)-covering design of size %d\n'
|
233
|
+
% (self.__v, self.__k, self.__t, self.__size))
|
234
|
+
repr += 'Lower bound: %d\n' % (self.__low_bd)
|
235
|
+
if self.__creator:
|
236
|
+
repr += 'Created by: %s\n' % (self.__creator)
|
237
|
+
if self.__method:
|
238
|
+
repr += 'Method: %s\n' % (self.__method)
|
239
|
+
if self.__timestamp:
|
240
|
+
repr += 'Submitted on: %s\n' % (self.__timestamp)
|
241
|
+
return repr[:-1]
|
242
|
+
|
243
|
+
def __str__(self):
|
244
|
+
"""
|
245
|
+
Return the string for this covering design.
|
246
|
+
|
247
|
+
This has the parameters and the blocks in readable form.
|
248
|
+
|
249
|
+
EXAMPLES::
|
250
|
+
|
251
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
252
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
253
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
254
|
+
sage: print(C)
|
255
|
+
C(7, 3, 2) = 7
|
256
|
+
Method: Projective Plane
|
257
|
+
0 1 2
|
258
|
+
0 3 4
|
259
|
+
0 5 6
|
260
|
+
1 3 5
|
261
|
+
1 4 6
|
262
|
+
2 3 6
|
263
|
+
2 4 5
|
264
|
+
"""
|
265
|
+
if self.__size == self.__low_bd: # check if covering is optimal
|
266
|
+
repr = ('C(%d, %d, %d) = %d\n' %
|
267
|
+
(self.__v, self.__k, self.__t, self.__size))
|
268
|
+
else:
|
269
|
+
repr = ('%d <= C(%d, %d, %d) <= %d\n' % (self.__low_bd,
|
270
|
+
self.__v, self.__k, self.__t, self.__size))
|
271
|
+
if self.__creator:
|
272
|
+
repr += 'Created by: %s\n' % (self.__creator)
|
273
|
+
if self.__method:
|
274
|
+
repr += 'Method: %s\n' % (self.__method)
|
275
|
+
if self.__timestamp:
|
276
|
+
repr += 'Submitted on: %s\n' % (self.__timestamp)
|
277
|
+
return repr + '\n'.join(' '.join(str(k) for k in block) for block in
|
278
|
+
self.__incidence_structure.blocks())
|
279
|
+
|
280
|
+
def is_covering(self):
|
281
|
+
"""
|
282
|
+
Check all `t`-sets are in fact covered by the blocks of ``self``.
|
283
|
+
|
284
|
+
.. NOTE::
|
285
|
+
|
286
|
+
This is very slow and wasteful of memory.
|
287
|
+
|
288
|
+
EXAMPLES::
|
289
|
+
|
290
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
291
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
292
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
293
|
+
sage: C.is_covering()
|
294
|
+
True
|
295
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
296
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6],
|
297
|
+
....: [2, 4, 6]], 0, 'not a covering') # last block altered
|
298
|
+
sage: C.is_covering()
|
299
|
+
False
|
300
|
+
"""
|
301
|
+
v = self.__v
|
302
|
+
k = self.__k
|
303
|
+
t = self.__t
|
304
|
+
Svt = Combinations(range(v), t)
|
305
|
+
Skt = Combinations(range(k), t)
|
306
|
+
tset = {} # tables of t-sets: False = uncovered, True = covered
|
307
|
+
for i in Svt:
|
308
|
+
tset[tuple(i)] = False
|
309
|
+
# mark all t-sets covered by each block
|
310
|
+
for a in self.__incidence_structure.blocks():
|
311
|
+
for z in Skt:
|
312
|
+
y = (a[x] for x in z)
|
313
|
+
tset[tuple(y)] = True
|
314
|
+
for i in Svt:
|
315
|
+
if not tset[tuple(i)]: # uncovered
|
316
|
+
return False
|
317
|
+
return True # everything was covered
|
318
|
+
|
319
|
+
def v(self):
|
320
|
+
"""
|
321
|
+
Return `v`, the number of points in the covering design.
|
322
|
+
|
323
|
+
EXAMPLES::
|
324
|
+
|
325
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
326
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
327
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
328
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
329
|
+
sage: C.v()
|
330
|
+
7
|
331
|
+
"""
|
332
|
+
return self.__v
|
333
|
+
|
334
|
+
def k(self):
|
335
|
+
"""
|
336
|
+
Return `k`, the size of blocks of the covering design.
|
337
|
+
|
338
|
+
EXAMPLES::
|
339
|
+
|
340
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
341
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
342
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
343
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
344
|
+
sage: C.k()
|
345
|
+
3
|
346
|
+
"""
|
347
|
+
return self.__k
|
348
|
+
|
349
|
+
def t(self):
|
350
|
+
"""
|
351
|
+
Return `t`, the size of sets which must be covered by the
|
352
|
+
blocks of the covering design
|
353
|
+
|
354
|
+
EXAMPLES::
|
355
|
+
|
356
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
357
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
358
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
359
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
360
|
+
sage: C.t()
|
361
|
+
2
|
362
|
+
"""
|
363
|
+
return self.__t
|
364
|
+
|
365
|
+
def size(self):
|
366
|
+
"""
|
367
|
+
Return the number of blocks in the covering design.
|
368
|
+
|
369
|
+
EXAMPLES::
|
370
|
+
|
371
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
372
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
373
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
374
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
375
|
+
sage: C.size()
|
376
|
+
7
|
377
|
+
"""
|
378
|
+
return self.__size
|
379
|
+
|
380
|
+
def low_bd(self):
|
381
|
+
"""
|
382
|
+
Return a lower bound for the number of blocks a covering
|
383
|
+
design with these parameters could have.
|
384
|
+
|
385
|
+
Typically this is the Schonheim bound, but for some parameters
|
386
|
+
better bounds have been shown.
|
387
|
+
|
388
|
+
EXAMPLES::
|
389
|
+
|
390
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
391
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
392
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
393
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
394
|
+
sage: C.low_bd()
|
395
|
+
7
|
396
|
+
"""
|
397
|
+
return self.__low_bd
|
398
|
+
|
399
|
+
def method(self):
|
400
|
+
"""
|
401
|
+
Return the method used to create the covering design.
|
402
|
+
|
403
|
+
This field is optional, and is used in a database to give information
|
404
|
+
about how coverings were constructed.
|
405
|
+
|
406
|
+
EXAMPLES::
|
407
|
+
|
408
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
409
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
410
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
411
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
412
|
+
sage: C.method()
|
413
|
+
'Projective Plane'
|
414
|
+
"""
|
415
|
+
return self.__method
|
416
|
+
|
417
|
+
def creator(self):
|
418
|
+
"""
|
419
|
+
Return the creator of the covering design.
|
420
|
+
|
421
|
+
This field is optional, and is used in a database to give
|
422
|
+
attribution for the covering design It can refer to the person
|
423
|
+
who submitted it, or who originally gave a construction
|
424
|
+
|
425
|
+
EXAMPLES::
|
426
|
+
|
427
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
428
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
429
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6],
|
430
|
+
....: [2, 4, 5]],0, 'Projective Plane', 'Gino Fano')
|
431
|
+
sage: C.creator()
|
432
|
+
'Gino Fano'
|
433
|
+
"""
|
434
|
+
return self.__creator
|
435
|
+
|
436
|
+
def timestamp(self):
|
437
|
+
"""
|
438
|
+
Return the time that the covering was submitted to the database.
|
439
|
+
|
440
|
+
EXAMPLES::
|
441
|
+
|
442
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
443
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
444
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
445
|
+
....: [2, 3, 6], [2, 4, 5]],0, 'Projective Plane',
|
446
|
+
....: 'Gino Fano', '1892-01-01 00:00:00')
|
447
|
+
sage: C.timestamp() # No exact date known; in Fano's 1892 article
|
448
|
+
'1892-01-01 00:00:00'
|
449
|
+
"""
|
450
|
+
return self.__timestamp
|
451
|
+
|
452
|
+
def incidence_structure(self):
|
453
|
+
"""
|
454
|
+
Return the incidence structure of this design, without extra parameters.
|
455
|
+
|
456
|
+
EXAMPLES::
|
457
|
+
|
458
|
+
sage: from sage.combinat.designs.covering_design import CoveringDesign
|
459
|
+
sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2],
|
460
|
+
....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6],
|
461
|
+
....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane')
|
462
|
+
sage: D = C.incidence_structure()
|
463
|
+
sage: D.ground_set()
|
464
|
+
[0, 1, 2, 3, 4, 5, 6]
|
465
|
+
sage: D.blocks()
|
466
|
+
[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5],
|
467
|
+
[1, 4, 6], [2, 3, 6], [2, 4, 5]]
|
468
|
+
"""
|
469
|
+
return self.__incidence_structure
|
470
|
+
|
471
|
+
|
472
|
+
def best_known_covering_design_www(v, k, t, verbose=False):
|
473
|
+
r"""
|
474
|
+
Return the best known `(v, k, t)` covering design from an online database.
|
475
|
+
|
476
|
+
This uses the La Jolla Covering Repository, a database
|
477
|
+
available at `<https://ljcr.dmgordon.org/cover.html>`_
|
478
|
+
|
479
|
+
INPUT:
|
480
|
+
|
481
|
+
- ``v`` -- integer; the size of the point set for the design
|
482
|
+
|
483
|
+
- ``k`` -- integer; the number of points per block
|
484
|
+
|
485
|
+
- ``t`` -- integer; the size of sets covered by the blocks
|
486
|
+
|
487
|
+
- ``verbose`` -- boolean (default: ``False``); print verbose message
|
488
|
+
|
489
|
+
OUTPUT:
|
490
|
+
|
491
|
+
A :class:`CoveringDesign` object representing the ``(v, k, t)``-covering
|
492
|
+
design with smallest number of blocks available in the database.
|
493
|
+
|
494
|
+
EXAMPLES::
|
495
|
+
|
496
|
+
sage: from sage.combinat.designs.covering_design import ( # optional - internet
|
497
|
+
....: best_known_covering_design_www)
|
498
|
+
sage: C = best_known_covering_design_www(7, 3, 2) # optional - internet
|
499
|
+
sage: print(C) # optional - internet
|
500
|
+
C(7, 3, 2) = 7
|
501
|
+
Method: lex covering
|
502
|
+
Submitted on: 1996-12-01 00:00:00
|
503
|
+
0 1 2
|
504
|
+
0 3 4
|
505
|
+
0 5 6
|
506
|
+
1 3 5
|
507
|
+
1 4 6
|
508
|
+
2 3 6
|
509
|
+
2 4 5
|
510
|
+
|
511
|
+
A :exc:`ValueError` is raised if the ``(v, k, t)`` parameters are not
|
512
|
+
found in the database.
|
513
|
+
"""
|
514
|
+
from sage.misc.sage_eval import sage_eval
|
515
|
+
|
516
|
+
v = int(v)
|
517
|
+
k = int(k)
|
518
|
+
t = int(t)
|
519
|
+
param = "?v=%s&k=%s&t=%s" % (v, k, t)
|
520
|
+
url = "https://ljcr.dmgordon.org/get_cover.php" + param
|
521
|
+
if verbose:
|
522
|
+
print("Looking up the bounds at %s" % url)
|
523
|
+
|
524
|
+
with urlopen(url, context=default_context()) as f:
|
525
|
+
s = f.read().decode()
|
526
|
+
|
527
|
+
if 'covering not in database' in s: # not found
|
528
|
+
str = "no (%d, %d, %d) covering design in database\n" % (v, k, t)
|
529
|
+
raise ValueError(str)
|
530
|
+
return sage_eval(s)
|