Let us start with a simple question. How long does it on average take to throw two times 6 in a row when throwing dice? I have treated average waiting times in one of the examples for Euler Math Toolbox (see here). But I want to treat more examples for sequences of random numbers in this posting.
The probability s(n) to get two consecutive 6 for the first time exactly after n throws can only be expressed recursively. So the usual way to compute the average waiting time as in infinite sum of n*s(n) is not really feasible.
For the more simple waiting for a single 6, this approach can be used. We have for the probability to get the first 6 after n throws
s(n) = \left(\frac56\right)^{n-1} \frac16Using a well-known formula (which we do not explain here), we get
\sum_{n=1}^\infty n \left(\frac56\right)^{n-1} \frac16 = 6Another idea is to compute the average waiting time for two consecutive 6 by computing the average distance of two consecutive 6 in a very large sequence of dice throws This gets complicated due to the fact that there might also be 3 consecutive 6. For the simple waiting for a 6, the average distance between to 6 is obviously 6. So, this case would be easy.
The most simply idea for waiting times is to represent the dice throws by two states.
- S1: We have just thrown a 6
- S2: We have just thrown any other number
Now, throwing dice is a game that is in one of these states at each point, and switches the states in a random way.
- From S1 to S2 we get with a probability of 5/6. With probability 1/6 the game exits from S1.
- From S2 to S1 we get with a probability of 1/6. From S2 to S2 with a probability of 5/6.
If W1 is the waiting time for the game to exit when it starts at S1, and W2 the exit time from S2, we get the following equations.
W_1 =1 + \frac56 W_2 \\ W_2 = 1 + \frac16 W_1 + \frac56 W_2
The reasoning is that it takes one more step via S2 on average if we are in S1 to exit the game, and we have to take the detour via S2 on average 5/6 of all times. This system of equations has the solution
W_1 = 36, \quad W_2 = 42
The answer to our question is like starting in S2. So the average waiting time is 42, a nice number.
If we know that the first throw is a 6, we only have to wait 36 throws on average. The reason for this improvement is that we have a chance of 1/6 to throw a 6 with our second throw.
How would this trick work for a simple wait for a 6? The formula for the average waiting time is clearly
W = 1 + \frac56W
with the solution W=6. The idea is that we either throw a 6 immediately with probability 1/6, or another number with probability 5/6. So we are either done after one throw, or we have to wait another W+1 throws on average, i.e.
W = \frac16 + \frac56 (W+1) = 1 + \frac56 W.
The usual way to represent such problems is using a transition matrix, in our case
A = \begin{pmatrix}0 & 5/6 \\ 1/6 & 5/6\end{pmatrix}and write the equations in matrix form as
W = {\bf 1} + AW \quad\Longleftrightarrow (I - A)W = {\bf 1} For another example, we throw a coin (with sides 0 and 1) and ask for the first time when the sequence 1011 is expected to appear. We have the following states this time.
- S0 : We are starting to wait.
- S1 : We have a 1
- S10 : We have a 10
- S101 : We have a 101
We can only exit from S101. The transition probabilities are as follows.
- S0->S0 (throwing another 0) and S0->S1 (throwing a needed 1) : 1/2.
- S1->S10 (throwing a needed 0) and S1->S1 (throwing another 1) : 1/2
- S10 ->S0 (throwing a useless 0) and S10 -> S101 (throwing a needed 1) : 1/2
- S101 -> S10 (throwing a 0, but still getting the sequence 10) : 1/2
The transition matrix is as follows.
A = \begin{pmatrix}
1/2 & 1/2 & 0 & 0 \\
0 & 1/2 & 1/2 & 0 \\
1/2 & 0 & 0 & 1/2 \\
0 & 0 & 1/2 & 0
\end{pmatrix}Solving the system of equations yields
W = \begin{pmatrix}18 \\ 16 \\14 \\ 8 \end{pmatrix} Thus, the average waiting time turns out to be 18.
We can use a Monte-Carlo simulation to confirm this result. The following Java program simulates one million runs.
/**
* Determine the waiting time for a pattern of random numbers by Monte-Carlo
* methods.
*/
public class WaitingTimes
{
public static void main (String args[])
{
// pattern to seek for
int pattern[] =
{ 1, 0, 1, 1 };
// random numbers from 0 to range-1
int range = 2;
// number of repetitions of the experiment
int rep = 1000000;
// sum results for average
int sum = 0;
// size of the pattern
int size = pattern.length;
// space for the last size random numbers
int last[] = new int[size];
for (int k = 0; k < rep; k++)
// repeat experiment rep times.
{
// fill last[] with random numbers
for (int i = 0; i < size; i++)
last[i] = getrandom(range);
// count of needed random numbers
int count = size;
while (true)
// repeat adding a random number until pattern
// is found.
{
// check if pattern found
boolean found = true;
for (int i = 0; i < size; i++)
if (last[i] != pattern[i])
{
found = false;
break;
}
if (found) break;
// add a new random number.
for (int i = 0; i < size - 1; i++)
last[i] = last[i + 1];
last[size - 1] = getrandom(range);
count++;
}
// sum up for average
sum += count;
}
// pint average.
System.out.println((double) sum / rep);
}
static int getrandom (int range)
{
return (int) (Math.random() * range);
}
}
The result of one simulation was 18.020663.
Assume, you are playing coin throwing and got a score of +2 already, i.e., two more heads than tails. How long do you have to wait on average until you reach +3?
The answer is counter-intuitive. It seems that we are very likely to reach +3 soon. You have a chance of 1/2 to reach it with one throw. But if you are like me, you can get very worried if you drop down in your score and it does not seem to go up ever again. After all, you were at +2 already, but you just seem to be unable to recover from a bit of bad luck. The fact of life is, however, that your average waiting time is infinite.
That does not mean that you cannot reach +3 ever. In fact, you might eventually. Mathematically, you reach it „almost certainly“.
But if you average the times on several tries, you will get ever bigger averages the longer you try.
Let us try a simulation in Java. For this, we will eventually have to give up after a given number of throws.
public class WaitingTimes
{
public static void main (String args[])
{
int NMax = 1000000;
int Ntries = 100000;
double Sum = 0;
double Success = 0;
for (int i = 0; i < Ntries; i++)
{
int W = 2;
int n;
for (n = 1; n <= NMax; n++)
{
W = W + ((Math.random() < 0.5) ? -1 : 1);
if (W >= 3)
{
Success++;
break;
}
}
Sum += n;
}
System.out.println("Average : " + (Sum / Ntries));
System.out.println("Success Rate : " + Success / Ntries);
}
}
I tried 100’000 tries to reach 3 above with a maximal waiting length of 100’000. The average waiting time is about 500 with a success rate of like 99%. If we increase the maximal length before we give up to 1’000’000 the average waiting time increases to 1700 and the success rate is like 99.9%.
The question if the score is greater than the score +2 at the beginning after exactly N steps is easy to answer, and approximately 1/2. But the steps are not independent. Yet, it can be shown that the chance of ever reaching +3 in N steps converges to 1.
The average waiting is a completely different question. For the simulation above where we give up after a certain maximal number of throws, it is not easy to compute. So, we use a different approach. We use N states S1,…,SN with wins 3-1, 3-2, …, 3-N. State S1 will exit with probability 1/2. For state SN, We assume that we stay there with probability 1/2. This makes it even easier to reach +3, and is therefore an underestimation of the waiting time.
For a specific example let us take N=3. We get the following transition matrix, describing the probabilities to go from one state to another state.
A = \begin{pmatrix}0 & 1/2 & 0 \\ 1/2 & 0 & 1/2 \\ 0 & 1/2 & 1/2\end{pmatrix}We can then solve the average waiting times to exit the game if we start in states 1,2,3 as follows.
For larger N, it turns out that W1 is always 2N. This is not easy to prove. But here is a computation with Euler Math Toolbox and N=20.
>N=20;
>A=zeros(N,N);
>A=setdiag(A,1,1/2);
>A=setdiag(A,-1,1/2);
>A[N,N]=1/2;
>A=id(N)-A;
>short A\ones(N,1)
40
78
114
148
180
...
If we also exit and give up in state SN (after losing too much), we get a completely symmetrical result with a waiting time for exit when starting in S1 or SN of N. That means that if you decide to give up after reaching something like -100, you will have to wait on average 100 throws before that happens. Let us simulate that.
public class WaitingTimesCase2
{
public static void main (String args[])
{
int NMax = 100;
int Ntries = 100000;
double Sum = 0;
double Success = 0;
double Failures = 0;
for (int i = 0; i < Ntries; i++)
{
int W = -1;
int n = 0;
while (true)
{
n++;
W = W + ((Math.random() < 0.5) ? -1 : 1);
if (W >= 0)
{
Success++;
break;
}
else if (W < -NMax)
{
Failures++;
break;
}
}
Sum += n;
}
System.out.println("Average : " + (Sum / Ntries));
System.out.println("Success Rate : " + Success / Ntries);
System.out.println("Success Rate : " + Failures / Ntries);
}
}
The average waiting time will be confirmed to be close to 100. Since we start at the top end, the exit will be far more likely to happen there, and the success rate is like 99%.
To be precise, we can compute the probability PN to be in state N if we start at state 1 and do n iterations as
P = A^n e_1
If we represent the unit vector e_1 in terms of Eigenvectors, we get
P = \lambda_1^n \alpha_1 v_1 + \ldots \lambda_N^n \alpha_N v_N
In the matrices of this examples, all Eigenvalues will be smaller than 1. Thus P will converge to 0, meaning that eventually all tries exit. They usually do so with at the geometric rate given by the largest eigenvalue.
There is a lot more to write about this, and there are some proofs missing here. But this is certainly an interesting problem in probability theory.