Category Archives: Modeling

How to Optimally Allocate “Bribe” Money

 As I sat through a 4-hour meeting the other day, I had an idea for a very useful and generic prescriptive analytics model to be used in conjunction with the results of a statistical learning study (e.g. a regression model). I can immediately see a large number of applications for this model, some of which I’ll illustrate in this post. I also believe this idea could be turned into an interesting case study (combining predictive and prescriptive analytics) for class discussion in a master’s level course (MBA or specialized MS), and I’d love to partner with someone to turn that into reality. Let me know if you’d like to pursue this! (Disclaimer: I don’t have much experience writing cases, but I want to get better at it.)

Without further ado…

You’re interested in gaining a better understanding of the likelihood, or probability p, that certain agents will perform a given action that benefits you. So you hire a group of business analytics consultants who create a statistical learning model M that predicts the value of p with high accuracy given an agent (and their attributes/characteristics) as input.

Those agents with high-enough probability of performing the action, say p \geq 50\% (a subjective choice), don’t concern you too much because they’re already on your side. Your focus is on those whose value of p is less than 50%. One of the outcomes of model M is a number for each agent (or group of similar agents) indicating how much of an effect giving that agent a financial incentive would have on the value of their action probability p. For example, this number could be 0.1 for a given agent, indicating that they’d be 10% more likely to perform the action for each $1000 of incentive they receive. So, assuming a linear model, if their originally predicted p were 35%, giving them $2000 would be enough to push them beyond your target 50% threshold. (Considering incentives are given in multiples of $1000.)

Before we go any further, let me make this more concrete with a few examples.

Example 1: You are the seller of a product. Agents are customers. The action is purchasing your product. The financial incentive is a discount. You have a budget for the overall discount you can give and you want to optimally allocate different discount amounts to different customers to bring as many of them as possible to the brink of buying your product (say, a 50% chance).

Example 2: You are a politician. Agents are voters. The action is voting for you. The financial incentive is a bribe. This happens in Brazil and likely in other countries as well. (Disclaimer: I’m not advocating that this is an ethical or moral thing to do. Like any superpower, however, mathematics can be used by the dark side as well.)

Example 3: You are a university. Agents are admitted students. The action is picking you to attend. The financial incentive is a scholarship.

I’m sure you can come up with other examples. Let me know in the comments!

So the big question is: How do we optimally allocate the limited pool of financial incentives? Optimization to the rescue! I’ll provide a link to an Excel spreadsheet below, but first let’s understand the math behind it.

Given n agents, for each agent i, let b_i be how much the agent’s action probability (before the incentive) is below my target threshold, and let c_i be how much agent i‘s action probability increases for each f dollars of financial incentive. In my example above, b_i=0.15 (50% minus 35%), c_i=0.1, and f=\$1000.

Let’s create two variables for each agent i. Variable x_i is an integer number indicating how many f-dollar incentives we decide to give to that agent. And variable y_i is a binary (yes/no) variable indicating whether or not we manage to bring agent i to our side (i.e. whether we raised his/her action probability beyond the threshold).

To indicate that our goal is to push as many agents beyond the action threshold as possible, we write

\displaystyle \max \sum_{i=1}^n y_i

If our total budget for financial incentives is B, we respect the budget with the following constraint (note that the sum of all x_i equals the total number off-dollar financial incentive packages given away):

\displaystyle f \sum_{i=1}^n x_i \leq B

Then, if we want y_i to be equal to 1 (meaning “yes”), we need x_i to be high enough for the increase in the agent’s action probability to exceed the threshold value. This can be accomplished with these constraints

\displaystyle b_i y_i \leq c_i x_i

In my earlier example, the above constraint would read

\displaystyle 0.15 y_i \leq 0.1 x_i

Therefore, unless x_i is at least 2, the value of y_i cannot be equal to 1.

That’s it! We are done with the math. Wasn’t that beautiful?

Here’s an Excel spreadsheet that implements this model for a random instance of this problem with 20 agents. It’s already set up with all you need to run the Solver add-in. Feel free to play with it and let me know if you have any questions.

