def balanced_incomplete_block_design(v, k, existence=False, use_LJCR=False): r""" Return a BIBD of parameters `v,k`. A Balanced Incomplete Block Design of parameters `v,k` is a collection `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two distinct elements `x,y\in V` there is a unique element `S\in \mathcal C` such that `x,y\in S`. More general definitions sometimes involve a `\lambda` parameter, and we assume here that `\lambda=1`. For more information on BIBD, see the :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`. 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. - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering Repository for the design when Sage does not know how to build it (see :func:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This requires internet. .. SEEALSO:: * :func:`steiner_triple_system` * :func:`v_4_1_BIBD` * :func:`v_5_1_BIBD` TODO: * Implement other constructions from the Handbook of Combinatorial Designs. EXAMPLES:: sage: designs.balanced_incomplete_block_design(7, 3).blocks() [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] sage: B = designs.balanced_incomplete_block_design(66, 6, use_LJCR=True) # optional - internet sage: B # optional - internet Incidence structure with 66 points and 143 blocks sage: B.blocks() # optional - internet [[0, 1, 2, 3, 4, 65], [0, 5, 24, 25, 39, 57], [0, 6, 27, 38, 44, 55], ... sage: designs.balanced_incomplete_block_design(66, 6, use_LJCR=True) # optional - internet Incidence structure with 66 points and 143 blocks sage: designs.balanced_incomplete_block_design(216, 6) Traceback (most recent call last): ... NotImplementedError: I don't know how to build a (216,6,1)-BIBD! TESTS:: sage: designs.balanced_incomplete_block_design(85,5,existence=True) True sage: _ = designs.balanced_incomplete_block_design(85,5) A BIBD from a Finite Projective Plane:: sage: _ = designs.balanced_incomplete_block_design(21,5) Some trivial BIBD:: sage: designs.balanced_incomplete_block_design(10,10) (10,10,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(1,10) (1,0,1)-Balanced Incomplete Block Design Existence of BIBD with `k=3,4,5`:: sage: [v for v in xrange(50) if designs.balanced_incomplete_block_design(v,3,existence=True)] [1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49] sage: [v for v in xrange(100) if designs.balanced_incomplete_block_design(v,4,existence=True)] [1, 4, 13, 16, 25, 28, 37, 40, 49, 52, 61, 64, 73, 76, 85, 88, 97] sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,5,existence=True)] [1, 5, 21, 25, 41, 45, 61, 65, 81, 85, 101, 105, 121, 125, 141, 145] For `k > 5` there are currently very few constructions:: sage: [v for v in xrange(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is True] [1, 6, 31, 66, 76, 91, 96, 106, 111, 121, 126, 136, 141, 151, 156, 171, 181, 186, 196, 201, 211, 241, 271] sage: [v for v in xrange(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is Unknown] [51, 61, 81, 166, 216, 226, 231, 246, 256, 261, 276, 286, 291] Here are some constructions with `k \geq 7` and `v` a prime power:: sage: designs.balanced_incomplete_block_design(169,7) (169,7,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(617,8) (617,8,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(433,9) (433,9,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(1171,10) (1171,10,1)-Balanced Incomplete Block Design And we know some inexistence results:: sage: designs.balanced_incomplete_block_design(21,6,existence=True) False """ lmbd = 1 # Trivial BIBD if v == 1: if existence: return True return BalancedIncompleteBlockDesign(v, [], check=False) if k == v: if existence: return True return BalancedIncompleteBlockDesign(v, [range(v)], check=False, copy=False) # Non-existence of BIBD if (v < k or k < 2 or (v-1) % (k-1) != 0 or (v*(v-1)) % (k*(k-1)) != 0 or # From the Handbook of combinatorial designs: # # With lambda>1 other exceptions are # (15,5,2),(21,6,2),(22,7,2),(22,8,4). (k==6 and v in [36,46]) or (k==7 and v == 43) or # Fisher's inequality (v*(v-1))/(k*(k-1)) < v): if existence: return False raise EmptySetError("There exists no ({},{},{})-BIBD".format(v,k,lmbd)) if k == 2: if existence: return True from itertools import combinations return BalancedIncompleteBlockDesign(v, combinations(range(v),2), check=False, copy=True) if k == 3: if existence: return v%6 == 1 or v%6 == 3 return steiner_triple_system(v) if k == 4: if existence: return v%12 == 1 or v%12 == 4 return BalancedIncompleteBlockDesign(v, v_4_1_BIBD(v), copy=False) if k == 5: if existence: return v%20 == 1 or v%20 == 5 return BalancedIncompleteBlockDesign(v, v_5_1_BIBD(v), copy=False) from difference_family import difference_family from database import BIBD_constructions if (v,k,1) in BIBD_constructions: if existence: return True return BlockDesign(v,BIBD_constructions[(v,k,1)](), copy=False) if BIBD_from_arc_in_desarguesian_projective_plane(v,k,existence=True): if existence: return True B = BIBD_from_arc_in_desarguesian_projective_plane(v,k) return BalancedIncompleteBlockDesign(v, B, copy=False) if BIBD_from_TD(v,k,existence=True): if existence: return True return BalancedIncompleteBlockDesign(v, BIBD_from_TD(v,k), copy=False) if v == (k-1)**2+k and is_prime_power(k-1): if existence: return True from block_design import projective_plane return BalancedIncompleteBlockDesign(v, projective_plane(k-1),copy=False) if difference_family(v,k,existence=True): if existence: return True G,D = difference_family(v,k) return BalancedIncompleteBlockDesign(v, BIBD_from_difference_family(G,D,check=False), copy=False) if use_LJCR: from covering_design import best_known_covering_design_www B = best_known_covering_design_www(v,k,2) # Is it a BIBD or just a good covering ? expected_n_of_blocks = binomial(v,2)/binomial(k,2) if B.low_bd() > expected_n_of_blocks: if existence: return False raise EmptySetError("There exists no ({},{},{})-BIBD".format(v,k,lmbd)) B = B.incidence_structure() if B.num_blocks() == expected_n_of_blocks: if existence: return True else: return B if existence: return Unknown else: raise NotImplementedError("I don't know how to build a ({},{},1)-BIBD!".format(v,k))
def BalancedIncompleteBlockDesign(v, k, use_LJCR=False): r""" Returns a BIBD of parameters `v,k`. A Balanced Incomplete Block Design of parameters `v,k` is a collection `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two distinct elements `x,y\in V` there is a unique element `S\in \mathcal C` such that `x,y\in S`. More general definitions sometimes involve a `\lambda` parameter, and we assume here that `\lambda=1`. For more information on BIBD, see the :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`. INPUT: - ``v,k`` (integers) - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering Repository for the design when Sage does not know how to build it (see :meth:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This requires internet. .. SEEALSO:: * :meth:`steiner_triple_system` * :meth:`v_4_1_BIBD` TODO: * Implement `(v,5,1)`-BIBD using `this text <http://www.argilo.net/files/bibd.pdf>`_. * Implement other constructions from the Handbook of Combinatorial Designs. EXAMPLES:: sage: designs.BalancedIncompleteBlockDesign(7,3).blocks() [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] sage: B = designs.BalancedIncompleteBlockDesign(21,5, use_LJCR=True) # optional - internet sage: B # optional - internet Incidence structure with 21 points and 21 blocks sage: B.blocks() # optional - internet [[0, 1, 2, 3, 20], [0, 4, 8, 12, 16], [0, 5, 10, 15, 19], [0, 6, 11, 13, 17], [0, 7, 9, 14, 18], [1, 4, 11, 14, 19], [1, 5, 9, 13, 16], [1, 6, 8, 15, 18], [1, 7, 10, 12, 17], [2, 4, 9, 15, 17], [2, 5, 11, 12, 18], [2, 6, 10, 14, 16], [2, 7, 8, 13, 19], [3, 4, 10, 13, 18], [3, 5, 8, 14, 17], [3, 6, 9, 12, 19], [3, 7, 11, 15, 16], [4, 5, 6, 7, 20], [8, 9, 10, 11, 20], [12, 13, 14, 15, 20], [16, 17, 18, 19, 20]] sage: designs.BalancedIncompleteBlockDesign(20,5, use_LJCR=True) # optional - internet Traceback (most recent call last): ... ValueError: No such design exists ! TESTS: A BIBD from a Finite Projective Plane:: sage: _ = designs.BalancedIncompleteBlockDesign(21,5) """ if ((binomial(v, 2) % binomial(k, 2) != 0) or (v - 1) % (k - 1) != 0): raise ValueError("No such design exists !") if k == 2: from itertools import combinations return BlockDesign(v, combinations(range(v), 2), test=False) if k == 3: return steiner_triple_system(v) if k == 4: return BlockDesign(v, v_4_1_BIBD(v), test=False) if v == (k - 1)**2 + k and is_prime_power(k - 1): from block_design import ProjectivePlaneDesign return ProjectivePlaneDesign(k - 1) if use_LJCR: from covering_design import best_known_covering_design_www B = best_known_covering_design_www(v, k, 2) # Is it a BIBD or just a good covering ? expected_n_of_blocks = binomial(v, 2) / binomial(k, 2) if B.low_bd() > expected_n_of_blocks: raise ValueError("No such design exists !") B = B.incidence_structure() if len(B.blcks) == expected_n_of_blocks: return B raise ValueError("I don't know how to build this design.")
def balanced_incomplete_block_design(v, k, existence=False, use_LJCR=False): r""" Return a BIBD of parameters `v,k`. A Balanced Incomplete Block Design of parameters `v,k` is a collection `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two distinct elements `x,y\in V` there is a unique element `S\in \mathcal C` such that `x,y\in S`. More general definitions sometimes involve a `\lambda` parameter, and we assume here that `\lambda=1`. For more information on BIBD, see the :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`. 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. - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering Repository for the design when Sage does not know how to build it (see :func:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This requires internet. .. SEEALSO:: * :func:`steiner_triple_system` * :func:`v_4_1_BIBD` * :func:`v_5_1_BIBD` TODO: * Implement other constructions from the Handbook of Combinatorial Designs. EXAMPLES:: sage: designs.balanced_incomplete_block_design(7, 3).blocks() [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] sage: B = designs.balanced_incomplete_block_design(66, 6, use_LJCR=True) # optional - internet sage: B # optional - internet Incidence structure with 66 points and 143 blocks sage: B.blocks() # optional - internet [[0, 1, 2, 3, 4, 65], [0, 5, 24, 25, 39, 57], [0, 6, 27, 38, 44, 55], ... sage: designs.balanced_incomplete_block_design(66, 6, use_LJCR=True) # optional - internet Incidence structure with 66 points and 143 blocks sage: designs.balanced_incomplete_block_design(141, 6) Traceback (most recent call last): ... NotImplementedError: I don't know how to build a (141,6,1)-BIBD! TESTS:: sage: designs.balanced_incomplete_block_design(85,5,existence=True) True sage: _ = designs.balanced_incomplete_block_design(85,5) A BIBD from a Finite Projective Plane:: sage: _ = designs.balanced_incomplete_block_design(21,5) Some trivial BIBD:: sage: designs.balanced_incomplete_block_design(10,10) (10,10,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(1,10) (1,0,1)-Balanced Incomplete Block Design Existence of BIBD with `k=3,4,5`:: sage: [v for v in xrange(50) if designs.balanced_incomplete_block_design(v,3,existence=True)] [1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49] sage: [v for v in xrange(100) if designs.balanced_incomplete_block_design(v,4,existence=True)] [1, 4, 13, 16, 25, 28, 37, 40, 49, 52, 61, 64, 73, 76, 85, 88, 97] sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,5,existence=True)] [1, 5, 21, 25, 41, 45, 61, 65, 81, 85, 101, 105, 121, 125, 141, 145] For `k > 5` there are currently very few constructions:: sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,6,existence=True) is True] [1, 6, 31, 91, 121] sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,6,existence=True) is Unknown] [51, 61, 66, 76, 81, 96, 106, 111, 126, 136, 141] Here are some constructions with `k \geq 7` and `v` a prime power:: sage: designs.balanced_incomplete_block_design(169,7) (169,7,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(617,8) (617,8,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(433,9) (433,9,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(1171,10) (1171,10,1)-Balanced Incomplete Block Design And we know some inexistence results:: sage: designs.balanced_incomplete_block_design(21,6,existence=True) False """ lmbd = 1 # Trivial BIBD if v == 1: if existence: return True return BalancedIncompleteBlockDesign(v, [], check=False) if k == v: if existence: return True return BalancedIncompleteBlockDesign(v, [range(v)], check=False, copy=False) # Non-existence of BIBD if (v < k or k < 2 or (v - 1) % (k - 1) != 0 or (v * (v - 1)) % (k * (k - 1)) != 0 or # From the Handbook of combinatorial designs: # # With lambda>1 other exceptions are # (15,5,2),(21,6,2),(22,7,2),(22,8,4). (k == 6 and v in [36, 46]) or (k == 7 and v == 43) or # Fisher's inequality (v * (v - 1)) / (k * (k - 1)) < v): if existence: return False raise EmptySetError("There exists no ({},{},{})-BIBD".format( v, k, lmbd)) if k == 2: if existence: return True from itertools import combinations return BalancedIncompleteBlockDesign(v, combinations(range(v), 2), check=False, copy=True) if k == 3: if existence: return v % 6 == 1 or v % 6 == 3 return steiner_triple_system(v) if k == 4: if existence: return v % 12 == 1 or v % 12 == 4 return BalancedIncompleteBlockDesign(v, v_4_1_BIBD(v), copy=False) if k == 5: if existence: return v % 20 == 1 or v % 20 == 5 return BalancedIncompleteBlockDesign(v, v_5_1_BIBD(v), copy=False) from difference_family import difference_family from database import BIBD_constructions if (v, k, 1) in BIBD_constructions: if existence: return True return BlockDesign(v, BIBD_constructions[(v, k, 1)](), copy=False) if BIBD_from_TD(v, k, existence=True): if existence: return True return BalancedIncompleteBlockDesign(v, BIBD_from_TD(v, k), copy=False) if v == (k - 1)**2 + k and is_prime_power(k - 1): if existence: return True from block_design import projective_plane return BalancedIncompleteBlockDesign(v, projective_plane(k - 1), copy=False) if difference_family(v, k, existence=True): if existence: return True G, D = difference_family(v, k) return BalancedIncompleteBlockDesign(v, BIBD_from_difference_family( G, D, check=False), copy=False) if use_LJCR: from covering_design import best_known_covering_design_www B = best_known_covering_design_www(v, k, 2) # Is it a BIBD or just a good covering ? expected_n_of_blocks = binomial(v, 2) / binomial(k, 2) if B.low_bd() > expected_n_of_blocks: if existence: return False raise EmptySetError("There exists no ({},{},{})-BIBD".format( v, k, lmbd)) B = B.incidence_structure() if B.num_blocks() == expected_n_of_blocks: if existence: return True else: return B if existence: return Unknown else: raise NotImplementedError( "I don't know how to build a ({},{},1)-BIBD!".format(v, k))
def BalancedIncompleteBlockDesign(v,k,existence=False,use_LJCR=False): r""" Returns a BIBD of parameters `v,k`. A Balanced Incomplete Block Design of parameters `v,k` is a collection `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two distinct elements `x,y\in V` there is a unique element `S\in \mathcal C` such that `x,y\in S`. More general definitions sometimes involve a `\lambda` parameter, and we assume here that `\lambda=1`. For more information on BIBD, see the :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`. INPUT: - ``v,k`` (integers) - ``existence`` (boolean) -- instead of building the design, returns: - ``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. - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering Repository for the design when Sage does not know how to build it (see :meth:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This requires internet. .. SEEALSO:: * :func:`steiner_triple_system` * :func:`v_4_1_BIBD` * :func:`v_5_1_BIBD` TODO: * Implement other constructions from the Handbook of Combinatorial Designs. EXAMPLES:: sage: designs.BalancedIncompleteBlockDesign(7,3).blocks() [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] sage: B = designs.BalancedIncompleteBlockDesign(21,5, use_LJCR=True) # optional - internet sage: B # optional - internet Incidence structure with 21 points and 21 blocks sage: B.blocks() # optional - internet [[0, 1, 2, 3, 20], [0, 4, 8, 12, 16], [0, 5, 10, 15, 19], [0, 6, 11, 13, 17], [0, 7, 9, 14, 18], [1, 4, 11, 14, 19], [1, 5, 9, 13, 16], [1, 6, 8, 15, 18], [1, 7, 10, 12, 17], [2, 4, 9, 15, 17], [2, 5, 11, 12, 18], [2, 6, 10, 14, 16], [2, 7, 8, 13, 19], [3, 4, 10, 13, 18], [3, 5, 8, 14, 17], [3, 6, 9, 12, 19], [3, 7, 11, 15, 16], [4, 5, 6, 7, 20], [8, 9, 10, 11, 20], [12, 13, 14, 15, 20], [16, 17, 18, 19, 20]] sage: designs.BalancedIncompleteBlockDesign(20,5, use_LJCR=True) # optional - internet Traceback (most recent call last): ... ValueError: No such design exists ! sage: designs.BalancedIncompleteBlockDesign(16,6) Traceback (most recent call last): ... NotImplementedError: I don't know how to build this design. TESTS:: sage: designs.BalancedIncompleteBlockDesign(85,5,existence=True) True sage: _ = designs.BalancedIncompleteBlockDesign(85,5) A BIBD from a Finite Projective Plane:: sage: _ = designs.BalancedIncompleteBlockDesign(21,5) Some trivial BIBD:: sage: designs.BalancedIncompleteBlockDesign(10,10) Incidence structure with 10 points and 1 blocks sage: designs.BalancedIncompleteBlockDesign(1,10) Incidence structure with 1 points and 0 blocks Existence of BIBD with `k=3,4,5`:: sage: [v for v in xrange(50) if designs.BalancedIncompleteBlockDesign(v,3,existence=True)] [1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49] sage: [v for v in xrange(100) if designs.BalancedIncompleteBlockDesign(v,4,existence=True)] [1, 4, 13, 16, 25, 28, 37, 40, 49, 52, 61, 64, 73, 76, 85, 88, 97] sage: [v for v in xrange(150) if designs.BalancedIncompleteBlockDesign(v,5,existence=True)] [1, 5, 21, 25, 41, 45, 61, 65, 81, 85, 101, 105, 121, 125, 141, 145] For `k > 5` there are currently very few constructions:: sage: [v for v in xrange(150) if designs.BalancedIncompleteBlockDesign(v,6,existence=True) is True] [1, 6, 31] sage: [v for v in xrange(150) if designs.BalancedIncompleteBlockDesign(v,6,existence=True) is Unknown] [16, 21, 36, 46, 51, 61, 66, 76, 81, 91, 96, 106, 111, 121, 126, 136, 141] """ if v == 1: if existence: return True return BlockDesign(v, [], test=False) if k == v: if existence: return True return BlockDesign(v, [range(v)], test=False) if v < k or k < 2 or (v-1) % (k-1) != 0 or (v*(v-1)) % (k*(k-1)) != 0: if existence: return False raise EmptySetError("No such design exists !") if k == 2: if existence: return True from itertools import combinations return BlockDesign(v, combinations(range(v),2), test = False) if k == 3: if existence: return v%6 == 1 or v%6 == 3 return steiner_triple_system(v) if k == 4: if existence: return v%12 == 1 or v%12 == 4 return BlockDesign(v, v_4_1_BIBD(v), test = False) if k == 5: if existence: return v%20 == 1 or v%20 == 5 return BlockDesign(v, v_5_1_BIBD(v), test = False) if BIBD_from_TD(v,k,existence=True): if existence: return True return BlockDesign(v, BIBD_from_TD(v,k)) if v == (k-1)**2+k and is_prime_power(k-1): if existence: return True from block_design import projective_plane return projective_plane(k-1) if use_LJCR: from covering_design import best_known_covering_design_www B = best_known_covering_design_www(v,k,2) # Is it a BIBD or just a good covering ? expected_n_of_blocks = binomial(v,2)/binomial(k,2) if B.low_bd() > expected_n_of_blocks: if existence: return False raise EmptySetError("No such design exists !") B = B.incidence_structure() if len(B.blcks) == expected_n_of_blocks: if existence: return True else: return B if existence: return Unknown else: raise NotImplementedError("I don't know how to build this design.")
def BalancedIncompleteBlockDesign(v, k, existence=False, use_LJCR=False): r""" Returns a BIBD of parameters `v,k`. A Balanced Incomplete Block Design of parameters `v,k` is a collection `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two distinct elements `x,y\in V` there is a unique element `S\in \mathcal C` such that `x,y\in S`. More general definitions sometimes involve a `\lambda` parameter, and we assume here that `\lambda=1`. For more information on BIBD, see the :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`. INPUT: - ``v,k`` (integers) - ``existence`` (boolean) -- instead of building the design, returns: - ``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. - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering Repository for the design when Sage does not know how to build it (see :meth:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This requires internet. .. SEEALSO:: * :func:`steiner_triple_system` * :func:`v_4_1_BIBD` * :func:`v_5_1_BIBD` TODO: * Implement other constructions from the Handbook of Combinatorial Designs. EXAMPLES:: sage: designs.BalancedIncompleteBlockDesign(7,3).blocks() [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] sage: B = designs.BalancedIncompleteBlockDesign(21,5, use_LJCR=True) # optional - internet sage: B # optional - internet Incidence structure with 21 points and 21 blocks sage: B.blocks() # optional - internet [[0, 1, 2, 3, 20], [0, 4, 8, 12, 16], [0, 5, 10, 15, 19], [0, 6, 11, 13, 17], [0, 7, 9, 14, 18], [1, 4, 11, 14, 19], [1, 5, 9, 13, 16], [1, 6, 8, 15, 18], [1, 7, 10, 12, 17], [2, 4, 9, 15, 17], [2, 5, 11, 12, 18], [2, 6, 10, 14, 16], [2, 7, 8, 13, 19], [3, 4, 10, 13, 18], [3, 5, 8, 14, 17], [3, 6, 9, 12, 19], [3, 7, 11, 15, 16], [4, 5, 6, 7, 20], [8, 9, 10, 11, 20], [12, 13, 14, 15, 20], [16, 17, 18, 19, 20]] sage: designs.BalancedIncompleteBlockDesign(20,5, use_LJCR=True) # optional - internet Traceback (most recent call last): ... ValueError: No such design exists ! sage: designs.BalancedIncompleteBlockDesign(16,6) Traceback (most recent call last): ... NotImplementedError: I don't know how to build this design. TESTS:: sage: designs.BalancedIncompleteBlockDesign(85,5,existence=True) True sage: _ = designs.BalancedIncompleteBlockDesign(85,5) A BIBD from a Finite Projective Plane:: sage: _ = designs.BalancedIncompleteBlockDesign(21,5) Some trivial BIBD:: sage: designs.BalancedIncompleteBlockDesign(10,10) Incidence structure with 10 points and 1 blocks sage: designs.BalancedIncompleteBlockDesign(1,10) Incidence structure with 1 points and 0 blocks Existence of BIBD with `k=3,4,5`:: sage: [v for v in xrange(50) if designs.BalancedIncompleteBlockDesign(v,3,existence=True)] [1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49] sage: [v for v in xrange(100) if designs.BalancedIncompleteBlockDesign(v,4,existence=True)] [1, 4, 13, 16, 25, 28, 37, 40, 49, 52, 61, 64, 73, 76, 85, 88, 97] sage: [v for v in xrange(150) if designs.BalancedIncompleteBlockDesign(v,5,existence=True)] [1, 5, 21, 25, 41, 45, 61, 65, 81, 85, 101, 105, 121, 125, 141, 145] For `k > 5` there are currently very few constructions:: sage: [v for v in xrange(150) if designs.BalancedIncompleteBlockDesign(v,6,existence=True) is True] [1, 6, 31] sage: [v for v in xrange(150) if designs.BalancedIncompleteBlockDesign(v,6,existence=True) is Unknown] [16, 21, 36, 46, 51, 61, 66, 76, 81, 91, 96, 106, 111, 121, 126, 136, 141] """ if v == 1: if existence: return True return BlockDesign(v, [], test=False) if k == v: if existence: return True return BlockDesign(v, [range(v)], test=False) if v < k or k < 2 or (v - 1) % (k - 1) != 0 or (v * (v - 1)) % (k * (k - 1)) != 0: if existence: return False raise EmptySetError("No such design exists !") if k == 2: if existence: return True from itertools import combinations return BlockDesign(v, combinations(range(v), 2), test=False) if k == 3: if existence: return v % 6 == 1 or v % 6 == 3 return steiner_triple_system(v) if k == 4: if existence: return v % 12 == 1 or v % 12 == 4 return BlockDesign(v, v_4_1_BIBD(v), test=False) if k == 5: if existence: return v % 20 == 1 or v % 20 == 5 return BlockDesign(v, v_5_1_BIBD(v), test=False) if BIBD_from_TD(v, k, existence=True): if existence: return True return BlockDesign(v, BIBD_from_TD(v, k)) if v == (k - 1)**2 + k and is_prime_power(k - 1): if existence: return True from block_design import projective_plane return projective_plane(k - 1) if use_LJCR: from covering_design import best_known_covering_design_www B = best_known_covering_design_www(v, k, 2) # Is it a BIBD or just a good covering ? expected_n_of_blocks = binomial(v, 2) / binomial(k, 2) if B.low_bd() > expected_n_of_blocks: if existence: return False raise EmptySetError("No such design exists !") B = B.incidence_structure() if len(B.blcks) == expected_n_of_blocks: if existence: return True else: return B if existence: return Unknown else: raise NotImplementedError("I don't know how to build this design.")
def BalancedIncompleteBlockDesign(v,k,use_LJCR=False): r""" Returns a BIBD of parameters `v,k`. A Balanced Incomplete Block Design of parameters `v,k` is a collection `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two distinct elements `x,y\in V` there is a unique element `S\in \mathcal C` such that `x,y\in S`. More general definitions sometimes involve a `\lambda` parameter, and we assume here that `\lambda=1`. For more information on BIBD, see the :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`. INPUT: - ``v,k`` (integers) - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering Repository for the design when Sage does not know how to build it (see :meth:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This requires internet. .. SEEALSO:: * :meth:`steiner_triple_system` * :meth:`v_4_1_BIBD` TODO: * Implement `(v,5,1)`-BIBD using `this text <http://www.argilo.net/files/bibd.pdf>`_. * Implement other constructions from the Handbook of Combinatorial Designs. EXAMPLES:: sage: designs.BalancedIncompleteBlockDesign(7,3).blocks() [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] sage: B = designs.BalancedIncompleteBlockDesign(21,5, use_LJCR=True) # optional - internet sage: B # optional - internet Incidence structure with 21 points and 21 blocks sage: B.blocks() # optional - internet [[0, 1, 2, 3, 20], [0, 4, 8, 12, 16], [0, 5, 10, 15, 19], [0, 6, 11, 13, 17], [0, 7, 9, 14, 18], [1, 4, 11, 14, 19], [1, 5, 9, 13, 16], [1, 6, 8, 15, 18], [1, 7, 10, 12, 17], [2, 4, 9, 15, 17], [2, 5, 11, 12, 18], [2, 6, 10, 14, 16], [2, 7, 8, 13, 19], [3, 4, 10, 13, 18], [3, 5, 8, 14, 17], [3, 6, 9, 12, 19], [3, 7, 11, 15, 16], [4, 5, 6, 7, 20], [8, 9, 10, 11, 20], [12, 13, 14, 15, 20], [16, 17, 18, 19, 20]] sage: designs.BalancedIncompleteBlockDesign(20,5, use_LJCR=True) # optional - internet Traceback (most recent call last): ... ValueError: No such design exists ! TESTS: A BIBD from a Finite Projective Plane:: sage: _ = designs.BalancedIncompleteBlockDesign(21,5) """ if ((binomial(v,2)%binomial(k,2) != 0) or (v-1)%(k-1) != 0): raise ValueError("No such design exists !") if k == 2: from itertools import combinations return BlockDesign(v, combinations(range(v),2), test = False) if k == 3: return steiner_triple_system(v) if k == 4: return BlockDesign(v, v_4_1_BIBD(v), test = False) if v == (k-1)**2+k and is_prime_power(k-1): from block_design import ProjectivePlaneDesign return ProjectivePlaneDesign(k-1) if use_LJCR: from covering_design import best_known_covering_design_www B = best_known_covering_design_www(v,k,2) # Is it a BIBD or just a good covering ? expected_n_of_blocks = binomial(v,2)/binomial(k,2) if B.low_bd() > expected_n_of_blocks: raise ValueError("No such design exists !") B = B.incidence_structure() if len(B.blcks) == expected_n_of_blocks: return B raise ValueError("I don't know how to build this design.")