Exemplo n.º 1
0
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))
Exemplo n.º 2
0
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.")
Exemplo n.º 3
0
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))
Exemplo n.º 4
0
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.")
Exemplo n.º 5
0
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.")
Exemplo n.º 6
0
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.")