Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Resolvable Balanced Incomplete Block Design (RBIBD)
This module contains everything related to resolvable Balanced Incomplete Block Designs. The constructions implemented here can be obtained through the ``designs.<tab>`` object::
designs.resolvable_balanced_incomplete_block_design(15,3)
For Balanced Incomplete Block Design (BIBD) see the module :mod:`bibd <sage.combinat.designs.bibd>`. A BIBD is said to be *resolvable* if its blocks can be partitionned into parallel classes, i.e. partitions of its ground set.
The main function of this module is :func:`resolvable_balanced_incomplete_block_design`, which calls all others.
.. csv-table:: :class: contentstable :widths: 30, 70 :delim: |
:func:`resolvable_balanced_incomplete_block_design` | Return a resolvable BIBD of parameters `v,k`. :func:`kirkman_triple_system` | Return a Kirkman Triple System on `v` points. :func:`v_4_1_rbibd` | Return a `(v,4,1)`-RBIBD :func:`PBD_4_7` | Return a `(v,\{4,7\})`-PBD :func:`PBD_4_7_from_Y` | Return a `(3v+1,\{4,7\})`-PBD from a `(v,\{4,5,7\},\NN-\{3,6,10\})`-GDD.
References:
.. [Stinson91] \D.R. Stinson, A survey of Kirkman triple systems and related designs, Volume 92, Issues 1-3, 17 November 1991, Pages 371-393, Discrete Mathematics, :doi:`10.1016/0012-365X(91)90294-C`
.. [RCW71] \D. K. Ray-Chaudhuri, R. M. Wilson, Solution of Kirkman's schoolgirl problem, Volume 19, Pages 187-203, Proceedings of Symposia in Pure Mathematics
.. [BJL99] \T. Beth, D. Jungnickel, H. Lenz, Design Theory 2ed. Cambridge University Press 1999
Functions --------- """ from __future__ import print_function, absolute_import, division from six.moves import range
from sage.arith.all import is_prime_power from sage.combinat.designs.bibd import BalancedIncompleteBlockDesign from sage.categories.sets_cat import EmptySetError from .bibd import balanced_incomplete_block_design from sage.misc.unknown import Unknown
def resolvable_balanced_incomplete_block_design(v,k,existence=False): r""" Return a resolvable BIBD of parameters `v,k`.
A BIBD is said to be *resolvable* if its blocks can be partitionned into parallel classes, i.e. partitions of the ground set.
INPUT:
- ``v,k`` (integers)
- ``existence`` (boolean) -- instead of building the design, return:
- ``True`` -- meaning that Sage knows how to build the design
- ``Unknown`` -- meaning that Sage does not know how to build the design, but that the design may exist (see :mod:`sage.misc.unknown`).
- ``False`` -- meaning that the design does not exist.
.. SEEALSO::
- :meth:`IncidenceStructure.is_resolvable` - :func:`~sage.combinat.designs.bibd.balanced_incomplete_block_design`
EXAMPLES::
sage: KTS15 = designs.resolvable_balanced_incomplete_block_design(15,3); KTS15 (15,3,1)-Balanced Incomplete Block Design sage: KTS15.is_resolvable() True
TESTS::
sage: for v in range(40): ....: for k in range(v): ....: if designs.resolvable_balanced_incomplete_block_design(v,k,existence=True): ....: _ = designs.resolvable_balanced_incomplete_block_design(v,k) """ # Trivial cases
# Non-existence of resolvable BIBD k < 2 or v%k != 0 or (v-1) % (k-1) != 0 or (v*(v-1)) % (k*(k-1)) != 0 or # From the Handbook of combinatorial designs: # # With lambda>1 the other exceptions is # (15,5,2) (k==6 and v == 36) or # Fisher's inequality (v*(v-1))/(k*(k-1)) < v): raise EmptySetError("There exists no ({},{},{})-RBIBD".format(v,k,1))
for c in range(v-1)]
sum(classes,[]), k = k, check=True, copy=False) else: raise NotImplementedError("I don't know how to build a ({},{},1)-RBIBD!".format(v,3))
def kirkman_triple_system(v,existence=False): r""" Return a Kirkman Triple System on `v` points.
A Kirkman Triple System `KTS(v)` is a resolvable Steiner Triple System. It exists if and only if `v\equiv 3\pmod{6}`.
INPUT:
- `n` (integer)
- ``existence`` (boolean; ``False`` by default) -- whether to build the `KTS(n)` or only answer whether it exists.
.. SEEALSO::
:meth:`IncidenceStructure.is_resolvable`
EXAMPLES:
A solution to Kirkmman's original problem::
sage: kts = designs.kirkman_triple_system(15) sage: classes = kts.is_resolvable(1)[1] sage: names = '0123456789abcde' sage: def to_name(r_s_t): ....: r, s, t = r_s_t ....: return ' ' + names[r] + names[s] + names[t] + ' ' sage: rows = [' '.join(('Day {}'.format(i) for i in range(1,8)))] sage: rows.extend(' '.join(map(to_name,row)) for row in zip(*classes)) sage: print('\n'.join(rows)) Day 1 Day 2 Day 3 Day 4 Day 5 Day 6 Day 7 07e 18e 29e 3ae 4be 5ce 6de 139 24a 35b 46c 05d 167 028 26b 03c 14d 257 368 049 15a 458 569 06a 01b 12c 23d 347 acd 7bd 78c 89d 79a 8ab 9bc
TESTS::
sage: for i in range(3,300,6): ....: _ = designs.kirkman_triple_system(i) """ if existence: return False raise ValueError("There is no KTS({}) as v!=3 mod(6)".format(v))
[[1, 6, 8], [3, 5, 7], [0, 2, 4]], [[1, 4, 7], [0, 3, 6], [2, 5, 8]], [[4, 5, 6], [0, 7, 8], [1, 2, 3]]]
# Construction 1.1 from [Stinson91] (originally Theorem 6 from [RCW71]) # # For all prime powers q=1 mod 6, there exists a KTS(2q+1)
# m is the solution of a^m=(a^t+1)/2
# First parallel class for i in list(range(t))+list(range(2*t,3*t))+list(range(4*t,5*t))) for i in range(t)])
# Action of K on the points
# relabel to integer for i,p in enumerate(K) for x in [1,2]}
for p in K]
# Construction 1.2 from [Stinson91] (originally Theorem 5 from [RCW71]) # # For all prime powers q=1 mod 6, there exists a KTS(3q) for i in range(t)]
# Action of K on the points
# relabel to integer for i,p in enumerate(K) for j in range(3)}
# Classes for p in K]
else: # This is Lemma IX.6.4 from [BJL99]. # # This construction takes a (v,{4,7})-PBD. All points are doubled (x has # a copy x'), and an infinite point \infty is added. # # On all blocks of 2*4 points we "paste" a KTS(2*4+1) using the infinite # point, in such a way that all {x,x',infty} are set of the design. We # do the same for blocks with 2*7 points using a KTS(2*7+1). # # Note that the triples of points equal to {x,x',\infty} will be added # several times. # # As all those subdesigns are resolvable, each class of the KTS(n) is # obtained by considering a set {x,x',\infty} and all sets of all # parallel classes of the subdesign which contain this set.
# We create the small KTS(n') we need, and relabel them such that # 01(n'-1),23(n'-1),... are blocks of the design.
# The first parallel class contains 01(n'-1), the second contains # 23(n'-1), etc.. # Then remove the blocks containing (n'-1)
# Pasting the KTS(n') without {x,x',\infty} blocks
# The {x,x',\infty} blocks
blocks = [tr for cl in classes for tr in cl], k=3, lambd=1, check=True, copy =False)
def v_4_1_rbibd(v,existence=False): r""" Return a `(v,4,1)`-RBIBD.
INPUT:
- `n` (integer)
- ``existence`` (boolean; ``False`` by default) -- whether to build the design or only answer whether it exists.
.. SEEALSO::
- :meth:`IncidenceStructure.is_resolvable` - :func:`resolvable_balanced_incomplete_block_design`
.. NOTE::
A resolvable `(v,4,1)`-BIBD exists whenever `1\equiv 4\pmod(12)`. This function, however, only implements a construction of `(v,4,1)`-BIBD such that `v=3q+1\equiv 1\pmod{3}` where `q` is a prime power (see VII.7.5.a from [BJL99]_).
EXAMPLES::
sage: rBIBD = designs.resolvable_balanced_incomplete_block_design(28,4) sage: rBIBD.is_resolvable() True sage: rBIBD.is_t_design(return_parameters=True) (True, (2, 28, 4, 1))
TESTS::
sage: for q in prime_powers(2,30): ....: if (3*q+1)%12 == 4: ....: _ = designs.resolvable_balanced_incomplete_block_design(3*q+1,4) # indirect doctest """ # Volume 1, VII.7.5.a from [BJL99]_ if existence: return Unknown raise NotImplementedError("I don't know how to build a ({},{},1)-RBIBD!".format(v,4))
for i in range(nn) for j in range(3)]
for S in first_class] for g in G]
blocks = sum(classes,[]), k=4, check=True, copy=False)
def PBD_4_7(v,check=True, existence=False): r""" Return a `(v,\{4,7\})`-PBD
For all `v` such that `n\equiv 1\pmod{3}` and `n\neq 10,19, 31` there exists a `(v,\{4,7\})`-PBD. This is proved in Proposition IX.4.5 from [BJL99]_, which this method implements.
This construction of PBD is used by the construction of Kirkman Triple Systems.
EXAMPLES::
sage: from sage.combinat.designs.resolvable_bibd import PBD_4_7 sage: PBD_4_7(22) Pairwise Balanced Design on 22 points with sets of sizes in set([4, 7])
TESTS:
All values `\leq 300`::
sage: for i in range(1,300,3): ....: if i not in [10,19,31]: ....: assert PBD_4_7(i,existence=True) ....: _ = PBD_4_7(i,check=True) """ raise NotImplementedError
# Beth/Jungnickel/Lenz: take KTS(15) and extend each of the 7 classes # with a new point. Make those new points a 7-set.
# [BJL99] (p527,vol1), but originally Brouwer
for S in A+B+C+D+[list(range(27,34))]] # [BJL99] (p527,vol1), but originally Brouwer
for S in A+B+C+D+E+[list(range(39, 46))]]
# [BJL99] (p527,vol1), but originally Brouwer
for S in A+B+C+D+E+F+[list(range(51,58))]]
# [BJL99] (p527,vol1), but originally Brouwer
for x in S] for S in A+B+C+D+E+F+H+[list(range(63,70))]]
# This construction is Theorem IX.3.16 from [BJL99] (p.627). # # A (15,{4},{3})-GDD from a (16,4)-BIBD
# A (75,{4},{15})-GDD
# We now complete the (75,{4},{15})-GDD into a (82,{4,7})-PBD. For this, # we add 7 new points that are added to all groups of size 15. # # On these groups a (15+7,{4,7})-PBD is pasted, in such a way that the 7 # new points are a set of the final PBD
# IX.4.5.l from [BJL99]. # # take 4 parallel lines from an affine plane of order 7, and a 5th # one. This is a (31,{4,5,7})-BIBD. And 94=3*31+1.
blocks = S_4_5_7, K = [4,5,7], check=False)
# IX.4.5.o from [BJL99]. # # Attach two or seven infinite points to a (40,4)-RBIBD to get a # (42,{4,5},{1,2,7})-GDD or a (47,{4,5},{1,2,7})-GDD for i,classs in enumerate(rBIBD4._classes) for S in classs] else: groups = groups, blocks = GDD, K = [2,4,5,7], check = False, copy = False)
# VII.5.17 from [BJL99]
# IV.4.5.p from [BJL99]
else: # IX.4.5.m from [BJL99]. # # This construction takes a TD(5,g) and truncates its last column to # size u: it yields a (4g+u,{4,5},{g,u})-GDD. If there exists a # (3g+1,{4,7})-PBD and a (3u+1,{4,7})-PBD, then we can apply the x->3x+1 # construction on the truncated transversal design (which is a GDD). # # We write vv = 4g+u while satisfying the hypotheses. PBD_4_7(3*g+1,existence=True) and PBD_4_7(3*u+1,existence=True)): groups = [[x for x in gr if x in domain] for gr in GDD.groups()], blocks = [[x for x in B if x in domain] for B in GDD], G = set([g,u]), K = [4,5], check=False)
blocks = blocks, K = [4,7], check = check, copy = False)
def PBD_4_7_from_Y(gdd,check=True): r""" Return a `(3v+1,\{4,7\})`-PBD from a `(v,\{4,5,7\},\NN-\{3,6,10\})`-GDD.
This implements Lemma IX.3.11 from [BJL99]_ (p.625). All points of the GDD are tripled, and a `+\infty` point is added to the design.
- A group of size `s\in Y=\NN-\{3,6,10\}` becomes a set of size `3s`. Adding `\infty` to it gives it size `3s+1`, and this set is then replaced by a `(3s+1,\{4,7\})`-PBD.
- A block of size `s\in\{4,5,7\}` becomes a `(3s,\{4,7\},\{3\})`-GDD.
This lemma is part of the existence proof of `(v,\{4,7\})`-PBD as explained in IX.4.5 from [BJL99]_).
INPUT:
- ``gdd`` -- a `(v,\{4,5,7\},Y)`-GDD where `Y=\NN-\{3,6,10\}`.
- ``check`` -- (boolean) Whether to check that output is correct before returning it. As this is expected to be useless (but we are cautious guys), you may want to disable it whenever you want speed. Set to ``True`` by default.
EXAMPLES::
sage: from sage.combinat.designs.resolvable_bibd import PBD_4_7_from_Y sage: PBD_4_7_from_Y(designs.transversal_design(7,8)) Pairwise Balanced Design on 169 points with sets of sizes in set([4, 7])
TESTS::
sage: PBD_4_7_from_Y(designs.balanced_incomplete_block_design(10,10)) Traceback (most recent call last): ... ValueError: The GDD should only contain blocks of size {4,5,7} but there are other: set([10]) sage: PBD_4_7_from_Y(designs.transversal_design(4,3)) Traceback (most recent call last): ... RuntimeError: A group has size 3 but I do not know how to build a (10,[4,7])-PBD """ "but there are other: {}".format(block_sizes.difference([4,5,7])))
"build a ({},[4,7])-PBD".format(gs,3*gs+1))
#GDD[4] = GDD_from_BIBD(3*4,4) #GDD[5] = GDD_from_BIBD(3*5,4) # It is obtained from a PBD_4_7(22) by removing a point only contained # in sets of size 4
# The blocks
# The groups for x in B])
blocks = PBD, K = [4,7], check = check, copy = False) |