Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Tournaments and the Random Generator

DZone's Guide to

Tournaments and the Random Generator

With March Madness near, let's see if the Random Generator could be used to do something that has never been accomplished before: Pick every single game correctly.

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

As the college basketball season winds down, teams across the United States prepare for what is called March Madness. March Madness is the name that has been given to the National Collegiate Athletic Association (NCAA) men's basketball tournament to determine the championship team for a given season. There is also a tournament for the women's NCAA basketball teams as well.

How the Tournament Works

Beginning in 1985, March Madness has been designed as a 64+ team, single-elimination tournament. There are four brackets of 16 teams, which are seeded so that the first team in the bracket plays the sixteenth team in the bracket. Doing so is intended to build up excitement as the better teams face each other later in the tournament.

In 2001, an initial round was added to introduce four more teams into the tournament. Basically, these four new teams participate in a play-in game against the last four teams (one from each bracket) just before the round of 32 pairings begins. One interesting note, in all the years that March Madness has been held, there has not been an instance where the number one seed was beaten by a number sixteen seed.

At a high level, the rounds are as shown below:

  • Play-in Games - 8 teams, 4 winners (which become #16 seed in each of four brackets)

  • Round #1 - 64 teams, 32 winners

  • Round #2 - 32 teams, 16 winners (referred to as the Sweet Sixteen)

  • Round #3 - 16 teams, 8 winners (referred to as the Elite Eight)

  • Round #4 - 8 teams, 4 winners (referred to as the Final Four)

  • Round #5 - 4 teams, 2 winners (final teams for the championship game)

  • Round #6 - 2 teams, 1 champion

Typically, the entire tournament spans three weeks.

The Social Aspects of March Madness

March Madness is quite popular in the United States. Not only are fans of their favorite college teams interested in watching them attempt to be awarded the trophy for being number one, but there are competitive aspects as well. Every client or employer I have worked at over the years has held some form of competition for participants to make their choices of who is going to win each game of each round.

In fact, major sporting and news websites host applications so that your own private group can manage the picks for each game. The bigger sites offer cash prizes to overall winners, driving the competition to an even higher level. As a result, people tend to review all the available information in order to make each pick their best choice.

While it sounds somewhat easy, there is not a recorded instance of where someone managed to get every single pick correct.

Last year, the longest streak was limited to 25 games (still in the first round). In 2015, someone managed to pick the first 34 games correctly, before picking their first incorrect winner.

Random Generator

Because of the difficulty of being able to correctly pick which team will win, I began to think about just how random the winner can be for some of the match-ups. Then, I began to wonder if my Random Generator could possible help with the process to make your March Madness picks.

Recently, I published a series on Random Generator on dZone:

The 1.3 version of Random Generator, uploaded to Maven Central in mid-February, improves the ranking processing - allowing for values other than a scale of 1 to 5. So, I thought I would mock up a simple implementation of how Random Generator could work to pick the winning teams.

First, I needed to add a dependency to a simple Maven project, as shown below:

<dependency>
    <groupId>com.gitlab.johnjvester</groupId>
    <artifactId>random-generator</artifactId>
    <version>1.3</version>
</dependency>


Next, I added a simple Team object, which uses Lombok, for each team:

@Data
public class Team {
    public Team(String name, Integer rating, Integer seed) {
        this.name = name;
        this.rating = rating;
        this.seed = seed;
    }

    @Override
    public String toString() {
        return seed + ". " + name + " (" + rating + ")";
    }

    private String name;
    private Integer rating;
    private Integer seed;
}


Within the Main class, a private method was created to manually load teams into a List:

private static void loadTeams(ArrayList<Team> teamList) {
    Team team = new Team("Baylor", 673, 1);
    teamList.add(team);
    team = new Team("Villanova", 669, 2);
    teamList.add(team);
    team = new Team("Kansas", 669, 3);
    teamList.add(team);
    team = new Team("Gonzaga", 659, 4);
    teamList.add(team);
    team = new Team("Louisville", 658, 5);
    teamList.add(team);
    team = new Team("Oregon", 655, 6);
    teamList.add(team);
    team = new Team("Arizona", 654, 7);
    teamList.add(team);
    team = new Team("N Carolina", 652, 8);
    teamList.add(team);
}


Of course, this data could be pulled for a database or even a RESTful API call. For my example, I decided to use each team's RPI, but converted it to an Integer. As an FYI, these rankings are for example purposes only.

Next, I wrote a simple method to pick the winner of a given set of teams:

private static Team pickWinner(Team home, Team visitor) {
    RandomGenerator randomGenerator = new RandomGenerator();

    ArrayList<Team> thisGame = new ArrayList<Team>();
    thisGame.add(home);
    thisGame.add(visitor);

    List<Team> winner = randomGenerator.randomize(thisGame, 1, true);

    System.out.println("Winner of " + home.toString() + " vs " + visitor.toString() + " is " + winner.get(0).getName());

    return winner.get(0);
}


For this exercise, I am using the randomize() option which includes max results and rated/weighed objects,

public List<T> randomize(List<T> tList, java.lang.Integer maxResults, Boolean useRating)


As shown above, the thisGame List (which contains two Team objects) will be randomized and only one Team will be returned. The RPI rating will be enabled, which will favor teams with a higher RPI. For purely random picks, this value could be set to false.

The pickWinner() method will then return the winning Team object back to the calling method. In my case, I created a simple method called processBracket() to handle lining up the games programmatically:

private static ArrayList<Team> processBracket(ArrayList<Team> thisRound) {
    ArrayList<Team> returnBracket = new ArrayList<Team>();

    int start = 0;
    int end = (thisRound.size() - 1);

    while (start < end) {
        Team winner = pickWinner(thisRound.get(start), thisRound.get(end));
        returnBracket.add(winner);

        start++;
        end--;
    }

    return returnBracket;
}


The processBracket() method pairs the highest seeds against the lowest seeds, returning a new List of Team objects containing the winners for each round.

I then introduced the Main method, which put everything above into place:

public static void main(String[] args) {
    ArrayList<Team> roundOne = new ArrayList<Team>();
    loadTeams(roundOne);

    System.out.println("Round #1");
    System.out.println("--------");

    ArrayList<Team> roundTwo = processBracket(roundOne);

    System.out.println("Round #2");
    System.out.println("--------");

    ArrayList<Team> roundThree = processBracket(roundTwo);

    System.out.println("Round #3");
    System.out.println("--------");

    ArrayList<Team> roundWinner = processBracket(roundThree);

    System.out.println("Winner of tournament is " + roundWinner.get(0).toString());
}


Running the code provides the following randomized output:

Round #1
--------
Winner of 1. Baylor (673) vs 8. N Carolina (652) is Baylor
Winner of 2. Villanova (669) vs 7. Arizona (654) is Villanova
Winner of 3. Kansas (669) vs 6. Oregon (655) is Kansas
Winner of 4. Gonzaga (659) vs 5. Louisville (658) is Louisville

Round #2
--------
Winner of 1. Baylor (673) vs 5. Louisville (658) is Baylor
Winner of 2. Villanova (669) vs 3. Kansas (669) is Kansas

Round #3
--------
Winner of 1. Baylor (673) vs 3. Kansas (669) is Baylor

Winner of tournament is 1. Baylor (673)


In my example above, there is one upset, with #5 Louisville getting the win over #4 Gonzaga.

While this example demonstrates a bracket of only 8 teams, it was intended to show how RandomGenerator could be used to predict all the winners for the March Madness tournament.

Conclusion

While I was a consultant a major pharmaceutical company, I observed a team of individuals participate in their March Madness tournament. The interesting conclusion that year wasn't that someone truly knew a great deal about college basketball teams and was able to walk away with an easy win over everyone else. The reality was that the person who won had very little knowledge on college basketball and simply picked his winners based upon a simple coin toss.

If memory serves correctly, I think he was continually asked to participate and decided he would use a coin toss to predict each winner. This made me wonder if Random Generator could improve upon that process, with the ability to include some form of rating (like RPI) to better the odds for stronger teams.

If you end up using Random Generator for your March Madness (or any other similar implementation), I would enjoy hearing from you ... especially your results.

Have a really great day!

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:
java ,randomness ,tutorial ,generators

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}