Advertisements

1 Comment

Filed under Analytics, Applications, Integer Programming, Mathematical Programming, Modeling, Motivation, Promoting OR, Teaching

Theory versus Practice, Intangibles, Intuition, and the Usefulness of Imperfection

I felt like putting in writing a few thoughts I often find myself telling my students, and hence this post. You can download a (nicer) PDF version of it here.

Theory versus Practice: A Challenge

It was a rainy Saturday afternoon…

“Ready? Go!”

As she reached for her pencil and began scribbling, I opened an empty Excel spreadsheet and started typing in the data and thinking out loud.

“Eight integer variables, three constraints, plus lower and upper bounds. How is it going over there?”

“I’m doing OK. Let me think.”

A minute later, I click “Solve” and declare victory.

“There you go: $2.80. Can’t beat that!”

“Five buns? Do you expect people to eat a burger with five buns?”

“Hmm…you’re right. One more constraint… voilà $2.62. The best burger on the market! What did you get?”

“Mine costs $2.61.”

“I win! Ha, ha!”

“But look at your burger! Nobody would ever want to eat this crap. Mine is much more appetizing.”

As I reluctantly examined the two solutions, there was no denying the obvious.

That was me and my wife solving the Good Burger puzzle. The challenge is to create the most expensive burger out of a given set of ingredients such as beef patties, cheese, lettuce, tomato, etc., while keeping sodium, fat, and calorie counts in check. Her hand-calculated solution was suboptimal by one cent. It was technically worse than mine, but what does optimality really mean in practice?

Optimality or Bust?

Once upon a time, at the board meeting of a for-profit company…

“Today, I’m excited to report the results from the cost-cutting initiative that my team of analytics experts developed over the last six months. We managed to produce a solution to our problem that improves profits by 6%.”

“But is this solution optimal?”

Said no one ever after hearing “improves profits by 6%.”

Intangibles and Intuition

The two anecdotes above illustrate an important idea that I emphatically stress to my students every spring semester: models aren’t perfect, and that’s perfectly OK. There’s a reason why business analytics is known as “the science of better” rather than “the science of provably optimal.” More often than not, it is impossible to capture all nuances of a real-life problem into a mathematical model. Therefore, solutions produced by such a model are to be taken with a grain of salt and cautious optimism. Do these numbers still make sense after the omitted intangibles are brought back into the picture? If so, great. If not, can we slightly modify the solution? Do we need to revise the model? When building my burger, I ignored flavor considerations and overall gastronomic appeal, whereas my wife didn’t.

Another matter with which non-experts struggle is keeping their intuition from negatively affecting their modeling choices. Or, as I like to say in class, “don’t try to solve the problem; focus on representing the problem.” A mathematical model is a translation, say, from English to formulas, of the story that warrants investigation. Letting your understanding of the story bias you into thinking the solution should/shouldn’t look a certain way, and adding that assumption into your model, can be detrimental. As humans, we tend to think intuitively, which in turn limits the universe of possibilities we look at. Good solutions to complex problems can be, at least at first sight, counterintuitive. Make sure your model has the freedom to consider “weird” courses of action as well.

The Usefulness of Imperfection

Imperfect models create imperfect solutions that can still be useful. Having a solution in the ballpark of good answers is better than looking at a blank slate and not knowing where to begin. Solving a model many times with a range of input values improves your understanding of how certain numbers relate to others. As your understanding of the problem improves, that (initially) counterintuitive solution starts to make sense. Improved understanding leads to revising your initial assumptions and even realizing that what you thought mattered is secondary. What really matters is this other number to which you didn’t pay much attention to begin with. In extreme cases, this first model may lead you to conclude that you need to create a completely different model to solve a completely different problem, and that’s OK too! You are learning about your problem in the process of trying to solve your problem. Finally, it may very well be that your problem, as originally stated, has no solution. This would have been difficult to detect by hand because complex problems have several moving parts with intricate relationships of cause and effect. Having a model whose output says “infeasible” can be a valuable tool in a meeting. It is concrete proof that the original question and/or assumptions are inconsistent in some way. (Assuming there’s no mistake in the model, of course.) From there, it will be a much shorter path to convincing people to revise the question/assumptions than it would have been otherwise. Who would have thought? Modeling also makes your meetings more efficient!

