3/26/2020

The Setup

The cake eating problem is the simplest economic example of a finite dimensional dynamic programming environment. The problem can be described by the following:

  • An agent lives through \(T\) periods and has preferences given the consumption of cake
  • In each period \(t \in T\) the utility received by consuming \(c_t\) units of cake is represented by a function \(u(c_t) = ln(c_t + \alpha)\) where \(u(c_t)\) is monotone and convex
  • Utility in future periods is discounted by a factor \(\beta \in (0,1)\) and cake in the first period is a non-zero endowment \(x_0 > 0\)
  • The agent future consumption of cake \(c_{t+1}\) depends on what they previously chose to invest in the future \(x_t\)

Dynamic Programming in Discrete Time

Dynamic Programming - an optimization problem in which agents make sequential decisions over multiple periods of time; often these problems are solved via methods of recursion depending on the complexity of the decision.

Dynamic programming is a necessary step in calculating an optimization problem defined on a multidimensional space. In the context of the cake eating problem our agent consumes cake over multiple periods of time; however each periodic decision is constrained to the cake saved in the previous decision.

The Cake Eating Optimization Problem

The value function of a discrete time cake eating problem \(\forall t \in \mathbb{N}\) is defined by the following expression: \[ \begin{equation} \begin{aligned} \max_{c_t,x_{t+1}} \quad & \sum_{t=1}^{T} \beta^{(t-1)} ln(c_t+\alpha) \\ {\text{s.t.}} \quad & x_{t+1}=x_t-c_t \\ & x_{t+1} \geq 0 \\ & c_t \geq 0 \end{aligned} \end{equation} \]

The Script

adjust = function(min_x, max_x, initial) {
  adj_x = c(initial,(max_x+min_x)/2)
  for (t in 3:T) {
    adj_x[t] = (1+B)*adj_x[t-1] - B*adj_x[t-2]
  }
  return(adj_x)
}

max_x = x[1]
min_x = 0
x_i = adjust(min_x, max_x, x[1])

while (TRUE) {
  if (x_i[T] > 0.00001) {max_x = x_i[2]}
  else if (x_i[T] < -0.00001) {min_x = x_i[2]}
  else {break}
  x_i = adjust(min_x, max_x, x[1])
}

c = c()
for (i in 1:T) {
  if (i < T) {c[i] = x_i[i] - x_i[i+1] - a}
  else {c[i] = x_i[i] - a}
}

The Solution

Suppose our agent is faces with a discount factor \(\beta = .95\), an initial endowment \(x_0 = 20\), and a natural state of utility \(\alpha = 0\) over \(T = 40\) periods. The following dataframe illustrates the optimized investments and consumption in this particular scenario:

##    time investment consumption
## 1     1    20.0000      1.1564
## 2     2    18.8436      1.0986
## 3     3    17.7449      1.0437
## 4     4    16.7013      0.9915
## 5     5    15.7098      0.9419
## 6     6    14.7678      0.8948
## 7     7    13.8730      0.8501
## 8     8    13.0229      0.8076
## 9     9    12.2153      0.7672
## 10   10    11.4481      0.7288
##    time investment consumption
## 31   31     1.8356      0.2482
## 32   32     1.5873      0.2358
## 33   33     1.3515      0.2240
## 34   34     1.1275      0.2128
## 35   35     0.9147      0.2022
## 36   36     0.7125      0.1921
## 37   37     0.5205      0.1825
## 38   38     0.3380      0.1733
## 39   39     0.1647      0.1647
## 40   40     0.0000      0.0000

Cake Remaining at each period

## Warning: Use of `df$time` is discouraged. Use `time` instead.
## Warning: Use of `df$investment` is discouraged. Use `investment` instead.
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Cake Consumed Each Period

## Warning: Use of `df$time` is discouraged. Use `time` instead.
## Warning: Use of `df$consumption` is discouraged. Use `consumption` instead.
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Finite Dimensional Visualization

Breakdown of Previous Image

Looking at the visualization, we see that in the first couple of iterations the consumer drastically over-consumes and is left with a severe ‘debt’ of cake. As the cake consumption is iterated over and over again, it briefly overcorrects around iteration 5 and leaves too much cake by the end of the 40 periods. As iterations continue, the leftovers or overconsumption values deviate less and less from the end goal of zero until finally reaching a point at iteration 23 where the consumer eats the perfect amount in the first period.