March Madness — nerd style

My work is doing a silly contest around the whole NCAA thing. Back in high school kids used to run around comparing their brackets and arguing over every detail, and I hated it. I don’t follow basketball at all, and other than knowing that Duke ususally does well I have no basis upon which to make any choices except the seeds.

So I decided to write a bracket-generating algorithm that uses the seeds to generate weights for a random function and pick teams that way. The algorithm works as such:

  • for a pair of teams, take their seeds and invert them (make small numbers big)
  • divide each seed by the total of the two seeds to get values 0 < = x <= 1
  • get a random number 0 < = r <= 1. If team a’s chance is >= that value, they win

The actual code isn’t as nice as that explanation, but it should be mathematically equivalent. Any errors in programming only make these results more my own. I took the results from the first run that (a) worked, and (b) had Wisconsin (my alma mater) not getting knocked out in the first round.

Based on brackets.py, the final four will be: Arizona, Kansas, Texas, and Ohio St.

Kansas will win.

Source code after the break:

#!/usr/bin/python

import random

MAX_SEED=16.0

initial_bracket_1 = [
	("Florida", 1.0),
	("Jackson St", 16.0),
	("Arizona", 8.0),
	("Purdue", 9.0),
	("Butler", 5.0),
	("Old Dominion", 12.0),
	("Maryland", 4.0),
	("Davidson", 13.0),
	("Notre Dame", 6.0),
	("Winthrop", 11.0),
	("Oregon", 3.0),
	("Miami (Ohio)", 14.0),
	("UNLV", 7.0),
	("Georgia Tech", 10.0),
	("Wisconsin", 2.0),
	("Texas A&M CC", 15.0)
	]
	
initial_bracket_2 = [
	("Kansas", 1),
	("BY", 16),
	("Kentucky", 8),
	("Villanoba", 9),
	("Virginia Tech", 5),
	("Illinois", 12),
	("Southern Ill", 4),
	("Holy Cross", 13),
	("Duke", 6),
	("VCU", 11),
	("Pittsburgh", 3),
	("Wright St.", 14),
	("Indiana", 7),
	("Gonzaga", 10),
	("UCLA", 2),
	("Weber St.", 15)
	]
	
initial_bracket_3 = [
	("North Carolina", 1),
	("Eastern Ky.", 16),
	("Marquette", 8),
	("Michigan St.", 9),
	("Southern Cal.", 5),
	("Arkansas", 12),
	("Texas", 4),
	("New Mexico St", 13),
	("Vanderbilt", 6),
	("G. Washington", 11),
	("Washington St.", 3),
	("Oral Roberts", 14),
	("Boston College", 7),
	("Texas Tech", 10),
	("Georgetown", 2),
	("Belmont", 15)
	]
	
initial_bracket_4 = [
	("Ohio St.", 1),
	("C. Conn. St", 16),
	("BYU", 8),
	("Xavier", 9),
	("Tennessee", 5),
	("Long Beach", 12),
	("Virginia", 4),
	("Albany", 13),
	("Louisville", 6),
	("Stanford", 11),
	("Texas A&M", 3),
	("Penn", 14),
	("Nevada", 7),
	("Creighton", 10),
	("Memphis", 2),
	("North Texas", 15)
	]

	
def play_bracket(bracket):

	"""returns winners"""
	
	winners = []
	
	for i in range(0, len(bracket), 2):
		team_a, seed_a = bracket[i]
		team_b, seed_b = bracket[i+1]
		
		if team_a == "BY":
			winners.append((team_b, seed_b))
			continue
		elif team_b == "BY":
			winners.append((team_a, seed_a))
			continue
		
		adj_seed_a = MAX_SEED - seed_a + 1
		adj_seed_b = MAX_SEED - seed_b + 1
		
		chance_a = adj_seed_a / MAX_SEED
		chance_b = adj_seed_b / MAX_SEED
		
		total = chance_a + chance_b
		chance_a = chance_a / total
		chance_b = chance_b / total
		
		winner = random.random()
		if winner < = chance_a:
			winners.append((team_a, seed_a))
		else:
			winners.append((team_b, seed_b))
	
	return winners
	
def print_teams(bracket):
	for team, seed in bracket:
		print team
	print "-"*20
	
def play_branch(bracket):
	while len(bracket) > 1:
		print_teams(bracket)
		bracket = play_bracket(bracket)
	print bracket[0][0]
	print "="*20
	return bracket[0]
	
final_four = []	
	
final_four.append(play_branch(initial_bracket_1))
final_four.append(play_branch(initial_bracket_2))
final_four.append(play_branch(initial_bracket_3))
final_four.append(play_branch(initial_bracket_4))

play_branch(final_four)
 

5 thoughts on “March Madness — nerd style”

  1. You should post your bracket, and score it with the usual point systems (like on Yahoo) - see how you compare to the great unwashed masses.

  2. You know he's probably right. You're set up will probably get you a bracket as good as many of the "knowledgeable" ones. I'd run a few of them on some free bracket sites as well just to see how well weighted random picking works.

  3. My friend's generated bracket had Duke losing in the first round, which he knew had to be all wrong -- however with last night's result apparently bracket.py knows better!

Comments are closed.