1 Comment

Filed under Analytics, Modeling, Promoting OR, Teaching, Tips and Tricks

Buying Metrorail Tickets in Miami

(Credits: Thanks to my MBA student Mike Plytynski for the idea for this post.)

Instead of a subway system, Miami has surface trains like the one depicted below. This is known as our Metrorail system. The Metrorail connects to the Tri-Rail system (which takes you north as far as West Palm Beach) and also to the free-to-ride, fully-automated, electrically-powered Metromover.

If you are a (reasonably) frequent Metrorail rider, you may consider buying a rechargeable card at one of the ticket vending machines. There is a 1-day pass ($5.65), a 7-day pass ($29.25), and a monthly pass ($112.50) that offer unlimited rides, but let’s focus on the case when you don’t ride often enough to justify the cost of such passes.

The current cost of a one-way trip is $2.25, regardless of distance traveled. The vending machines at the entrance of each Metrorail station allow you to load the following pre-specified amounts onto your card: $1, $2.25, $3, $4.50, $5, $10, $20, and $40.

No one likes to waste time having to stop by the vending machine to reload the Metrorail card. Besides, by Murphy’s Law, the next train will arrive and depart exactly when you’re stuck in line at the machine trying to reload your card. Therefore, we’ll consider that our objective is to minimize the number of visits to the vending machine to load our card with enough money for n one-way trips. If we were free to load any amount on the card, we could simply load n times $2.25 and be done. The absence of this flexibility is what makes this situation both interesting and a reason for us to hate the Metrorail. So let’s write an optimization model to solve this problem.

Let variable x_1 be the number of times we go to the vending machine to load $1 on the card. Let x_2 be the number of times we load $2.25 on the card, and so on all the way to x_8 (how many times we load $40). To minimize the number of visits to the vending machine, we write the objective function

\min x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 + x_8

To make sure we load enough money on the card for n trips, we write the constraint

x_1 + 2.25x_2 + 3x_3 + 4.5x_4 + 5x_5 + 10x_6 + 20x_7 + 40x_8 \geq 2.25n

If we are not careful, we may end up with unnecessarily too much money left on the card. So it’s wise to limit that excess with the constraint

x_1 + 2.25x_2 + 3x_3 + 4.5x_4 + 5x_5 + 10x_6 + 20x_7 + 40x_8 - 2.25n \leq L

where L is a limit on what we’d be willing to have left on the card after the n trips are completed. Conceivably, this leftover amount could be applied toward your next batch of n trips. Hold that thought; we’ll return to it later.

I put together an Excel Solver spreadsheet model for this problem, which you can download from here (sheet named “standard” in the Excel file).

If you change the second constraint above to an equality and solve this problem for different values of n and L, you can create the following heat map. The numbers in the colored squares indicate the minimum number of required visits to the vending machine.

Interestingly, some values of n, such as 10, 18, and 20, are more friendly in the sense that they allow you to visit the machine at most twice while incurring a small leftover amount (no more than $0.50). On the other hand, to avoid visiting the machine more than twice when paying for 12, 14, or 16 trips, you must be willing to accept a much higher ending balance: $3, $8.50, and $4, respectively. In addition, some of the reload amounts that might at first seem useless, such as $5 and $10, actually do get used in the optimal solutions for some values of n and L.

Ending Balances As Multiples of $2.25

As we saw above, allowing for larger ending balances on the card can help reduce the number of visits to the vending machine. One way to make these balances useful is to apply them toward future trips. If the balance is a multiple of the cost of a one-way trip, even better. To do that, we can replace the second constraint above with

x_1 + 2.25x_2 + 3x_3 + 4.5x_4 + 5x_5 + 10x_6 + 20x_7 + 40x_8 - 2.25n = 2.25k

