diff --git a/dewittpe-solution/frog_jump.R b/dewittpe-solution/frog_jump.R new file mode 100644 index 0000000..26ea156 --- /dev/null +++ b/dewittpe-solution/frog_jump.R @@ -0,0 +1,186 @@ +#'--- +#'title: Frog Jump Problem +#'author: Peter DeWitt +#'output: pdf_document +#'header-includes: +#' - \usepackage{blkarray} +#' - \usepackage{amsmath} +#'--- +#' +#+ label = "setup", include = FALSE, cache = FALSE +knitr::opts_chunk$set(cache = TRUE) +library(parallel) + +#' +#' # The Problem: +#' +#' A frog is on one bank of a pond. There are $p$ lily pads between the frog +#' and the opposite bank of the pond. This frog has the ability to jump from +#' the bank it starts on to any of the $p$ lily pads or all the way to the +#' opposite bank. The frog will randomly jump, with equal probability, forward, +#' at least one pad. The question is, what is the expected number of jumps +#' the frog will make to transverse the pond? +#' +#' \begin{center} +#' \begin{tabular}{cccccccc} +#' \includegraphics[width=0.10\textwidth]{grass} & +#' \includegraphics[width=0.10\textwidth]{lilypad}& +#' \includegraphics[width=0.10\textwidth]{lilypad}& +#' \ldots & +#' \includegraphics[width=0.10\textwidth]{lilypad}& +#' \includegraphics[width=0.10\textwidth]{lilypad}& +#' \includegraphics[width=0.10\textwidth]{lilypad}& +#' \includegraphics[width=0.10\textwidth]{pictures-of-green-frogs-7} \\ +#' Pad $0$ & Pad $1$ & Pad $2$ & \ldots & Pad $p - 2$ & Pad $p - 1$ & Pad $p$ & Pad $p+1$ \\ +#' GOAL: Pond bank & & & & & & & Start +#' \end{tabular} +#' \end{center} +#' +#' +#' Goals for the solution: +#' +#' 1. Solution is to be general for any number of pads. +#' 2. Solution should not rely on recursion. +#' +#' +#' # Solution +#' +#' ## Simulation +#' +#' The simulation does rely on recursion. This simulation is used to test the +#' other solution. The code is writen in [R](https://www.r-project.org). +#' +# frog_jumper +# Arguments: +# pads : the number of lily pads between the frog and the bank of the pond. +# jumps : number of jumps taken so far +# verbose : if TRUE print status. +# +# Return: +# the number of jumps needed to transverse the pond for the given simulation. +# +frog_jumper <- function(pads, jumps = 0, verbose = FALSE) { + if (verbose) {cat("jump:", jumps, "frog is on pad:", pads + 1, "\n")} + distance <- sample(x = seq(1, pads + 1, by = 1), size = 1) + if (distance > pads) { + if (verbose) {cat("jump:", jumps + 1, "frog Has Reached the bank.\n")} + return(invisible(jumps + 1)) + } else { + frog_jumper(pads = pads - distance, jumps + 1, verbose = verbose) + } +} + +#' +#' A couple quick checks of the simulation code. If there are zero pads between +#' the frog and the pond bank then the function should return 1. +set.seed(42) +frog_jumper(0, verbose = TRUE) + +#' +#' If there is one pad beween the frog and the bank then the function should +#' return the value 1 with probability 1/2 and the value 2 with probability 1/2. +#' Test this with 1,000,000 simulations. +x <- replicate(n = 1e6, expr = {frog_jumper(1)}) +prop.table(table(x)) + +#' +#' The expected number of jumps the frog will take if there is only one pad +#' between the frog an the bank is +simulation <- function(pads, iterations = 1e6) { + mean( + do.call(c, + mclapply(X = seq(1, iterations), + FUN = function(i, ...) {frog_jumper(...) }, + pads = pads, + mc.cores = 12)) + ) +} +simulation(1) + +#' +#' For 10 pads between the frog and the opposite bank, the expected number of +#' jumps the frog will take is +simulation(10) + +#' +#' ## A Maths Solution +#' +#' Define the transtion of the frog via a discrete time Markov chain with the +#' transition probability matrix $\boldsymbol{T}$ with the current state defined +#' on the rows and next state defined on columns. +#' +#' $$ \boldsymbol{T} = +#' \begin{pmatrix} \boldsymbol{Q} & \boldsymbol{B} \\ \boldsymbol{0} & 1 \end{pmatrix}.$$ +#' +#' The bottom row of $\boldsymbol{T}$ is a row vector of zeros with $p + 1$ +#' elements and the bottom right entry in $\boldsymbol{T}$ is 1. This row +#' represents the transition probability for jumping form the goal bank to the +#' goal bank. +#' $\boldsymbol{B}$ is a column vector with $p+1$ entries. This vector gives +#' the probabilities of jumping for the current pad to the goal bank. Finally, +#' the matrix $\boldsymbol{Q}$ is the $(p+1) \times (p+1)$ matrix of transition +#' probabilities from pad to pad. +#' +#' $$ \boldsymbol{Q} = +#'\begin{blockarray}{cccccc} +#' & \text{Pad } p + 1 & \text{Pad } p & \cdots & \text{Pad } 2 & \text{Pad } 1 \\ +#'\begin{block}{c(ccccc)} +#' \text{Pad } p + 1 & 0 & \frac{1}{p+1} & \cdots & \frac{1}{p+1} & \frac{1}{p+1} \\ +#' \text{Pad } p & 0 & 0 & \cdots & \frac{1}{p} & \frac{1}{p} \\ +#' \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ +#' \text{Pad } 2 & 0 & 0 & 0 & 0 & \frac{1}{2} \\ +#' \text{Pad } 1 & 0 & 0 & 0 & 0 & 0 \\ +#'\end{block} +#'\end{blockarray}. +#'$$ +#' +#' The expected number of transitions, i.e., jumps, the frog will take to +#' transverse the pond via lily pad can be found via the rowsums of the matrix +#' $\boldsymbol{J}:$ +#' $$ \boldsymbol{J} = \left( \boldsymbol{I} - \boldsymbol{Q} \right)^{-1}, $$ +#' where $\boldsymbol{I}$ is the identity matrix. +#' +#' The form of $\boldsymbol{J}$ is +#' $$ \boldsymbol{J} = +#'\begin{blockarray}{ccccccc} +#' & \text{Pad } p + 1 & \text{Pad } p & \cdots & \text{Pad } 3 & \text{Pad } 2 & \text{Pad } 1 \\ +#'\begin{block}{c(cccccc)} +#' \text{Pad } p + 1 & 1 & \frac{1}{p+1} & \cdots & \frac{1}{4} & \frac{1}{3} & \frac{1}{2} \\ +#' \text{Pad } p & 0 & 1 & \cdots & \frac{1}{4} & \frac{1}{3} & \frac{1}{2} \\ +#' \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\ +#' \text{Pad } 3 & 0 & 0 & 0 & 1 & \frac{1}{3} & \frac{1}{2} \\ +#' \text{Pad } 2 & 0 & 0 & 0 & 0 & 1 & \frac{1}{2} \\ +#' \text{Pad } 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ +#'\end{block} +#'\end{blockarray}. +#'$$ +#' +#' The expected number of jumps the frog will take from pad $p$ to get to the +#' bank is +#' +#' $$ \text{E}\left(\text{jumps}\right) = \sum_{j = 1}^{p + 1} \frac{1}{j}.$$ +#' +#' The expected number of jumps if there are 10 pads between the frog and the +#' bank is +PADS <- 10 +sum(seq(1, PADS + 1, by = 1)^-1) + +#' +#' For 20 pads between the frog and the bank: +PADS <- 20 +sum(seq(1, PADS + 1, by = 1)^-1) +simulation(PADS) + +#' +#' For 30 pads between the frog and the bank: +PADS <- 30 +sum(seq(1, PADS + 1, by = 1)^-1) +simulation(PADS) + +#' +#' The simulations and the closed form soluion see to match up. +#' +#' **Disclaimer** Part of the goal for this project was to avoid recursion in +#' the solution. The derivation of $\boldsymbol{J}$ could be considered +#' recursive. However, I would argue the final solution does not rely on +#' recursion. diff --git a/dewittpe-solution/frog_jump.Rmd b/dewittpe-solution/frog_jump.Rmd new file mode 100644 index 0000000..1073b17 --- /dev/null +++ b/dewittpe-solution/frog_jump.Rmd @@ -0,0 +1,212 @@ +--- +title: Frog Jump Problem +author: Peter DeWitt +output: pdf_document +header-includes: + - \usepackage{blkarray} + - \usepackage{amsmath} +--- + + +```{r label = "setup", include = FALSE, cache = FALSE} +knitr::opts_chunk$set(cache = TRUE) +library(parallel) +``` + + +# The Problem: + +A frog is on one bank of a pond. There are $p$ lily pads between the frog +and the opposite bank of the pond. This frog has the ability to jump from +the bank it starts on to any of the $p$ lily pads or all the way to the +opposite bank. The frog will randomly jump, with equal probability, forward, +at least one pad. The question is, what is the expected number of jumps +the frog will make to transverse the pond? + +\begin{center} +\begin{tabular}{cccccccc} +\includegraphics[width=0.10\textwidth]{grass} & +\includegraphics[width=0.10\textwidth]{lilypad}& +\includegraphics[width=0.10\textwidth]{lilypad}& +\ldots & +\includegraphics[width=0.10\textwidth]{lilypad}& +\includegraphics[width=0.10\textwidth]{lilypad}& +\includegraphics[width=0.10\textwidth]{lilypad}& +\includegraphics[width=0.10\textwidth]{pictures-of-green-frogs-7} \\ +Pad $0$ & Pad $1$ & Pad $2$ & \ldots & Pad $p - 2$ & Pad $p - 1$ & Pad $p$ & Pad $p+1$ \\ +GOAL: Pond bank & & & & & & & Start +\end{tabular} +\end{center} + + +Goals for the solution: + +1. Solution is to be general for any number of pads. +2. Solution should not rely on recursion. + + +# Solution + +## Simulation + +The simulation does rely on recursion. This simulation is used to test the +other solution. The code is writen in [R](https://www.r-project.org). + + +```{r } +# frog_jumper +# Arguments: +# pads : the number of lily pads between the frog and the bank of the pond. +# jumps : number of jumps taken so far +# verbose : if TRUE print status. +# +# Return: +# the number of jumps needed to transverse the pond for the given simulation. +# +frog_jumper <- function(pads, jumps = 0, verbose = FALSE) { + if (verbose) {cat("jump:", jumps, "frog is on pad:", pads + 1, "\n")} + distance <- sample(x = seq(1, pads + 1, by = 1), size = 1) + if (distance > pads) { + if (verbose) {cat("jump:", jumps + 1, "frog Has Reached the bank.\n")} + return(invisible(jumps + 1)) + } else { + frog_jumper(pads = pads - distance, jumps + 1, verbose = verbose) + } +} +``` + + +A couple quick checks of the simulation code. If there are zero pads between +the frog and the pond bank then the function should return 1. + +```{r } +set.seed(42) +frog_jumper(0, verbose = TRUE) +``` + + +If there is one pad beween the frog and the bank then the function should +return the value 1 with probability 1/2 and the value 2 with probability 1/2. +Test this with 1,000,000 simulations. + +```{r } +x <- replicate(n = 1e6, expr = {frog_jumper(1)}) +prop.table(table(x)) +``` + + +The expected number of jumps the frog will take if there is only one pad +between the frog an the bank is + +```{r } +simulation <- function(pads, iterations = 1e6) { + mean( + do.call(c, + mclapply(X = seq(1, iterations), + FUN = function(i, ...) {frog_jumper(...) }, + pads = pads, + mc.cores = 12)) + ) +} +simulation(1) +``` + + +For 10 pads between the frog and the opposite bank, the expected number of +jumps the frog will take is + +```{r } +simulation(10) +``` + + +## A Maths Solution + +Define the transtion of the frog via a discrete time Markov chain with the +transition probability matrix $\boldsymbol{T}$ with the current state defined +on the rows and next state defined on columns. + +$$ \boldsymbol{T} = +\begin{pmatrix} \boldsymbol{Q} & \boldsymbol{B} \\ \boldsymbol{0} & 1 \end{pmatrix}.$$ + +The bottom row of $\boldsymbol{T}$ is a row vector of zeros with $p + 1$ +elements and the bottom right entry in $\boldsymbol{T}$ is 1. This row +represents the transition probability for jumping form the goal bank to the +goal bank. +$\boldsymbol{B}$ is a column vector with $p+1$ entries. This vector gives +the probabilities of jumping for the current pad to the goal bank. Finally, +the matrix $\boldsymbol{Q}$ is the $(p+1) \times (p+1)$ matrix of transition +probabilities from pad to pad. + +$$ \boldsymbol{Q} = +\begin{blockarray}{cccccc} +& \text{Pad } p + 1 & \text{Pad } p & \cdots & \text{Pad } 2 & \text{Pad } 1 \\ +\begin{block}{c(ccccc)} +\text{Pad } p + 1 & 0 & \frac{1}{p+1} & \cdots & \frac{1}{p+1} & \frac{1}{p+1} \\ +\text{Pad } p & 0 & 0 & \cdots & \frac{1}{p} & \frac{1}{p} \\ +\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ +\text{Pad } 2 & 0 & 0 & 0 & 0 & \frac{1}{2} \\ +\text{Pad } 1 & 0 & 0 & 0 & 0 & 0 \\ +\end{block} +\end{blockarray}. +$$ + +The expected number of transitions, i.e., jumps, the frog will take to +transverse the pond via lily pad can be found via the rowsums of the matrix +$\boldsymbol{J}:$ +$$ \boldsymbol{J} = \left( \boldsymbol{I} - \boldsymbol{Q} \right)^{-1}, $$ +where $\boldsymbol{I}$ is the identity matrix. + +The form of $\boldsymbol{J}$ is +$$ \boldsymbol{J} = +\begin{blockarray}{ccccccc} +& \text{Pad } p + 1 & \text{Pad } p & \cdots & \text{Pad } 3 & \text{Pad } 2 & \text{Pad } 1 \\ +\begin{block}{c(cccccc)} +\text{Pad } p + 1 & 1 & \frac{1}{p+1} & \cdots & \frac{1}{4} & \frac{1}{3} & \frac{1}{2} \\ +\text{Pad } p & 0 & 1 & \cdots & \frac{1}{4} & \frac{1}{3} & \frac{1}{2} \\ +\vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\ +\text{Pad } 3 & 0 & 0 & 0 & 1 & \frac{1}{3} & \frac{1}{2} \\ +\text{Pad } 2 & 0 & 0 & 0 & 0 & 1 & \frac{1}{2} \\ +\text{Pad } 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ +\end{block} +\end{blockarray}. +$$ + +The expected number of jumps the frog will take from pad $p$ to get to the +bank is + +$$ \text{E}\left(\text{jumps}\right) = \sum_{j = 1}^{p + 1} \frac{1}{j}.$$ + +The expected number of jumps if there are 10 pads between the frog and the +bank is + +```{r } +PADS <- 10 +sum(seq(1, PADS + 1, by = 1)^-1) +``` + + +For 20 pads between the frog and the bank: + +```{r } +PADS <- 20 +sum(seq(1, PADS + 1, by = 1)^-1) +simulation(PADS) +``` + + +For 30 pads between the frog and the bank: + +```{r } +PADS <- 30 +sum(seq(1, PADS + 1, by = 1)^-1) +simulation(PADS) +``` + + +The simulations and the closed form soluion see to match up. + +**Disclaimer** Part of the goal for this project was to avoid recursion in +the solution. The derivation of $\boldsymbol{J}$ could be considered +recursive. However, I would argue the final solution does not rely on +recursion. diff --git a/dewittpe-solution/frog_jump.pdf b/dewittpe-solution/frog_jump.pdf new file mode 100644 index 0000000..2d9967b Binary files /dev/null and b/dewittpe-solution/frog_jump.pdf differ diff --git a/dewittpe-solution/grass.pdf b/dewittpe-solution/grass.pdf new file mode 100644 index 0000000..5b2c508 Binary files /dev/null and b/dewittpe-solution/grass.pdf differ diff --git a/dewittpe-solution/lilypad.pdf b/dewittpe-solution/lilypad.pdf new file mode 100644 index 0000000..1159a0d Binary files /dev/null and b/dewittpe-solution/lilypad.pdf differ diff --git a/dewittpe-solution/makefile b/dewittpe-solution/makefile new file mode 100644 index 0000000..9553f28 --- /dev/null +++ b/dewittpe-solution/makefile @@ -0,0 +1,5 @@ +frog_jump.pdf : frog_jump.Rmd + Rscript --vanilla -e "rmarkdown::render('$<')" + +frog_jump.Rmd : frog_jump.R + Rscript --vanilla -e "knitr::spin('$<', knit = FALSE)" diff --git a/dewittpe-solution/pictures-of-green-frogs-7.pdf b/dewittpe-solution/pictures-of-green-frogs-7.pdf new file mode 100644 index 0000000..d7fddda Binary files /dev/null and b/dewittpe-solution/pictures-of-green-frogs-7.pdf differ