0

There are 64 students in our class. We had one round of random team assignment and will soon have a second round. In each round, we randomly divide the students into 16 groups of size 4 each.

What's probability that no pair of teammates in Round 1 are teammates again in Round 2?

user118464
  • 33
  • 1
  • 4

2 Answers2

0

If by "computationally" you mean "with a simulation":

import random

def make_teams(teamsize, numteams):
    students = list(range(teamsize * numteams))  # Py2 & Py3 compatible
    random.shuffle(students)
    teammates = {}
    for i in range(0, len(students), teamsize):
        team = set(students[i:i+teamsize])
        for t in team: teammates[t] = team.difference([t])
    return teammates

ref_tms = make_teams(4, 16)
common_teammates = 0
for i in range(10000):
    new_tms = make_teams(4, 16)
    if any(ref_tms[t].intersection(new_tms[t]) for t in ref_tms):
        common_teammates += 1
print('Common teammates seen in {} cases out of 10000'.format(
      common_teammates)

Of course a sample of 10000 examples is small-ish, but it should start giving you an idea. You can run this a few times and see how the frequency (takes as an estimate of the probability) varies, and compute confidence bounds, etc, etc.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • BTW, the "some common teammates" is **by far** most likely, as a modicum of statistical intuition should show - the probability of "no common teammates at all" is very low, thus requiring advanced stats techniques to assess robustly (beyond what was stats 101 in my time). I'm sure your prof realizes that and is using this as a stepping-stone to higher, harder tasks. One of my early publications was exactly about a better heuristic to estimate probabilities of very rare events -- though the world ignored me and keeps blithely using Good-Turing estimation, at least **I** know better:-). – Alex Martelli Feb 09 '15 at 03:21
  • Sorry I mistakenly wrote something just now...so I just erased it! Sorry for that! Your answer is very helpful. I really appreciate your help! – user118464 Feb 09 '15 at 03:25
  • @user118464, NP, saw your edit and changed my own comment -- now when you delete your latest comment I'll delete this one (not the previous one about the Martelli heuristic's improvements on the Turing-Good one, of which I'm still proud 30 years later, and which opened the way to my "How shape influences strength" articles in The Bridge World Jan and Feb 2000 issues which I count as my biggest achievement!-) Key intuition, and Good and Turing WERE first there!, is that, if some combination is very rare, standard stats 101 approaches to estimate its probability misbehave, so you need more...! – Alex Martelli Feb 09 '15 at 03:31
0

Let's label the students according to their round-1 team:

0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 AAAA BBBB CCCC DDDD EEEE FFFF

The number of ways to assign round-2 teams, without restrictions, is

64! / ((4! ** 16) * (4! ** 16)) == 864285371844932000669608560277139342915848604
 ^        ^            ^
 |        |        ways of rearranging each round-2 team
 |     indistinguishable arrangements for round-1 team members
raw number of permutations

The number of ways to assign round-2 teams without per-team duplicates is complicated because how we assign the first team changes the combinations available for the second team (and so on). But it should still be tractable with clever math and careful memoization!

from functools import lru_cache

# lookup table for `choose(n, k)` for n up to 16 and k up to 4
ncr = {}
for n in range(17):
    nn   = n
    ntok = 1
    ktok = 1
    ncr[n, 0] = 1
    for k in range(1, min(n, 4) + 1):
        ntok *= nn
        nn -= 1
        ktok *= k
        ncr[n, k] = ntok // ktok

@lru_cache(maxsize=None)
def team_combos(zeros, ones, twos, threes, fours):
    """
    Calculate the number of unique second-round 4-person
      team combinations such that no team has members from
      the same first-round team.
    """
    if ones or twos or threes or fours:
        total_ways = 0
        # number of members to take from teams having one person remaining
        for b in range(min(ones, 4) + 1):
            zeros_ = zeros + b
            b_ways = ncr[ones, b]
            b_rem = 4 - b   # number of members yet to be chosen
            # number of members to take from teams having two persons remaining
            for c in range(min(twos, b_rem) + 1):
                ones_ = ones - b + c
                bc_ways = b_ways * ncr[twos, c]
                bc_rem = b_rem - c  # number of members yet to be chosen
                # number of members to take from teams having three persons remaining
                for d in range(min(threes, bc_rem) + 1):
                    e = bc_rem - d  # number of members yet to be chosen
                    # ... all of which _must_ now come from
                    #   teams having four persons remaining
                    if e <= fours:
                        bcde_ways = bc_ways * ncr[threes, d] * ncr[fours, e]
                        total_ways += bcde_ways * team_combos(zeros_, ones_, twos - c + d, threes - d + e, fours - e)
        return total_ways
    else:
        return 1

then

>>> team_combos(0, 0, 0, 0, 16)   # start with 16 four-person teams
6892692735539278753058456514221737762215000

then the final probability is exactly

>>> 6892692735539278753058456514221737762215000 / 864285371844932000669608560277139342915848604
0.0079750195480295
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99