where k is a new, non-negative integer variable. The sheet called “leftover is multiple” in this Excel file implements this version of the optimization model. The conclusion is that you pretty much only need 2 visits to the vending machine for n \leq 20, and the value of k seems to decrease as n increases. (See Excel file for detailed results.)

Now, if only I could get someone from Miami-Dade Transit to read this post…

Leave a comment

Filed under Applications, Integer Programming, Knapsack, Mathematical Programming, Modeling, Motivation, Promoting OR, transportation

Bringing Research into the Classroom: Can Relevant and Impactful be Easy to Explain?

math-equation_chalkboard O.R. researchers and practitioners are constantly churning out papers that tackle a wide variety of important and hard-to-solve practical problems. On one hand, as a researcher, I understand how difficult these problems can be and how it’s often the case that fancy math and complex algorithms need to be used. On the other hand, as someone who teaches optimization to MBA students who aren’t easily excited by mathematics, I’m always looking for motivational examples that are both interesting and not too complex to be understood in 5 minutes. (That’s the little slot of time I reserve at the beginning of my lectures to go over an application before the lecture itself starts.)

Every now and then, I come across a paper that fits the bill perfectly: it addresses an important problem, produces impactful results, and (here comes the rare part), accomplishes the previous two goals by using math that my MBA students can follow 100%, while being confident that they themselves could replicate it given what they learned in my course (the optimization models).

