{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Foundations of Computational Economics #27\n", "\n", "by Fedor Iskhakov, ANU\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "## Dynamic programming in discrete world\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "\n", "\n", "[https://youtu.be/kpNGDQnDpmU](https://youtu.be/kpNGDQnDpmU)\n", "\n", "Description: Backwards induction. Tiling problem. Deal or no deal game. Bellman optimality principle. Inventory dynamics model." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### What is dynamic programming?\n", "\n", "**“DP is recursive method for solving sequential decision problems”**\n", "\n", "📖 Rust 2006, *New Palgrave Dictionary of Economics*\n", "\n", "In computer science the meaning of the term is broader:\n", "**DP is a general algorithm design technique for solving problems with\n", "overlapping sub-problems.**\n", "\n", "Generally allows solving in polynomial time $ O(n^k) $ problems that would\n", "otherwise take exponential time $ O(a^n) $" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Tiling with dominoes example\n", "\n", "Given a $ 3 \\times n $ board, find **the number of ways** to\n", "fill it with $ 2 \\times 1 $ dominoes." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Examples of tiling\n", "\n", "These are three possible ways to fill up $ 3 \\times 2 $ board\n", "\n", "\n", "\n", "This is one possible way to tile $ 3 \\times 8 $ board\n", "\n", "\n", "\n", "The problem is to compute the number of possible tilings for any $ 3 \\times n $ board." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Breaking the big problem into subproblems\n", "\n", "Observe that at any possible stage of filling up a $ 3 \\times n $ board we may have\n", "the following configurations\n", "\n", "\n", "\n", "And it is impossible to have the following configurations\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Defining the recursion\n", "\n", "The case of $ A_n $:\n", "\n", "\n", "\n", "The case of $ B_n $:\n", "\n", "\n", "\n", "The case of $ C_n $ is identical to $ B_n $, i.e. $ C_n = B_n $" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Recursive solution\n", "\n", "Therefore for any $ n $ we have\n", "\n", "$$\n", "\\begin{eqnarray*}\n", "A_n &=& A_{n-2} + 2 B_{n-1} \\\\\n", "B_n &=& A_{n-1} + B_{n-2}\n", "\\end{eqnarray*}\n", "$$\n", "\n", "The answer to the whole problem is given by $ A_n $\n", "\n", "1. Inductive computation of the two sequences. \n", "1. Can be improved by *memoization* (optimization technique based on caching previous calls to the function) " ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "def WaysTileDominoes(n):\n", " '''Compute the number of ways to tile 3 x n area by 2x1 tiles'''\n", " A, B = [0] * (n + 1),[0] * (n + 1)\n", " A[0] = 1 # one way to tile 3x0\n", " A[1] = 0 # no way to tile 3x1\n", " B[0] = 0 # no way to tile 3x0 without a corner\n", " B[1] = 1 # one way to tile 3x1 without a corner\n", " for i in range(2, n+1): # loop over 2,3,..,n\n", " A[i] = A[i-2] + 2 * B[i-1]\n", " B[i] = A[i-1] + B[i-2]\n", " return A[n]" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "There are 0 ways to tile the 3 by 1 board\n", "There are 3 ways to tile the 3 by 2 board\n", "There are 0 ways to tile the 3 by 3 board\n", "There are 11 ways to tile the 3 by 4 board\n", "There are 0 ways to tile the 3 by 5 board\n", "There are 41 ways to tile the 3 by 6 board\n", "There are 0 ways to tile the 3 by 7 board\n", "There are 153 ways to tile the 3 by 8 board\n", "There are 0 ways to tile the 3 by 9 board\n", "There are 571 ways to tile the 3 by 10 board\n", "There are 0 ways to tile the 3 by 11 board\n", "There are 2131 ways to tile the 3 by 12 board\n", "There are 0 ways to tile the 3 by 13 board\n", "There are 7953 ways to tile the 3 by 14 board\n", "There are 0 ways to tile the 3 by 15 board\n", "There are 29681 ways to tile the 3 by 16 board\n", "There are 0 ways to tile the 3 by 17 board\n", "There are 110771 ways to tile the 3 by 18 board\n", "There are 0 ways to tile the 3 by 19 board\n" ] } ], "source": [ "for n in range(1,20):\n", " print('There are',WaysTileDominoes(n),'ways to tile the 3 by',n,'board')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Deal or no deal example\n", "\n", "Consider a version of [Deal or no deal](https://en.wikipedia.org/wiki/Deal_or_No_Deal) TV show game\n", "\n", "- the player is presented with $ n $ boxes with prizes hidden inside \n", "- all prizes $ x_1,\\dots,x_n $ are known to the player, but not where they are \n", "- at each round the player may choose a box at random to be removed from the game (and loose the opportunity to get the prize within) \n", "- otherwise, the player may choose to stop the game and walk away with the prize chosen randomly from remaining boxes \n", "\n", "\n", "What is the optimal strategy to maximize the (expected) reward?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Need assumption about the reward evaluation\n", "\n", "- assume that the player is maximizing the expected reward \n", "- ok, but then for each set of remaining prizes $ (x,y,z) $ the expected reward is \n", "\n", "\n", "$$\n", "\\frac{x+y+z}{3} \\text{ (stopping the game)}\n", "$$\n", "\n", "$$\n", "\\frac{1}{3}\\cdot\\frac{x+y}{2} + \\frac{1}{3}\\cdot\\frac{x+z}{2} + \\frac{1}{3}\\cdot\\frac{y+z}{2} \\text{ (removing random box)}\n", "$$\n", "\n", "- at each point of the game the player will be indifferent between stopping or continuing the game \n", "- thus, optimal strategy is to stop at the first round and take random reward! " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Loss aversion utility\n", "\n", "- assume that the player has loss aversion utility of the form \n", "\n", "\n", "$$\n", "U(\\text{reward},\\text{reference}) = \\text{reward} - \\theta \\cdot \\mathbb{1}\\{ \\text{reward}< \\text{reference}\\}\n", "$$\n", "\n", "- if award is below the reference level, there is a cut in utility \n", "- assume further that the reference level is *updated* endogenously during the game: \n", "- at each round equal to the foregone option of stopping the game in the previous round " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### How to solve for the optimal strategy in this game?\n", "\n", "1. What is the maximum number of rounds in the game? \n", "1. What does the optimal choice depend on in each round? \n", "1. What is the *complete* strategy in the game? " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "- for a given round let $ B $ denote the set of remaining $ n $ boxes/prizes \n", "- denote $ r $ the reference level in the utility function $ U(\\cdot,r) $ \n", "\n", "\n", "Let $ V(B,r) $ be the maximum expected reward, i.e. assuming optimal strategy is played from this round on\n", "\n", "$$\n", "V(B,r) = \\max\\Big[ \\underbrace{\\tfrac{1}{n} \\sum_{b \\in B} U(b,r)}_{\\text{stop}} ;\n", " \\underbrace{\\sum_{b \\in B} \\tfrac{1}{n} V\\big(B \\backslash b, \\tfrac{1}{n} \\sum_{d \\in B} U(d,r)\\big) }_{\\text{continue}}\n", " \\Big]\n", "$$\n", "\n", "$$\n", "V(B,r) = \\max\\big[ R_r ; \\sum_{b \\in B} \\tfrac{1}{n} V(B \\backslash b, R_r) \\big]\n", "$$\n", "\n", "- $ R_r = \\tfrac{1}{n} \\sum_{b \\in B} U(b,r) $ is current round expected reward \n", "- $ B \\backslash b $ is the next round set of $ n-1 $ boxes/prizes " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "def expected_reward(boxes,ref=None,loss_aversion_param=.1,verbose=True):\n", " '''Compute the expected reward from the game with given boxed prizes and the reference level'''\n", " n = len(boxes) # number of boxed remaining\n", " ref = sum(boxes)/n if ref is None else ref # default reference level\n", " # reward if stopping\n", " current = [b - loss_aversion_param*(b1:\n", " print(' reward if stop={:<6.3f} if continue={:<6.3f}'.format(current,next),end='') # rewards for two decisions\n", " print(' >> {}!'.format('stop' if current >= next else 'continue')) # best decision\n", " else:\n", " print(' reward={:<6.3f}'.format(current)) # reward in case of last box left\n", " return max(current,next) # reward from the optimal choice" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Initial prizes = [1, 2, 7]\n", "[7] ref=4.450 reward=7.000 \n", "[2] ref=4.450 reward=1.900 \n", "[2][7] ref=3.267 reward if stop=4.450 if continue=4.450 >> stop!\n", "[7] ref=3.950 reward=7.000 \n", "[1] ref=3.950 reward=0.900 \n", "[1][7] ref=3.267 reward if stop=3.950 if continue=3.950 >> stop!\n", "[2] ref=1.400 reward=2.000 \n", "[1] ref=1.400 reward=0.900 \n", "[1][2] ref=3.267 reward if stop=1.400 if continue=1.450 >> continue!\n", "[1][2][7] ref=3.333 reward if stop=3.267 if continue=3.283 >> continue!\n" ] } ], "source": [ "import math\n", "boxes = [int(math.exp(b)) for b in range(3)] # uneven prizes\n", "print('Initial prizes = ',boxes)\n", "expected_reward(boxes,loss_aversion_param=0.1);" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Bellman’s Principle of Optimality\n", "\n", "“An optimal policy has a property that whatever the initial state and\n", "initial decision are, the remaining decisions must constitute an\n", "optimal policy with regard to the state resulting from the first\n", "decision.”\n", "\n", "📖 Bellman, 1957 “Dynamic Programming”" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Breaking the problem into sequence of small problems\n", "\n", "- Thus, the sequential decision problem is broken into *initial decision*\n", " problem and the *future decisions* problem \n", "- The solution can be computed through **backward induction**,\n", " i.e. solving a sequential decision problem from the later periods \n", "- Embodiment of the recursive way of modeling sequential decisions is\n", " **Bellman equation** " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Bellman equation\n", "\n", "$$\n", "V(\\text{state}) = \\max_{\\text{decisions}} \\big[ U(\\text{state},\\text{decision}) + \\beta \\mathbb{E}\\big\\{ V(\\text{next state}) \\big| \\text{state},\\text{decision} \\big\\} \\big]\n", "$$\n", "\n", "- $ V(\\text{state}) $ is **value function** = maximum attainable (discounted) expected reward/utility/payoff \n", "- $ U(\\text{state},\\text{decision}) $ is per-period/flow/instantaneous reward/utility/payoff \n", "- (*next state*) is the *stochastic* next period state resulting from current state and decision \n", "- expectation $ \\mathbb{E}\\{\\cdot\\} $ is taken over the distribution of the next period state conditional on current state and decision \n", "- $ \\beta $ is a discount factor to measure future rewards in terms of current ones \n", "\n", "\n", "The optimal choices are revealed along the solution of the Bellman equation as decisions which solve the maximization problem in the right hand side!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Bellman equation in deterministic models\n", "\n", "In deterministic case, expectation is not necessary:\n", "\n", "$$\n", "V(\\text{state}) = \\max_{\\text{decisions}} \\big[ U(\\text{state},\\text{decision}) + \\beta \\cdot V(\\text{next state}) \\big]\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Bellman equation in models with finite horizon\n", "\n", "Additional condition at the final period $ t=T $, usually\n", "\n", "$$\n", "V(\\text{state}) = \\max_{\\text{decisions}} \\big[ U(\\text{state},\\text{decision}) \\big] \\text{ at terminal period } T\n", "$$\n", "\n", "In other words, as if $ V(\\text{at } T +1 ) = \\mathbb{0} $" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Power of dynamic programming\n", "\n", "DP is a the main tool in analyzing modern micro and macto economic models\n", "\n", "DP is powerful due to its **flexibility and breadth**\n", "\n", "DP provides a framework to study decision making over time and under uncertainty\n", "and can accommodate learning, strategic interactions between agents (game theory)\n", "and market interactions (equilibrium theory)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Dynamic programming in economics\n", "\n", "Many important problems and economic models are analyzed and solved\n", "using dynamic programming:\n", "\n", "- Dynamic models of labor supply \n", "- Job search \n", "- Human capital accumulation \n", "- Health process, insurance and long term care \n", "- Consumption/savings choices \n", "- Durable consumption \n", "- Growth models \n", "- Heterogeneous agents models \n", "- Overlapping generation models " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Origin of the term Dynamic Programming\n", "\n", "📖 Bellman’s autobiography “The Eye of the Hurricane”\n", "\n", "The 1950’s were not good years for mathematical research. We had a very interesting\n", "gentleman in Washington named Wilson. He was Secretary of Defence, and\n", "he actually had a pathological fear and hatred of the word “research”.\n", "\n", "I’m not using the term lightly; I’m using it precisely. His face would\n", "suffuse, he would turn red, and he would get violent if people used the\n", "term, research, in his presence. You can imagine how he felt, then,\n", "about the term, mathematical." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Hence, I felt I had to do something to shield Wilson and the Air Force\n", "from the fact that I was really doing mathematics inside the RAND Corporation.\n", "\n", "What title, what name, could I choose?\n", "\n", "In the first place, I was interested in planning, in\n", "decision-making, in thinking. But planning, is not a good word for\n", "various reasons. I decided therefore to use the word, “programming”.\n", "\n", "I wanted to get across the idea that this was dynamic, this was\n", "multistage, this was time-varying." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "I thought, let’s kill two birds with one stone. Let’s take a word which has an absolutely precise\n", "meaning, namely dynamic, in the classical physical sense.\n", "\n", "It also has a very interesting property as an adjective, and that is it’s impossible\n", "to use the word, dynamic, in the pejorative sense.\n", "\n", "Thus, I thought dynamic programming was a good name. It was something not even a\n", "Congressman could object to. So I used it as an umbrella for my activities." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Inventory dynamics problem\n", "\n", "Consider the following problem in discrete time and finite horizon $ t=0,\\dots,T $\n", "\n", "The notation is:\n", "\n", "- $ x_t\\ge 0 $ is inventory at period $ t $ measured in **discrete units** \n", "- $ d_t\\ge 0 $ is *potentially stochastic* demand at period $ t $ \n", "- $ q_t\\ge 0 $ is the order of new inventory \n", "- $ p $ is the profit per one unit of (supplied) good \n", "- $ c $ is the fixed cost of ordering any amount of new inventory \n", "- $ r $ is the cost of storing one unit of good " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "The sales in period $ t $ are given by $ s_t = \\min\\{x_t,d_t\\} $.\n", "\n", "Inventory to be stored till next period is given by $ k_t = \\max\\{x_t-d_t,0\\} + q_t = x_{t+1} $.\n", "\n", "The profit in period $ t $ is given by\n", "\n", "$$\n", "\\begin{eqnarray}\n", "\\pi_t & = & p \\cdot \\text{sales}_t - r \\cdot x_{t+1} - c \\cdot (\\text{order made in period }t) \\\\\n", "& = & s_t p - k_t r - c \\mathbb{1}\\{q_t>0\\}\n", "\\end{eqnarray}\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Assuming all $ q_t \\ge 0 $, let $ \\sigma = \\{q_t\\}_{t=1,\\dots,T} $ denote a feasible inventory policy.\n", "\n", "If $ d_t $ is stochastic the policy becomes a function of the period $ t $ inventory $ x_t $.\n", "\n", "The expected profit maximizing problem is given by\n", "\n", "$$\n", "{\\max}_{\\sigma} \\mathbb{E}\\Big[ \\sum_{t=0}^{T} \\beta^t \\pi_t \\Big],\n", "$$\n", "\n", "where $ \\beta $ is discount factor." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Bellman equation for the problem\n", "\n", "Decisions: $ q_t $, how much new inventory to order\n", "\n", "What is important for the inventory decision at time period $ t $?\n", "- instanteneous utility (profit) contains $ x_t $ and $ d_t $\n", "- timing: (beginning of period) - current inventory - demand - (choice) order - stored inventory - (end of period)\n", "\n", "So, both $ x_t $ and $ d_t $ are taken into account for the new order to be made, forming the state space." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "$$\n", "\\begin{eqnarray}\n", "V(x_t,d_t) &=& \\max_{q_t \\ge 0} \\Big\\{ \\pi_t + \\beta \\mathbb{E}\\Big[ V\\big(x_{t+1} , d_{t+1} \\big) \\Big| x_t,d_t,q_t \\Big] \\Big\\} \\\\\n", "&=& \\max_{q_t \\ge 0} \\Big\\{ s_t p - k_t r - c \\mathbb{1}\\{q_t>0\\}\n", "+ \\beta \\mathbb{E}\\Big[ V\\big( k_t, d_{t+1} \\big) \\Big] \\Big\\}\n", "\\end{eqnarray}\n", "$$\n", "\n", "$$\n", "\\begin{eqnarray}\n", "s_t &=& \\min\\{x_t,d_t\\} \\\\\n", "k_t &=& \\max\\{x_t-d_t,0\\} + q_t\n", "\\end{eqnarray}\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "The expectation in the Bellman equation is taken over the distribution of the next period demand $ d_{t+1} $, which we assume is independent of any other variables and across time (idiosyncratic), thus the conditioning on $ (x_t,d_t,s_t) $ can be meaningfully dropped.\n", "\n", "Expectation can be written as an integral over the distribution of demand $ F(d) $, and since inventory is discrete it’s natural to assume demand is as well.\n", "\n", "The integral then transforms into a sum over the possible value of demand, weighted by their probabilities $ pr(d) $\n", "\n", "$$\n", "\\begin{eqnarray}\n", "V(x_t,d_t)\n", "&=& \\max_{q_t \\ge 0} \\Big\\{ s_t p - k_t r - c \\mathbb{1}\\{q_t>0\\}\n", "+ \\beta \\int V\\big( k_t, d \\big) \\partial F(d) \\Big\\} \\\\\n", "&=& \\max_{q_t \\ge 0} \\Big\\{ s_t p - k_t r - c \\mathbb{1}\\{q_t>0\\}\n", "+ \\beta \\sum_d V\\big( k_t, d \\big) pr(d) \\Big\\}\n", "\\end{eqnarray}\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Today: deterministic case\n", "\n", "Let $ d $ be fixed and constant across time. How does the Bellman equation change?\n", "\n", "In the deterministic case with fixed $ d $, it can be simply dropped from the state space, and the Bellman equation can be simplified to\n", "\n", "$$\n", "\\begin{multline}\n", "V(x_t) = \\max_{q_t \\ge 0} \\big\\{ p \\min\\{x_t,d\\} - r \\big[ \\max\\{x_t-d,0\\} + q_t \\big] \\\\ - c \\mathbb{1}\\{q_t>0\\}\n", "+ \\beta V\\big( \\max\\{x_t-d,0\\} + q_t \\big) \\big\\}\n", "\\end{multline}\n", "$$" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "plt.rcParams['figure.figsize'] = [12, 8]\n", "\n", "class inventory_model:\n", " '''Small class to hold model fundamentals and its solution'''\n", "\n", " def __init__(self,label='noname',\n", " max_inventory=10, # upper bound on the state space\n", " c = 3.2, # fixed cost of order\n", " p = 2.5, # profit per unit of good\n", " r = 0.5, # storage cost per unit of good\n", " β = 0.95, # discount factor\n", " demand = 4 # fixed demand\n", " ):\n", " '''Create model with default parameters'''\n", " self.label=label # label for the model instance\n", " self.c, self.p, self.r, self.β = c, p, r, β\n", " self.demand = demand\n", " # created dependent attributes (it would be better to have them updated when underlying parameters change)\n", " self.n = max_inventory+1 # number of inventory levels\n", " self.upper = max_inventory # upper boundary on inventory\n", " self.x = np.arange(self.n) # all possible values of inventory (state space)\n", "\n", " def __repr__(self):\n", " '''String representation of the model'''\n", " return 'Inventory model labeled \"{}\"\\nParamters (c,p,r,β) = ({},{},{},{})\\nDemand={}\\nUpper bound on inventory {}' \\\n", " .format (self.label,self.c,self.p,self.r,self.β,self.demand,self.upper)\n", "\n", " def sales(self,x,d):\n", " '''Sales in given period'''\n", " return np.minimum(x,d)\n", "\n", " def next_x(self,x,d,q):\n", " '''Inventory to be stored, becomes next period state'''\n", " return x - self.sales(x,d) + q\n", "\n", " def profit(self,x,d,q):\n", " '''Profit in given period'''\n", " return self.p * self.sales(x,d) - self.r * self.next_x(x,d,q) - self.c * (q>0)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Inventory model labeled \"test\"\n", "Paramters (c,p,r,β) = (3.2,2.5,0.5,0.95)\n", "Demand=4\n", "Upper bound on inventory 10\n", "Current profits with zero orders\n", " [ 0. 2.5 5. 7.5 10. 9.5 9. 8.5 8. 7.5 7. ]\n" ] } ], "source": [ "model=inventory_model(label='test')\n", "print(model)\n", "\n", "q=np.zeros(model.n)\n", "print('Current profits with zero orders\\n',model.profit(model.x,model.demand,q))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Current inventory\n", " [ 0 1 2 3 4 5 6 7 8 9 10]\n", "Current sales\n", " [0 1 2 3 4 4 4 4 4 4 4]\n", "Current orders\n", " [[ 0]\n", " [ 1]\n", " [ 2]\n", " [ 3]\n", " [ 4]\n", " [ 5]\n", " [ 6]\n", " [ 7]\n", " [ 8]\n", " [ 9]\n", " [10]]\n", "Next period inventory\n", " [[ 0 0 0 0 0 1 2 3 4 5 6]\n", " [ 1 1 1 1 1 2 3 4 5 6 7]\n", " [ 2 2 2 2 2 3 4 5 6 7 8]\n", " [ 3 3 3 3 3 4 5 6 7 8 9]\n", " [ 4 4 4 4 4 5 6 7 8 9 10]\n", " [ 5 5 5 5 5 6 7 8 9 10 11]\n", " [ 6 6 6 6 6 7 8 9 10 11 12]\n", " [ 7 7 7 7 7 8 9 10 11 12 13]\n", " [ 8 8 8 8 8 9 10 11 12 13 14]\n", " [ 9 9 9 9 9 10 11 12 13 14 15]\n", " [10 10 10 10 10 11 12 13 14 15 16]]\n", "Current profits\n", " [[ 0. 2.5 5. 7.5 10. 9.5 9. 8.5 8. 7.5 7. ]\n", " [-3.7 -1.2 1.3 3.8 6.3 5.8 5.3 4.8 4.3 3.8 3.3]\n", " [-4.2 -1.7 0.8 3.3 5.8 5.3 4.8 4.3 3.8 3.3 2.8]\n", " [-4.7 -2.2 0.3 2.8 5.3 4.8 4.3 3.8 3.3 2.8 2.3]\n", " [-5.2 -2.7 -0.2 2.3 4.8 4.3 3.8 3.3 2.8 2.3 1.8]\n", " [-5.7 -3.2 -0.7 1.8 4.3 3.8 3.3 2.8 2.3 1.8 1.3]\n", " [-6.2 -3.7 -1.2 1.3 3.8 3.3 2.8 2.3 1.8 1.3 0.8]\n", " [-6.7 -4.2 -1.7 0.8 3.3 2.8 2.3 1.8 1.3 0.8 0.3]\n", " [-7.2 -4.7 -2.2 0.3 2.8 2.3 1.8 1.3 0.8 0.3 -0.2]\n", " [-7.7 -5.2 -2.7 -0.2 2.3 1.8 1.3 0.8 0.3 -0.2 -0.7]\n", " [-8.2 -5.7 -3.2 -0.7 1.8 1.3 0.8 0.3 -0.2 -0.7 -1.2]]\n" ] } ], "source": [ "# illustration of broadcasting in the inventory model\n", "q=model.x[:,np.newaxis] # column vector\n", "print('Current inventory\\n',model.x)\n", "print('Current sales\\n',model.sales(model.x,model.demand))\n", "print('Current orders\\n',q)\n", "print('Next period inventory\\n',model.next_x(model.x,model.demand,q))\n", "print('Current profits\\n',model.profit(model.x,model.demand,q))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "def bellman(m,v0):\n", " '''Bellman equation for inventory model\n", " Inputs: model object\n", " next period value function\n", " '''\n", " # create the grid of choices (same as x), column-vector\n", " q = m.x[:,np.newaxis]\n", " # compute current period profit (relying on numpy broadcasting to get the matrix with choices in rows)\n", " p = m.profit(m.x,m.demand,q)\n", " # indexes for next period value with extrapolation using last value\n", " i = np.minimum(m.next_x(m.x,m.demand,q),m.upper)\n", " # compute the Bellman maximand\n", " vm = p + m.β*v0[i]\n", " # find max and argmax\n", " v1 = np.amax(vm,axis=0) # maximum in every column\n", " q1 = np.argmax(vm,axis=0) # arg-maximum in every column = order volume\n", " return v1, q1" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Value =\n", "[ 0. 2.5 5. 7.5 10. 9.5 9. 8.5 8. 7.5 7. ]\n", "Policy =\n", "[0 0 0 0 0 0 0 0 0 0 0]\n", "\n", "Value =\n", "[ 4.3 6.8 9.3 11.8 14.3 14.3 14.3 15.625 17.5 16.525\n", " 15.55 ]\n", "Policy =\n", "[4 4 4 4 4 3 2 0 0 0 0]\n", "\n", "Value =\n", "[ 9.425 11.925 14.425 16.925 19.425 19.425 19.425 19.71 21.585 21.085\n", " 20.585]\n", "Policy =\n", "[8 8 8 8 8 7 6 0 0 0 0]\n", "\n" ] } ], "source": [ "v = np.zeros(model.n)\n", "for i in range(3):\n", " v,q = bellman(model,v)\n", " print('Value =',v,'Policy =',q,sep='\\n',end='\\n\\n')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Backwards induction algorithm\n", "\n", "Solver for the finite horizon dynamic programming problems\n", "\n", "1. Start at $ t=T $ \n", "1. Solve Bellman equation at $ t $, record optimal choice \n", "1. Decrease $ t $ unless $ t=1 $, and return to previous step. \n", "\n", "\n", "As result, for all $ t=1,\\dots,T $ have found the optimal choice (as a function of state)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "def solver_backwards_induction(m,T=10,verbose=False):\n", " '''Backwards induction solver for the finite horizon case'''\n", " # solution is time dependent\n", " m.value = np.zeros((m.n,T))\n", " m.policy = np.zeros((m.n,T))\n", " # main DP loop (from T to 1)\n", " for t in range(T,0,-1):\n", " if verbose:\n", " print('Time period %d\\n'%t)\n", " j = t-1 # index of value and policy functions for period t\n", " if t==T:\n", " # terminal period: ordering zero is optimal\n", " m.value[:,j] = m.profit(m.x,m.demand,np.zeros(m.n))\n", " m.policy[:,j] = np.zeros(m.n)\n", " else:\n", " # all other periods\n", " m.value[:,j], m.policy[:,j] = bellman(m,m.value[:,j+1]) # next period to Bellman\n", " if verbose:\n", " print(m.value,'\\n')\n", " # return model with updated value and policy functions\n", " return m" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Time period 5\n", "\n", "[[ 0. 0. 0. 0. 0. ]\n", " [ 0. 0. 0. 0. 2.5]\n", " [ 0. 0. 0. 0. 5. ]\n", " [ 0. 0. 0. 0. 7.5]\n", " [ 0. 0. 0. 0. 10. ]\n", " [ 0. 0. 0. 0. 9.5]\n", " [ 0. 0. 0. 0. 9. ]\n", " [ 0. 0. 0. 0. 8.5]\n", " [ 0. 0. 0. 0. 8. ]\n", " [ 0. 0. 0. 0. 7.5]\n", " [ 0. 0. 0. 0. 7. ]] \n", "\n", "Time period 4\n", "\n", "[[ 0. 0. 0. 4.3 0. ]\n", " [ 0. 0. 0. 6.8 2.5 ]\n", " [ 0. 0. 0. 9.3 5. ]\n", " [ 0. 0. 0. 11.8 7.5 ]\n", " [ 0. 0. 0. 14.3 10. ]\n", " [ 0. 0. 0. 14.3 9.5 ]\n", " [ 0. 0. 0. 14.3 9. ]\n", " [ 0. 0. 0. 15.625 8.5 ]\n", " [ 0. 0. 0. 17.5 8. ]\n", " [ 0. 0. 0. 16.525 7.5 ]\n", " [ 0. 0. 0. 15.55 7. ]] \n", "\n", "Time period 3\n", "\n", "[[ 0. 0. 9.425 4.3 0. ]\n", " [ 0. 0. 11.925 6.8 2.5 ]\n", " [ 0. 0. 14.425 9.3 5. ]\n", " [ 0. 0. 16.925 11.8 7.5 ]\n", " [ 0. 0. 19.425 14.3 10. ]\n", " [ 0. 0. 19.425 14.3 9.5 ]\n", " [ 0. 0. 19.425 14.3 9. ]\n", " [ 0. 0. 19.71 15.625 8.5 ]\n", " [ 0. 0. 21.585 17.5 8. ]\n", " [ 0. 0. 21.085 16.525 7.5 ]\n", " [ 0. 0. 20.585 15.55 7. ]] \n", "\n", "Time period 2\n", "\n", "[[ 0. 13.30575 9.425 4.3 0. ]\n", " [ 0. 15.80575 11.925 6.8 2.5 ]\n", " [ 0. 18.30575 14.425 9.3 5. ]\n", " [ 0. 20.80575 16.925 11.8 7.5 ]\n", " [ 0. 23.30575 19.425 14.3 10. ]\n", " [ 0. 23.30575 19.425 14.3 9.5 ]\n", " [ 0. 23.30575 19.425 14.3 9. ]\n", " [ 0. 24.57875 19.71 15.625 8.5 ]\n", " [ 0. 26.45375 21.585 17.5 8. ]\n", " [ 0. 25.95375 21.085 16.525 7.5 ]\n", " [ 0. 25.45375 20.585 15.55 7. ]] \n", "\n", "Time period 1\n", "\n", "[[17.9310625 13.30575 9.425 4.3 0. ]\n", " [20.4310625 15.80575 11.925 6.8 2.5 ]\n", " [22.9310625 18.30575 14.425 9.3 5. ]\n", " [25.4310625 20.80575 16.925 11.8 7.5 ]\n", " [27.9310625 23.30575 19.425 14.3 10. ]\n", " [27.9310625 23.30575 19.425 14.3 9.5 ]\n", " [27.9310625 23.30575 19.425 14.3 9. ]\n", " [28.2654625 24.57875 19.71 15.625 8.5 ]\n", " [30.1404625 26.45375 21.585 17.5 8. ]\n", " [29.6404625 25.95375 21.085 16.525 7.5 ]\n", " [29.1404625 25.45375 20.585 15.55 7. ]] \n", "\n", "Optimal policy:\n", " [[8. 8. 8. 4. 0.]\n", " [8. 8. 8. 4. 0.]\n", " [8. 8. 8. 4. 0.]\n", " [8. 8. 8. 4. 0.]\n", " [8. 8. 8. 4. 0.]\n", " [7. 7. 7. 3. 0.]\n", " [6. 6. 6. 2. 0.]\n", " [0. 0. 0. 0. 0.]\n", " [0. 0. 0. 0. 0.]\n", " [0. 0. 0. 0. 0.]\n", " [0. 0. 0. 0. 0.]]\n" ] } ], "source": [ "model = inventory_model(label='illustration')\n", "model=solver_backwards_induction(model,T=5,verbose=True)\n", "print('Optimal policy:\\n',model.policy)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def plot_solution(model):\n", " plt.step(model.x,model.value)\n", " plt.legend([f'{i+1}' for i in range(model.value.shape[1])])\n", " plt.title('Value function')\n", " plt.show()\n", " plt.step(model.x,model.policy)\n", " plt.legend([f'{i+1}' for i in range(model.policy.shape[1])])\n", " plt.title('Policy function (optimal order sizes)')\n", " plt.show()\n", "\n", "plot_solution(model)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "image/png": "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5vjjj3/Mx/fZZ5+85S1vyX777Zcddtghxx57bI499tiB1jCRzi8AACPzox/9KJ/61Kfyve99LzfffHPuvffeXHzxxUNbT+cXAIAkedwO7bB84QtfyP7775899tgjSfLyl788//RP/5STTz55KOvp/AIAMDL77bdf/vmf/zn33XdfWmu54oorMmfOnKGtJ/wCADAyRxxxRF75ylfmsMMOy7Of/ez89Kc/zemnnz609Wx7AABgpM4+++ycffbZm2UtnV8AADpD5xcYqFnjLUuPOWijx686YEbOOP+qIVYEAP9F+AUGZtUBM5Ks2ejxs8bbpMYDwFQJv8DATLaDO5kOMQAMgj2/AAB0hvALAEBnCL8AAIzUeeedl7lz5+bggw/OueeeO9S1hF8AAEbmuuuuy1/91V/lmmuuyde//vV85jOfyY033ji09YRfAABG5vrrr8+RRx6ZHXfcMdOmTcvzn//8XHrppUNbz9UeAABIknzrW/8zd99z/UDn3GXnOXnmM//gMR+fO3du3v72t+f222/PDjvskKVLl2b+/PkDrWEi4RcAgJGZM2dOzjzzzCxcuDA777xzDj300EybNryIKvwCAJAkj9uhHabTTjstp512WpLkbW97W8bGxoa2lvALAMBI3XbbbZk5c2a+//3v5xOf+ESuvvrqoa0l/AIAMFKveMUrcvvtt2fbbbfNX/zFX+SpT33q0NYSfgEAGKkvf/nLm20tlzoDAKAzhF8AADpD+AUAoDOEXwAAOkP4BQCgM4RfAAA6Q/gFAGCkTj311MycOTNz58595Ngdd9yRhQsX5hnPeEYWLlyYH/3oRwNZS/gFAGCkFi9enGXLlj3q2DnnnJMXvvCFufHGG/PCF74w55xzzkDWEn4BABipBQsWZPr06Y869qlPfSqnnHJKkuSUU07JJz/5yYGs5RPeAABIkvzBjatz3T0/Huicc3feIf/zGWOTft6tt96avfbaK0my11575bbbbhtIPRvs/FbVB6rqtqq6bsKx6VV1eVXd2P97eB/ADAAAA7Ixnd8PJXl/kg9POHZWkitaa+dU1Vn9+2cOvjwAADaXTenQDsusWbNyyy23ZK+99sott9ySmTNnDmTeDYbf1tpVVTV7ncMvS3J0//ZFSa6M8AtsglnjLUuPOWijx686YEbOOP+qIVYEwJbgpS99aS666KKcddZZueiii/Kyl71sIPNu6p7fWa21W5KktXZLVT1mFK+q05OcniT77bffJi4HbI1WHTAjyZqNHj9rvE1qPABPDIsWLcqVV16ZNWvWZGxsLGeffXbOOuusvOpVr8qFF16Y/fbbLx/72McGstbQ3/DWWrsgyQVJMn/+/Dbs9YAnjsl2cCfTIQbgiWPJkiXrPX7FFVcMfK1NvdTZrVW1V5L0/x7M2+8AAGCINjX8XpbklP7tU5J8ajDlAADA8GzMpc6WJLk6ybOqanVVnZbknCQLq+rGJAv79wEAYIu2MVd7WPQYD71wwLUAAMBQ+XhjAAA6Q/gFAKAzhF8AAEbq1FNPzcyZMzN37txHjn3sYx/LwQcfnCc96UlZvnz5wNYSfgEAGKnFixdn2bJljzo2d+7cfOITn8iCBQsGutbQP+QCAAAez4IFC7Jq1apHHZszZ85Q1hJ+AQBIkpz96W/m32++a6BzHrT3rnnHSw4e6JxTYdsDAACdofMLAECSbFEd2mHR+QUAoDOEXwAARmrRokU56qijsnLlyoyNjeXCCy/MpZdemrGxsVx99dV58YtfnF/6pV8ayFq2PQAAMFJLlixZ7/ETTzxx4Gvp/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIAMFKnnnpqZs6cmblz5z5y7K1vfWsOPPDAHHLIITnxxBNz5513DmQt4RcAgJFavHhxli1b9qhjCxcuzHXXXZdvfOMbeeYzn5l3v/vdA1lL+AUAYKQWLFiQ6dOnP+rYsccem2nTep/HduSRR2b16tUDWcsnvAFPKLPGW5Yec9BGj191wIyccf5VQ6wIYCvyubOSH/7bYOfc89nJ8edMaYoPfOAD+dVf/dWBlCP8Ak8Yqw6YkWTNRo+fNd4mNR6ALc873/nOTJs2LSeddNJA5hN+gSeMyXZwJ9MhBiBT7tAO2kUXXZTPfOYzueKKK1JVA5lT+AUAYIuzbNmyvOc978k//uM/ZscddxzYvN7wBgDASC1atChHHXVUVq5cmbGxsVx44YV5/etfn7vvvjsLFy7MvHnz8tu//dsDWUvnFwCAkVqyZMnPHDvttNOGspbOLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAI3Xqqadm5syZmTt37iPH/uAP/iCHHHJI5s2bl2OPPTY333zzQNYSfgEAGKnFixdn2bJljzr21re+Nd/4xjeyYsWKnHDCCfmjP/qjgawl/AIAMFILFizI9OnTH3Vs1113feT2vffem6oayFo+4Q0AgCTJe655T26444aBznng9ANz5nPP3KTnvv3tb8+HP/zhPOUpT8mXvvSlgdSj8wsAwBbpne98Z2666aacdNJJef/73z+QOXV+AQBIkk3u0A7br/3ar+XFL35xzj777CnPpfMLAMAW58Ybb3zk9mWXXZYDDzxwIPPq/AIAMFKLFi3KlVdemTVr1mRsbCxnn312li5dmpUrV+ZJT3pSnva0p+X8888fyFrCLwAAI7VkyZKfOXbaaacNZS3bHgAA6AzhFwCAzphS+K2qN1XVN6vquqpaUlXbD6owAAAYtE0Ov1W1T5L/nmR+a21ukm2SvHpQhQEAwKBNddvDtCQ7VNW0JDsmuXnqJQEAwHBs8tUeWms/qKo/TvL9JD9O8vnW2ucHVhnAAMwab1l6zEEbPX7VATNyxvlXDbEiAEZpKtsenprkZUn2T7J3kp2q6uT1jDu9qpZX1fLx8fFNrxRgklYdMCO37lEbPX7WeMvsb68ZYkUArM+pp56amTNnZu7cuT/z2B//8R+nqrJmzWC+P0/lOr/HJPlea208SarqE0n+W5KLJw5qrV2Q5IIkmT9/fpvCegCTMtkO7mQ6xAAMzuLFi/P6178+v/7rv/6o4zfddFMuv/zy7LfffgNbayp7fr+f5Miq2rGqKskLk1w/mLIAAOiKBQsWZPr06T9z/E1velPe+973phc1B2Mqe37/pao+nuRrSR5Kcm36HV4AAJ54fviud+Un198w0DmfPOfA7Pm2t036eZdddln22WefHHrooQOtZ0ofb9xae0eSdwyoFgAAyH333Zd3vvOd+fznB38thSmFXwAAth6b0qEdhu985zv53ve+90jXd/Xq1TnssMNyzTXXZM8995zS3MIvAABblGc/+9m57bbbHrk/e/bsLF++PDNmzJjy3FP9kAsAAJiSRYsW5aijjsrKlSszNjaWCy+8cGhr6fwCADBSS5YsedzHV61aNbC1dH4BAOgM4RcAgM4QfgEA6AzhFwCAzhB+AQDoDOEXAIDOEH4BABipU089NTNnzszcuXMfOfaHf/iH2WeffTJv3rzMmzcvS5cuHchawi8AACO1ePHiLFu27GeOv+lNb8qKFSuyYsWKvOhFLxrIWsIvAAAjtWDBgkyfPn2zrOUT3gAASJJ8+aPfypqb7hnonDP23Tm/8KpnbtJz3//+9+fDH/5w5s+fn/e973156lOfOuV6dH4BANjivO51r8t3vvOdrFixInvttVfe/OY3D2RenV8AAJJkkzu0wzBr1qxHbr/2ta/NCSecMJB5dX4BANji3HLLLY/cvvTSSx91JYip0PkFAGCkFi1alCuvvDJr1qzJ2NhYzj777Fx55ZVZsWJFqiqzZ8/OX/7lXw5kLeEXAICRWrJkyc8cO+2004aylm0PAAB0hvALAEBn2PYAMMGs8Zalxxy00RkXeyIAAAwkSURBVONXHTAjZ5x/1RArAmCQhF+AvlUHzEiyZqPHzxpvkxoPsKVqraWqRl3GJmmtTWq88AvQN9kO7mQ6xABbqu233z633357dt999ydcAG6t5fbbb8/222+/0c8RfgEAOmxsbCyrV6/O+Pj4qEvZJNtvv33GxsY2erzwCwDQYdtuu23233//UZex2bjaAwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BlTCr9VtVtVfbyqbqiq66vqqEEVBgAAgzZtis8/L8my1torq2q7JDsOoCYAABiKTQ6/VbVrkgVJFidJa+2BJA8MpiwAABi8qXR+n55kPMkHq+rQJF9N8obW2r0DqQzgCWDWeMvSYw6a1HNWHTAjZ5x/1ZAqAuDxTGXP77QkhyX5/1prz0lyb5Kz1h1UVadX1fKqWj4+Pj6F5QC2LKsOmJFb96hJPWfWeMvsb68ZUkUAbMhUOr+rk6xurf1L//7Hs57w21q7IMkFSTJ//vw2hfUAtiib0r2dbJcYgMHa5M5va+2HSW6qqmf1D70wyb8PpCoAABiCqV7t4f9O8jf9Kz18N8lvTL0kAAAYjimF39baiiTzB1QLAAAMlU94AwCgM4RfAAA6Q/gFAKAzhF8AADpD+AUAoDOEXwAAOkP4BQCgM4RfAAA6Q/gFAKAzhF8AADpD+AUAoDOEXwAAOkP4BQCgM4RfAAA6Q/gFAKAzhF8AADpD+AUAoDOEXwAAOkP4BQCgM4RfAAA6Y9qoCwDomlnjLUuPOWijx686YEbOOP+qIVYE0B3CL8BmtOqAGUnWbPT4WeNtUuMBeHzCL8BmNNkO7mQ6xABsmD2/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHTGlMNvVW1TVddW1WcGURAAAAzLIDq/b0hy/QDmAQCAoZpS+K2qsSQvTvLXgykHAACGZ6qd33OT/F6Snw6gFgAAGKpNDr9VdUKS21prX93AuNOranlVLR8fH9/U5QAAYMqm0vn9+SQvrapVSS5J8oKqunjdQa21C1pr81tr8/fYY48pLAcAAFOzyeG3tfb7rbWx1trsJK9O8sXW2skDqwwAAAbMdX4BAOiMaYOYpLV2ZZIrBzEXAAAMi84vAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZwi8AAJ0h/AIA0BnCLwAAnSH8AgDQGcIvAACdIfwCANAZmxx+q2rfqvpSVV1fVd+sqjcMsjAAABi0aVN47kNJ3txa+1pV7ZLkq1V1eWvt3wdUGwAADNQmd35ba7e01r7Wv313kuuT7DOowgAAYNAGsue3qmYneU6Sf1nPY6dX1fKqWj4+Pj6I5QAAYJNMOfxW1c5J/j7JG1trd637eGvtgtba/Nba/D322GOqywEAwCabUvitqm3TC75/01r7xGBKAgCA4ZjK1R4qyYVJrm+t/cngSgIAgOGYSuf355O8JskLqmpF/8+LBlQXAAAM3CZf6qy19n+S1ABrAQCAofIJbwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdIbwCwBAZwi/AAB0hvALAEBnCL8AAHSG8AsAQGcIvwAAdMaUwm9VHVdVK6vq21V11qCKAgCAYdjk8FtV2yT5iyTHJzkoyaKqOmhQhQEAwKBNpfP73CTfbq19t7X2QJJLkrxsMGUBAMDgTZvCc/dJctOE+6uTHDG1cgbvyx/9VtbcdM+oywDYJHfs84Zs+0DLhaf85ahLAZi0n9Ytee2H/nDUZTzKVDq/tZ5j7WcGVZ1eVcuravn4+PgUlgPonvt32DYPbre+b7cAbIqpdH5XJ9l3wv2xJDevO6i1dkGSC5Jk/vz5PxOOh+0XXvXMzb0kwAAdNuoCALYqU+n8/muSZ1TV/lW1XZJXJ7lsMGUBAMDgbXLnt7X2UFW9Psk/JNkmyQdaa98cWGUAADBgU9n2kNba0iRLB1QLAAAMlU94AwCgM4RfAAA6Q/gFAKAzhF8AADpD+AUAoDOEXwAAOkP4BQCgM4RfAAA6Q/gFAKAzhF8AADpD+AUAoDOEXwAAOkP4BQCgM4RfAAA6Q/gFAKAzqrW2+RarGk/yH5ttwf8yI8maEazL5uU8d4Pz3A3O89bPOe6GUZ7np7XW9lj34GYNv6NSVctba/NHXQfD5Tx3g/PcDc7z1s857oYt8Tzb9gAAQGcIvwAAdEZXwu8Foy6AzcJ57gbnuRuc562fc9wNW9x57sSeXwAASLrT+QUAgK0//FbVcVW1sqq+XVVnjboeBqOqPlBVt1XVdROOTa+qy6vqxv7fTx1ljUxNVe1bVV+qquur6ptV9Yb+ced5K1JV21fVNVX19f55Prt/fP+q+pf+ef67qtpu1LUydVW1TVVdW1Wf6d93nrcyVbWqqv6tqlZU1fL+sS3q+/ZWHX6rapskf5Hk+CQHJVlUVQeNtioG5ENJjlvn2FlJrmitPSPJFf37PHE9lOTNrbU5SY5M8jv9/36d563LT5K8oLV2aJJ5SY6rqiOTvCfJn/bP84+SnDbCGhmcNyS5fsJ953nr9IuttXkTLnG2RX3f3qrDb5LnJvl2a+27rbUHklyS5GUjrokBaK1dleSOdQ6/LMlF/dsXJfnlzVoUA9Vau6W19rX+7bvT+x/mPnGetyqt557+3W37f1qSFyT5eP+487wVqKqxJC9O8tf9+xXnuSu2qO/bW3v43SfJTRPur+4fY+s0q7V2S9ILTklmjrgeBqSqZid5TpJ/ifO81en/KnxFktuSXJ7kO0nubK091B/ie/fW4dwkv5fkp/37u8d53hq1JJ+vqq9W1en9Y1vU9+1po1x8M6j1HHN5C3gCqaqdk/x9kje21u7qNYvYmrTWHk4yr6p2S3JpkjnrG7Z5q2KQquqEJLe11r5aVUevPbyeoc7zE9/Pt9ZurqqZSS6vqhtGXdC6tvbO7+ok+064P5bk5hHVwvDdWlV7JUn/79tGXA9TVFXbphd8/6a19on+Yed5K9VauzPJlent8d6tqtY2aHzvfuL7+SQvrapV6W1BfEF6nWDneSvTWru5//dt6f0w+9xsYd+3t/bw+69JntF/N+l2SV6d5LIR18TwXJbklP7tU5J8aoS1MEX9/YAXJrm+tfYnEx5ynrciVbVHv+ObqtohyTHp7e/+UpJX9oc5z09wrbXfb62NtdZmp/f/4i+21k6K87xVqaqdqmqXtbeTHJvkumxh37e3+g+5qKoXpffT5TZJPtBae+eIS2IAqmpJkqOTzEhya5J3JPlkko8m2S/J95P8Smtt3TfF8QRRVc9L8uUk/5b/2iP4tvT2/TrPW4mqOiS9N8Bsk15D5qOttT+qqqen1yGcnuTaJCe31n4yukoZlP62h7e01k5wnrcu/fN5af/utCR/21p7Z1Xtni3o+/ZWH34BAGCtrX3bAwAAPEL4BQCgM4RfAAA6Q/gFAKAzhF8AADpD+AUAoDOEXwAAOkP4BQCgM/5/ENQLFzC04TQAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "mod = inventory_model(label='production',max_inventory=50)\n", "mod.demand = 15\n", "mod.c = 5\n", "mod.p = 2.5\n", "mod.r = 1.4\n", "mod.β = 0.975\n", "mod = solver_backwards_induction(mod,T=15)\n", "plot_solution(mod)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Next steps\n", "\n", "- Stochastic demand \n", "- Infinite horizon \n", "\n", "\n", "More appropriate setup for the dynamic programming solution, so today only a simple special case" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Further learning resources\n", "\n", "- 📖 Adda and Russell Cooper “Dynamic Economics. Quantitative Methods and Applications.” *Chapters: 2, 3.3* \n", "- Bellman equation [https://en.wikipedia.org/wiki/Bellman_equation](https://en.wikipedia.org/wiki/Bellman_equation) \n", "- Computer science view on DP [https://www.techiedelight.com/introduction-dynamic-programming](https://www.techiedelight.com/introduction-dynamic-programming) \n", "- Popular optimal stopping [https://www.americanscientist.org/article/knowing-when-to-stop](https://www.americanscientist.org/article/knowing-when-to-stop) " ] } ], "metadata": { "celltoolbar": "Slideshow", "date": 1612589585.955616, "download_nb": false, "filename": "27_dp_intro.rst", "filename_with_path": "27_dp_intro", "kernelspec": { "display_name": "Python", "language": "python3", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" }, "title": "Foundations of Computational Economics #27" }, "nbformat": 4, "nbformat_minor": 4 }