### The problem is described below:

For the match *Limp Stoners *vs *Exmouth Breathers *the two bookmakers A and C offer different odds,

Stoners Win | Draw | Breathers Win | |

A | 4/1 (5.00) | 3/1 (4.00) | 2/3 (1.67) |

C | 3/1 (4.00) | 2/1 (3.00) | 1/1 (2.00) |

You have £100. How do you have to place your bets in order to maximize guaranteed profit no matter what the outcome of the game?

Noticing,

*One is allowed to put money on different outcomes simultaneously. So, you can bet £50 on Stoners and £20 on Draw at A, and £30 on Breathers at C.**The numbers for the odds mean that, for example, if you bet £1 on Stoners at BrokeLads you will get £5.00 back (your own £1 and £4 winning). The fraction format specifies how much you would win if you bet £1, the decimal format specifies how much you would get back if you bet £1 (so, it’s the same as the fraction + 1*.

### Thought & Solution

Here are my thought and solution.

Given that the requirement in the description, *no matter what the outcome*, which suggests that no matter Stoners win, Breathers win or ended up in tie, the profit is maximised and **the same** for them. (If we use mathematical expectation, then the approach will be different.)

Also, if there multiple bookmakers, then for the same outcome, we always choose the bookmaker with highest odds. For example, for the outcome that Stoners win, odds provided by bookmaker A is 5 versus 3 at bookmaker C, thus we choose bookmaker A to put our stake on Stoners win.

Let's use $x_1, x_2, x_3$ to denote the stakes we put on Stoners Win, Draw and Breathers Win respectively. And the total amount of available money is $\mathcal{M}=100$. Then obviously, the first constrain is $\sum_{i=1}^3=x_1+x_2+x_3=\mathcal{M}=100$.

Another two equations we can find are shown below.

$$\begin{align} \left\{ \begin{aligned} 5*x_1 - 4*x_2 + 0*x_3 &= 0\\ 5*x_1 + 0*x_2 - 2*x_3 &= 0 \end{aligned} \right.\\ \end{align} $$

Because no matter what the outcome, our profit is maximised and the same. If Stoners win, our income is $5x_1-100$, if the result is draw, then profit is $4x_2-100$. And them should be equal, thus to say we have the follow equation,

\begin{align} \begin{aligned} &5*x_1-100 = 4*x_2-100\\ &5*x_1 - 4*x_2 + 0*x_3 = 0 \end{aligned} \end{align}

As for $5*x_1+0*x_2-2*x_3=0$, it's basically the same. If Stoners win, our income is $5x_1-100$, if the result is Breathers win, then profit is $2x_3-100$. Then we have the follow equation,

\begin{align} \begin{aligned} &5*x_1-100 = 2*x_3-100\\ &5*x_1 + 0*x_2 - 2*x_3 = 0 \end{aligned} \end{align}

*As a matter of fact, there's a third equation, $0*x_1+4*x_2-2*x_3=0$. But if we take these 3 equations to solve this problem with linear algebra, the matrix will be singular matrix. *

Now we have 3 equations, we can rewrite them in matrix form.

\[\begin{bmatrix} 1 & 1 & 1\\ 5 & -4 & 0\\ 5 & 0 & -2 \end{bmatrix}\begin{bmatrix}x_1\\ x_2\\ x_3 \end{bmatrix}=\begin{bmatrix}100\\ 0\\ 0 \end{bmatrix}\]

We now have form of $\mathbf{A}\mathbf{x}=\mathbf{B}$, then left multiple $\mathbf{A}^{-1}$ at both sides we get $\mathbf{A}^{-1}\mathbf{A}\mathbf{x}=\mathbf{A}^{-1}\mathbf{B}$, which simplifies to $\mathbf{x}=\mathbf{A}^{-1}\mathbf{B}$.

We can write this solution in Python with numpy. And we can expand the number of choices beyond 3.

#!/usr/bin/python3# -*- coding: utf-8 -*-import numpy as np def solve(odds=np.zeros((0,0)), constraint=0):"""Solve gamble-like problem@param odds: np.array with shape (num_bookmakers, num_choices)@param constraint: total amount of money@return odds_indice,stakes,winningsodds_indice: np.array with shape (num_choices,) the value indicates which bookmaker to put stake onstakes: np.array with shape (num_choices,) the value indicates the amount of stakeswinnings: the amount of winnings"""# using float64 type, to get an accurate result when doing matrix inverseodds = odds.astype('float64')# get number of choices_, num_choices = odds.shape# find out which bookmaker we should choose for each choiceodds_indice = np.argmax(odds, axis=0)# get the maximum odds among available bookmakersfor each choiceodds = np.max(odds, axis=0) # Eq. $\sum_{i=1}^nx_i=\mathcal{M}$ A = np.ones((1, num_choices)) B = np.array([constraint])# fill in the rest equationsfor i in range(0, num_choices - 1):# prefixed with $i$ zerosequation = np.zeros((1, i))# just pick 2 consecutive odds# positive for the first one, negative for the second oneequation = np.append(equation, [odds[i], -odds[i+1]])# resize to (1, num_choices), filling zerosequation.resize((1, num_choices))# concatenate this equation to AA = np.concatenate((A, equation))# the result of all the equations we generate in the for loop are 0sB.resize(num_choices, 1)# solve $\mathcal{x}=\mathcal{A}^{-1}\mathcal{B}$stakes = (np.linalg.inv(A) @ B).flatten()# compute winningswinnings = stakes[0] * odds[0] return odds_indice, stakes, winnings if __name__ == '__main__': odds_indice, stakes, winnings = solve(np.array([[5, 4, 1.67], [4, 3, 2]]), 100) for i in range(stakes.shape[0]): print("Place {:.4f} on {} bookmaker on choice {}, winnings {:.4f}".format(stakes[i], odds_indice[i], i, winnings))

And the script will have the following output,

Place 21.0526 on 0 bookmaker on choice 0, winnings 105.2632 Place 26.3158 on 0 bookmaker on choice 1, winnings 105.2632 Place 52.6316 on 1 bookmaker on choice 2, winnings 105.2632