The paper to which I’m referring has recently appeared in Operations Research (Articles in Advance, January 2017): The Impact of Linear Optimization on Promotion Planning, by Maxime C. Cohen, Ngai-Hang Zachary Leung, Kiran Panchamgam, Georgia Perakis, and Anthony Smith (http://dx.doi.org/10.1287/opre.2016.1573).

If I had to pick one word to describe this paper, it would be BEAUTIFUL.

I immediately proceeded to put together a 5-minute summary presentation (8 slides) to cover the problem, approach, and results. I’ll be showing this to 100 of my MBA students on this coming Tuesday (Valentine’s Day!). I hope they love it as much as I did. Feel free to show this presentation to your own students if you wish, and let me know how it went down in the comments.

A recent Poets & Quants article explains how business schools with the highest quality teaching strive to bring their faculty’s research into the classroom so that students get to learn the latest and greatest ideas. The O.R. paper above is a perfect example of when this can be done effectively.

Leave a comment

Filed under Analytics, Applications, Integer Programming, Linear Programming, Modeling, Motivation, Promoting OR, Research, Teaching

How to Build the Best Fantasy Football Team, Part 2

UPDATE on 10/5/2015: Explained how to model a requirement of baseball leagues (Requirement 4).

UPDATE on 10/8/2015: Explained how to model a different objective function (Requirement 5).

 

fantasy-football-ringYesterday, I wrote a post describing an optimization model for picking a set of players for a fantasy football team that maximizes the teams’ point projection, while respecting a given budget and team composition constraints. In this post I’ll assume you’re familiar with that model. (If you are not, please spend a few minutes reading this first.)

Fellow O.R. blogger and Analytics expert Matthew Galati pointed out that my model did not include all of the team-building constraints that appear on popular fantasy football web sites. Therefore, I’m writing this follow-up post to address this issue. (Thanks, Matthew!) My MBA student Kevin Bustillo was kind enough to compile a list of rules from three sites for me. (Thanks, Kevin!) After looking at them, it seems my previous model fails to deal with three kinds of requirements:

  1. Rosters must include players from at least N_1 different NFL teams (N_1=2 for Draft Kings and N_1=3 for both Fan Duel and Yahoo!).
  2. Rosters cannot have more than N_2 players from the same team (N_2=4 for Fan Duel and N_2=6 for Yahoo! Draft Kings does not seem to have this requirement).
  3. Players in the roster must represent at least N_3 different football games (Only Draft Kings seems to have this requirement, with N_3=2).

Let’s see what the math would look like for each of the three requirements above. (Converting this math into Excel formulas shouldn’t be a problem if you follow the methodology I used in my previous post.) I’ll be using the same variables I had before (recall that binary variable x_i indicates whether or not player i is on the team).

Requirement 1

Last time I checked, the NFL had 32 teams, so let’s index them with the letter j=1,2,\ldots,32 and create 32 new binary variables called y_j, each of which is equal to 1 when at least one player from team j is on our team, and equal to zero otherwise. The requirement that our team must include players from at least N_1 teams can be written as this constraint:

\displaystyle \sum_{j=1}^{32} y_j \geq N_1

The above constraint alone, however, won’t do anything unless the y_j variables are connected with the x_i variables via additional constraints. The behavior that we want to enforce is that a given y_j can only be allowed to equal 1, if at least one of the players from team j has its corresponding x variable equal to 1. To make this happen, we add the constraint below for each team j:

\displaystyle y_j \leq \sum_{\text{all players } i \text{ that belong to team } j} x_i

For example, if the Miami Dolphins are team number 1 and their players are numbered from 1 to 20, this constraint would look like this: y_1 \leq x_1 + x_2 + \cdots + x_{20}

Requirement 2

Repeat the following constraint for every team j:

\displaystyle \sum_{\text{all players } i \text{ that belong to team } j} x_i \leq N_2

Assuming again that the first 2o players represent all the players from the Miami Dolphins, this constraint on Fan Duel would look like this: x_1 + x_2 + \cdots + x_{20} \leq 4

Requirement 3

My understanding of this requirement is that it applies to short-term leagues that get decided after a given collection of games takes place (it could even be a single-day league). This could be implemented in a way that’s very similar to what I did for requirement 1. Create one binary z_g variable for each game g. It will be equal to 1 if your team includes at least one player who’s participating in game g, and equal to zero otherwise. Then, you need this constraint

\displaystyle \sum_{\text{all games } g} z_g \geq N_3

as well as the constraint below repeated for each game g:

\displaystyle z_g \leq \sum_{\text{all players } i \text{ that participate in game } g} x_i


Additional Requirements Submitted by Readers

I earlier claimed that this model can be adapted to fit fantasy leagues other than football. So here’s a question I received from one of my readers:

For fantasy baseball, some players can play multiple positions. E.g. Miguel Cabrera can play 1B or 3B. I currently use OpenSolver for DFS and haven’t found a good way to incorporate this into my model. Any ideas?

Let’s call this…

Requirement 4: What if some players can be added to the team at one of several positions?

Here’s how to take care of this. Given a player i, let the index t=1,2,\ldots,T_i represent the different positions he/she can play. Instead of having a binary variable x_i representing whether or not i is on the team, we have binary variables x_{it} (as many as there are possible values for t) representing whether or not player i is on the team at position t. Because a player can either not be picked or picked to play one position, we need the following constraint for each of these multi-position players:

\displaystyle \sum_{t=1}^{T_i} x_{it} \leq 1

Because we have replaced x_i with a collection of x_{it}‘s, we need to replace all occurrences of x_i in our model with (x_{i1} + x_{i2} + \cdots + x_{iT_i}).

In the Miguel Cabrera example above, let’s say Cabrera’s player ID (the index i) is 3, and that t=1 represents the first-base position, and t=2 represents the third-base position. The constraint above would become

x_{31} + x_{32} \leq 1

And we would replace all occurrences of x_3 in our model with (x_{31} + x_{32}).

That’s it!


Reader rs181602 asked me the following question:

I was wondering, is there a way to add an additional constraint that maximizes the minimum rating of the chosen players, if each player has some rating score. I tried to think that out, but can’t seem to get it to be linear.

Let’s call this…

Requirement 5: What if I want to maximize the point projection of the worst player on the team? (In other words, how do I make my worst player as good as possible?)

It’s possible to write a linear model to accomplish this. Technically speaking, we would be changing the objective function from maximizing the total point projection of all players on the team to maximizing the point projection of the worst player on the team. (There’s a way to do both together (sort of). I’ll say a few words about that later on.)

Here we go. Because we don’t know what the projection of the worst player is, let’s create a variable to represent it and call it z. The objective then becomes:

\max z

You might have imagined, however, that this isn’t enough. We defined in words what we want z to be, but we still need formulas to make z behave the way we want. Let M be the largest point projection among all players that could potentially be on our team. It should be clear to you that the constraint z\leq M is a valid ceiling on the value of z. In fact, the value of z will be limited above by 9 values/ceilings: the 9 point projections of the players on the team. We want the lowest of these ceilings to be as high as possible.

When a player i is not on the team (x_i=0), his point projection p_i should not interfere with the value of z. When player i is on the team (x_i=1), we would like p_i to become a ceiling for z, by enforcing z\leq p_i. The way to make this happen is to write a constraint that changes its behavior depending on the value of x_i, as follows:

z \leq p_ix_i + M(1-x_i)

We need one of these for each player. To see why the constraint above works, consider the two possibilities for x_i. When x_i=0 (player not on the team), the constraint reduces to z\leq M (the obvious ceiling), and when x_i=1 (player on the team), the constraint reduces to z\leq p_i (the ceiling we want to push up).

BONUS: What if I want, among all possible teams that have the maximum total point projection, the one team whose worst player is as good as possible? To do this, you solve two optimization problems. First solve the original model maximizing the total point projection. Then switch to this \max z model and include a constraint saying that the total point projection of your team (the objective formula of the first model) should equal the total maximum value you found earlier.

That’s it!


And that does it, folks!

Does your league have other requirements I have not addressed here? If so, let me know in the comments. I’m sure most (if not all) of them can be incorporated.

24 Comments

Filed under Analytics, Applications, Integer Programming, Modeling, Motivation, Sports

How to Build the Best Fantasy Football Team

Note 1: This is Part 1 of a two-part post on building fantasy league teams. Read this first and then read Part 2 here.

Note 2: Although the title says “Fantasy Football”, the model I describe below can, in principle, be modified to fit any fantasy league for any sport.

footballI’ve been recently approached by several people (some students, some friends) regarding the creation of optimal teams for fantasy football leagues. With the recent surge of betting sites like Fan Duel and Draft Kings, this has become a multi-million (or should I say, billion?) dollar industry. So I figured I’d write down a simple recipe to help everybody out. We’re about to use Prescriptive Analytics to bet on sports. Are you ready? Let’s do this! I’ll start with the math model and then show you how to make it all work using a spreadsheet.

The Rules

The fantasy football team rules state that a team must consist of:

  • 1 quarterback (QB)
  • 2 running backs (RB)
  • 3 wide receivers (WR)
  • 1 tight end (TE)
  • 1 kicker
  • 1 defense

Some leagues also have what’s called a “flex player”, which could be either a RB, WR, or TE. I’ll explain how to handle the flex player below. In addition, players have a cost and the person creating the team has a budget, call it B, to abide by (usually B is $50,000 or $60,000).

The Data

For each player i, we are given the cost mentioned above, call it c_i, and a point projection p_i. The latter is an estimate of how many points we expect that player to score in a given week or game. When it comes to the defense, although it doesn’t always score, there’s also a way to calculate points for it (e.g. points prevented). How do these point projections get calculated, you may ask? This is where Predictive Analytics come into play. It’s essentially forecasting. You look at past/recent performance, you look at the upcoming opponent, you look at players’ health, etc. There are web sites that provide you with these projections, or you can calculate your own. The more accurate you are at these predictions, the more likely you are to cash in on the bets. Here, we’ll take these numbers as given.

The Optimization Model

The main decisions to be made are simple: which players should be on our team? This can be modeled as a yes/no decision variable for each player. So let’s create a binary variable called x_i which can only take two values: it’s equal to the value 1 when player i is on our team, and it’s equal to the value zero when player i is not on our team. The value of i (the player ID) ranges from 1 to the total number of players available to us.

Our objective is to create a team with the largest possible aggregate value of projected points. That is, we want to maximize the sum of point projections of all players we include on the team. This formula looks like this:

\max \displaystyle \sum_{\text{all } i} p_i x_i

The formula above works because when a player is on the team (x_i=1), its p_i gets multiplied by one and is added to the sum, and when a player isn’t on the team (x_i=0) its p_i gets multiplied by zero and doesn’t get added to the final sum. The mechanism I just described is the main idea behind what makes all formulas in this model work. For example, if the point predictions for the first 3 players are 12, 20, and 10, the maximization function start as: \max 12x_1 + 20x_2 + 10x_3 + \cdots

The budget constraint can be written by saying that the sum of the costs of all players on our team has to be less than or equal to our budget B, like this:

\displaystyle \sum_{\text{all }i} c_i x_i \leq B

For example, if the first 3 players cost 9000, 8500, and 11000, and our budget is 60,000, the above formula would look like this: 9000x_1 + 8500x_2 + 11000x_3 + \cdots \leq 60000.

To enforce that the team has the right number of players in each position, we do it position by position. For example, to require that the team have one quarterback, we write:

\displaystyle \sum_{\text{all } i \text{ that are quarterbacks}} x_i = 1

To require that the team have two running backs and three wide receivers, we write:

\displaystyle \sum_{\text{all } i \text{ that are running backs}} x_i = 2

\displaystyle \sum_{\text{all } i \text{ that are wide receivers}} x_i = 3

The constraints for the remaining positions would be:

\displaystyle \sum_{\text{all } i \text{ that are tight ends}} x_i = 1

\displaystyle \sum_{\text{all } i \text{ that are kickers}} x_i = 1

\displaystyle \sum_{\text{all } i \text{ that are defenses}} x_i = 1

The Curious Case of the Flex Player

The flex player adds an interesting twist to this model. It’s a player that, if I understand correctly, takes the place of the kicker (meaning we would not have the kicker constraint above) and can be either a RB, WR, or TE. Therefore, right away, we have a new decision to make: what kind of player should the flex be? Let’s create three new yes/no variables to represent this decision: f_{\text{RB}}, f_{\text{WR}}, and f_{\text{TE}}. These variables mean, respectively: is the flex RB?, is the flex WR?, and is the flex TE? To indicate that only one of these things can be true, we write the constraint below:

f_{\text{RB}} + f_{\text{WR}} + f_{\text{TE}} = 1

In addition, having a flex player is equivalent to increasing the right-hand side of the constraints that count the number of RB, WR, and TE by one, but only for a single one of those constraints. We achieve this by changing these constraints from the format they had above to the following:

\displaystyle \sum_{\text{all } i \text{ that are running backs}} x_i = 2 + f_{\text{RB}}

\displaystyle \sum_{\text{all } i \text{ that are wide receivers}} x_i = 3 + f_{\text{WR}}

\displaystyle \sum_{\text{all } i \text{ that are tight ends}} x_i = 1 + f_{\text{TE}}

Note that because only one of the f variables can be equal to 1, only one of the three constraints above will have its right-hand side increased from its original value of 2, 3, or 1.

Other Potential Requirements

Due to personal preference, inside information, or other esoteric considerations, one might want to include other requirements in this model. For example, if I want the best team that includes player number 8 and excludes player number 22, I simply have to force the x variable of player 8 to be 1, and the x variable of player 22 to be zero. Another constraint that may come in handy is to say that if player 9 is on the team, then player 10 also has to be on the team. This is achieved by:

x_9 \leq x_{10}

If you wanted the opposite, that is if player 9 is on the team then player 10 is NOT on the team, you’d write:

x_9 + x_{10} \leq 1

Other conditions along these lines are also possible.

Putting It All Together

If you were patient enough to stick with me all the way through here, you’re eager to put this math to work. Let’s do it using Microsoft Excel. Start by downloading this spreadsheet and opening it on your computer. Here’s what it contains:

  • Column A: list of player names.
  • Column B: yes/no decisions for whether a player is on the team (these are the x variables that Excel Solver will compute for us).
  • Columns C through H: flags indicating whether or not a player is of a given type (0 = no, 1 = yes).
  • Columns I and J: the cost and point projections for each player.

Now scroll down so that you can see rows 144 through 150. The cells in column B are currently empty because we haven’t chosen which players to add to the team yet. But if those choices had been made (that is, if we had filled column B with 0’s and 1’s), multiplying column B with column C in a cell-wise fashion and adding it all up would tell you how many quarterbacks you have. I have included this multiplication in cell C144 using the SUMPRODUCT formula. In a similar fashion, cells D144:H144 calculate how many players of each kind we’d have once the cells in column B receive values. The calculations of total team cost and total projected points for the team are analogous to the previous calculations and also use the SUMPRODUCT formula (see cells I144 and J144). You can try picking some players by hand (putting 1’s in some cells of column B) to see how the values of the cells in row 144 will change.

If you now open the Excel Solver window (under the Data tab, if your Solver add-in is active), you’ll see that I already have the entire model set up for you. If you’ve never used Excel Solver before, the following two-part video will get you started with it: part 1 and part 2.

The objective cell is J144, and that’s what we want to maximize. The variables (a.k.a. changing cells) are the player selections in column B, plus the flex-player type decisions (cells D147:F147). The constraints say that: (1) the actual number of players of each type (C144:H144) are equal to the desired number of each type (C146:H146), (2) the total cost of the team (I144) doesn’t exceed the budget (I146), (3) the three flex-player binary variables add up to 1 (D150 = F150), and, (4) all variables in the problem are binary. (I set the required number of kickers in cell G146 to zero because we are using the flex-player option. If you can have both a flex player and a kicker, just type a 1 in cell G146.) If you click on the “Solve” button, you’ll see that the best answer is a team that costs exactly $50,000 and has a total projected point value of 78.3. Its flex player ended up being an RB.

This model is small enough that I can solve it with the free student version of Excel Solver (which comes by default with any Office installation). If you happen to have more players and your total variable count exceeds 200, the free solver won’t work. But don’t despair! There exists a great Solver add-in for Excel that is also free and has no size limit. It’s called OpenSolver, and it will work with the exact same setup I have here.

That’s it! If you have any questions or remarks, feel free to leave me a note in the comments below.

UPDATE: In a follow-up post, I explain how to model a few additional fantasy-league requirements that are not included in the model above.

18 Comments

Filed under Analytics, Applications, Integer Programming, Modeling, Motivation, Sports

Semantic Typing: When Is It Not Enough To Say That X Is Integer?

Andre Cire, John Hooker, and I recently finished a paper on an interesting, and somewhat controversial, topic that relates to high-level modeling of optimization problems. The paper is entitled “Modeling with Metaconstraints and Semantic Typing of Variables“, and its current version can be downloaded from here.

Here’s the abstract:

Recent research in the area of hybrid optimization shows that the right combination of different technologies, which exploits their complementary strengths, simplifies modeling and speeds up computation significantly. A substantial share of these computational gains comes from better communicating problem structure to solvers. Metaconstraints, which can be simple (e.g. linear) or complex (e.g. global) constraints endowed with extra behavioral parameters, allow for such richer representation of problem structure. They do, nevertheless, come with their own share of complicating issues, one of which is the identification of relationships between auxiliary variables of distinct constraint relaxations. We propose the use of additional semantic information in the declaration of decision variables as a generic solution to this issue. We present a series of examples to illustrate our ideas over a wide variety of applications.

Optimization models typically declare a variable by giving it a name and a canonical type, such as real, integer, binary, or string. However, stating that variable x is integer does not indicate whether that integer is the ID of a machine, the start time of an operation, or a production quantity. In other words, variable declarations say little about what the variable means. In the paper, we argue that giving a more specific meaning to variables through semantic typing can be beneficial for a number of reasons. For example, let’s say you need an integer variable x_j to represent the machine assigned to job j. Instead of writing something like this in your modeling language (e.g. AMPL):

var x{j in jobs} integer;

it would be beneficial to have a language that allows you to write something like this

x[j] is which machine assign(job j);

To see why, take a look at the paper ;-)

Leave a comment

Filed under Modeling, Research