Quire

Stochastic dynamic programming

From Quire, the open reference·1957 technique for modelling problems of decision making under uncertainty·10 min read

Originally introduced by Richard E. Bellman in (Bellman 1957), stochastic dynamic programming (SDP) is a technique for modelling and solving problems of decision making under uncertainty. Closely related to stochastic programming and dynamic programming, stochastic dynamic programming represents the problem under scrutiny in the form of a Bellman equation.[1] The aim is to compute a policy prescribing how to act optimally in the face of uncertainty.

A motivating example: Gambling game#edit

A gambler has $2, she is allowed to play a game of chance 4 times and her goal is to maximize her probability of ending up with a least $6. If the gambler bets ${\displaystyle b} on a play of the game, then with probability 0.4 she wins the game, recoups the initial bet, and she increases her capital position by ${\displaystyle b}; with probability 0.6, she loses the bet amount ${\displaystyle b}; all plays are pairwise independent. On any play of the game, the gambler may not bet more money than she has available at the beginning of that play.[2]

Stochastic dynamic programming can be employed to model this problem and determine a betting strategy that, for instance, maximizes the gambler's probability of attaining a wealth of at least $6 by the end of the betting horizon.

Note that if there is no limit to the number of games that can be played, the problem becomes a variant of the well known St. Petersburg paradox.

An optimal betting strategy that maximizes the gambler's probability of attaining a wealth of at least $6 by the end of the betting horizon; represents the bet amount for game when the gambler has $ a
An optimal betting strategy that maximizes the gambler's probability of attaining a wealth of at least $6 by the end of the betting horizon; {\displaystyle b_{t}(\$x)} represents the bet amount for game {\displaystyle t} when the gambler has ${\displaystyle x} at the beginning of that play. If the decision maker follows this policy, with probability 0.1984 she will attain a wealth of at least $6. Image: source and license

Formal background#edit

Consider a discrete system defined on {\displaystyle n} stages in which each stage {\displaystyle t=1,\ldots ,n} is characterized by

  • an initial state {\displaystyle s_{t}\in S_{t, where {\displaystyle S_{t is the set of feasible states at the beginning of stage {\displaystyle t};
  • a decision variable {\displaystyle x_{t}\in X_{t, where {\displaystyle X_{t is the set of feasible actions at stage {\displaystyle t} – note that {\displaystyle X_{t may be a function of the initial state {\displaystyle s_{t;
  • an immediate cost/reward function {\displaystyle p_{t}(s_{t},x_{t})}, representing the cost/reward at stage {\displaystyle t} if {\displaystyle s_{t is the initial state and {\displaystyle x_{t the action selected;
  • a state transition function {\displaystyle g_{t}(s_{t},x_{t})} that leads the system towards state {\displaystyle s_{t+1}=g_{t}(s_{t},x_{t})}.

Let {\displaystyle f_{t}(s_{t})} represent the optimal cost/reward obtained by following an optimal policy over stages {\displaystyle t,t+1,\ldots ,n}. Without loss of generality in what follow we will consider a reward maximisation setting. In deterministic dynamic programming one usually deals with functional equations taking the following structure

{\displaystyle f_{t}(s_{t})=\max _{x_{t}\in X_{t\{p_{t}(s_{t},x_{t})+f_{t+1}(s_{t+1})\

where {\displaystyle s_{t+1}=g_{t}(s_{t},x_{t})} and the boundary condition of the system is

{\displaystyle f_{n}(s_{n})=\max _{x_{n}\in X_{n\{p_{n}(s_{n},x_{n})\}.}

The aim is to determine the set of optimal actions that maximise {\displaystyle f_{1}(s_{1})}. Given the current state {\displaystyle s_{t and the current action {\displaystyle x_{t, we know with certainty the reward secured during the current stage and – thanks to the state transition function {\displaystyle g_{t – the future state towards which the system transitions.

In practice, however, even if we know the state of the system at the beginning of the current stage as well as the decision taken, the state of the system at the beginning of the next stage and the current period reward are often random variables that can be observed only at the end of the current stage.

Stochastic dynamic programming deals with problems in which the current period reward and/or the next period state are random, i.e. with multi-stage stochastic systems. The decision maker's goal is to maximise expected (discounted) reward over a given planning horizon.

In their most general form, stochastic dynamic programs deal with functional equations taking the following structure

{\displaystyle f_{t}(s_{t})=\max _{x_{t}\in X_{t}(s_{t})}\left\{({\text{expected reward during stage t\mid s_{t},x_{t})+\alpha \sum _{s_{t+1\Pr(s_{t+1}\mid s_{t},x_&#

where

  • {\displaystyle f_{t}(s_{t})} is the maximum expected reward that can be attained during stages {\displaystyle t,t+1,\ldots ,n}, given state {\displaystyle s_{t at the beginning of stage {\displaystyle t};
  • {\displaystyle x_{t belongs to the set {\displaystyle X_{t}(s_{t})} of feasible actions at stage {\displaystyle t} given initial state {\displaystyle s_{t;
  • {\displaystyle \alpha } is the discount factor;
  • {\displaystyle \Pr(s_{t+1}\mid s_{t},x_{t})} is the conditional probability that the state at the end of stage {\displaystyle t} is {\displaystyle s_{t+1 given current state {\displaystyle s_{t and selected action {\displaystyle x_{t.

Markov decision processes represent a special class of stochastic dynamic programs in which the underlying stochastic process has state transitions satisfying the Markov property.

Gambling game as a stochastic dynamic program#edit

Gambling game can be formulated as a Stochastic Dynamic Program as follows: there are {\displaystyle n=4} games (i.e. stages) in the planning horizon

  • the state {\displaystyle s} in period {\displaystyle t} represents the initial wealth at the beginning of period {\displaystyle t};
  • the action given state {\displaystyle s} in period {\displaystyle t} is the bet amount {\displaystyle b};
  • the transition probability {\displaystyle p_{i,j}^{a from state {\displaystyle i} to state {\displaystyle j} when action {\displaystyle a} is taken in state {\displaystyle i} is easily derived from the probability of winning (0.4) or losing (0.6) a game.

Let {\displaystyle f_{t}(s)} be the probability that, by the end of game 4, the gambler has at least $6, given that she has ${\displaystyle s} at the beginning of game {\displaystyle t}.

  • the immediate profit incurred if action {\displaystyle b} is taken in state {\displaystyle s} is given by the expected value {\displaystyle p_{t}(s,b)=0.4f_{t+1}(s+b)+0.6f_{t+1}(s-b)}.

To derive the functional equation, define {\displaystyle b_{t}(s)} as a bet that attains {\displaystyle f_{t}(s)}, then at the beginning of game {\displaystyle t=4}

  • if {\displaystyle s<3} it is impossible to attain the goal, i.e. {\displaystyle f_{4}(s)=0} for {\displaystyle s<3};
  • if {\displaystyle s\geq 6} the goal is attained, i.e. {\displaystyle f_{4}(s)=1} for {\displaystyle s\geq 6};
  • if {\displaystyle 3\leq s\leq 5} the gambler should bet enough to attain the goal, i.e. {\displaystyle f_{4}(s)=0.4} for {\displaystyle 3\leq s\leq 5}.

For {\displaystyle t<4} the functional equation is {\displaystyle f_{t}(s)=\max _{b_{t}(s)}\{0.4f_{t+1}(s+b)+0.6f_{t+1}(s-b)\, where {\displaystyle b_{t}(s)} ranges in {\displaystyle 0,...,s}; the aim is to find {\displaystyle f_{1}(2)}.

Given the functional equation, an optimal betting policy can be obtained via forward recursion or backward recursion algorithms, as outlined below.

Solution methods#edit

Stochastic dynamic programs can be solved to optimality by using backward recursion or forward recursion algorithms. Memoization is typically employed to enhance performance. However, like deterministic dynamic programming also its stochastic variant suffers from the curse of dimensionality. For this reason approximate solution methods are typically employed in practical applications.

Backward recursion#edit

Given a bounded state space, backward recursion (Bertsekas 2000) begins by tabulating {\displaystyle f_{n}(k)} for every possible state {\displaystyle k} belonging to the final stage {\displaystyle n}. Once these values are tabulated, together with the associated optimal state-dependent actions {\displaystyle x_{n}(k)}, it is possible to move to stage {\displaystyle n-1} and tabulate {\displaystyle f_{n-1}(k)} for all possible states belonging to the stage {\displaystyle n-1}. The process continues by considering in a backward fashion all remaining stages up to the first one. Once this tabulation process is complete, {\displaystyle f_{1}(s)} – the value of an optimal policy given initial state {\displaystyle s} – as well as the associated optimal action {\displaystyle x_{1}(s)} can be easily retrieved from the table. Since the computation proceeds in a backward fashion, it is clear that backward recursion may lead to computation of a large number of states that are not necessary for the computation of {\displaystyle f_{1}(s)}.

Forward recursion#edit

Given the initial state {\displaystyle s} of the system at the beginning of period 1, forward recursion (Bertsekas 2000) computes {\displaystyle f_{1}(s)} by progressively expanding the functional equation (forward pass). This involves recursive calls for all {\displaystyle f_{t+1}(\cdot ),f_{t+2}(\cdot ),\ldots } that are necessary for computing a given {\displaystyle f_{t}(\cdot )}. The value of an optimal policy and its structure are then retrieved via a (backward pass) in which these suspended recursive calls are resolved. A key difference from backward recursion is the fact that {\displaystyle f_{t is computed only for states that are relevant for the computation of {\displaystyle f_{1}(s)}. Memoization is employed to avoid recomputation of states that have been already considered.

Example: Gambling game#edit

We shall illustrate forward recursion in the context of the Gambling game instance previously discussed. We begin the forward pass by considering {\displaystyle f_{1}(2)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 1,2,3,4\\\hline 0&0.4f_{2}(2+0)+0.6f_{2}(2-0)\\1&0.4f_{2}(2+1)+0.6f_{2}(2-1)\\2&0.4f_{2}(2+2)+0.6f_{2&#1

At this point we have not computed yet {\displaystyle f_{2}(4),f_{2}(3),f_{2}(2),f_{2}(1),f_{2}(0)}, which are needed to compute {\displaystyle f_{1}(2)}; we proceed and compute these items. Note that {\displaystyle f_{2}(2+0)=f_{2}(2-0)=f_{2}(2)}, therefore one can leverage memoization and perform the necessary computations only once.

Computation of {\displaystyle f_{2}(4),f_{2}(3),f_{2}(2),f_{2}(1),f_{2}(0)}

{{mathimg|c795ac19bc1083b80b2bbf1dca848fd5386453c2|width=55.117ex|height=7.509ex|va=-3.171ex|alt={\displaystyle f_{2}(0)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 2,3,4\\\hline 0&0.4f_{3}(0+0)+0.6f_{3}(0-0)\\\end{array\right.}}}

{{mathimg|6e01cdcc166494a4802be5b52e2503aa7ca6de9c|width=55.309ex|height=10.509ex|va=-4.671ex|alt={\displaystyle f_{2}(1)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 2,3,4\\\hline 0&0.4f_{3}(1+0)+0.6f_{3}(1-0)\\1&0.4f_{3}(1+1)+0.6f_{3}(1-1)\\\end{array\right.}}}

{{mathimg|90ab1e98ee88fdbd9779a5a7b0fa971bd90a00fb|width=55.309ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{2}(2)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 2,3,4\\\hline 0&0.4f_{3}(2+0)+0.6f_{3}(2-0)\\1&0.4f_{3}(2+1)+0.6f_{3}(2-1)\\2&0.4f_{3}(2+2)+0.6f_{3&#125}}

{{mathimg|2f7e80d08825c680d708d5d284f5e75bff1b5a76|width=55.309ex|height=17.176ex|va=-8.005ex|alt={\displaystyle f_{2}(3)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 2,3,4\\\hline 0&0.4f_{3}(3+0)+0.6f_{3}(3-0)\\1&0.4f_{3}(3+1)+0.6f_{3}(3-1)\\2&0.4f_{3}(3+2)+0.6f_{3&#125}}

{{mathimg|0a9d38173eb594235cafe28c655032d2744b51d5|width=55.309ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{2}(4)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 2,3,4\\\hline 0&0.4f_{3}(4+0)+0.6f_{3}(4-0)\\1&0.4f_{3}(4+1)+0.6f_{3}(4-1)\\2&0.4f_{3}(4+2)+0.6f_{3&#125}}

We have now computed {\displaystyle f_{2}(k)} for all {\displaystyle k} that are needed to compute {\displaystyle f_{1}(2)}. However, this has led to additional suspended recursions involving {\displaystyle f_{3}(4),f_{3}(3),f_{3}(2),f_{3}(1),f_{3}(0)}. We proceed and compute these values.

Computation of {\displaystyle f_{3}(4),f_{3}(3),f_{3}(2),f_{3}(1),f_{3}(0)}

{{mathimg|a649ef5830649d6aea249166efdd7b6379882218|width=53.307ex|height=7.509ex|va=-3.171ex|alt={\displaystyle f_{3}(0)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 3,4\\\hline 0&0.4f_{4}(0+0)+0.6f_{4}(0-0)\\\end{array\right.}}}

{{mathimg|ec57be82c8dea747cb38b5854e9ba67aaa44a205|width=53.5ex|height=10.509ex|va=-4.671ex|alt={\displaystyle f_{3}(1)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 3,4\\\hline 0&0.4f_{4}(1+0)+0.6f_{4}(1-0)\\1&0.4f_{4}(1+1)+0.6f_{4}(1-1)\\\end{array\right.}}}

{{mathimg|d80121dad243ce3c0fea6ee939990b07c7c9357f|width=53.5ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{3}(2)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 3,4\\\hline 0&0.4f_{4}(2+0)+0.6f_{4}(2-0)\\1&0.4f_{4}(2+1)+0.6f_{4}(2-1)\\2&0.4f_{4}(2+2)+0.6f_{4}(}}

{{mathimg|676e8dfcab8a9fe210d563080da535249e9e1aa1|width=53.5ex|height=17.176ex|va=-8.005ex|alt={\displaystyle f_{3}(3)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 3,4\\\hline 0&0.4f_{4}(3+0)+0.6f_{4}(3-0)\\1&0.4f_{4}(3+1)+0.6f_{4}(3-1)\\2&0.4f_{4}(3+2)+0.6f_{4}(}}

{{mathimg|79d843409feb498ffb357a50356cc3177cb6bb2e|width=53.5ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{3}(4)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 3,4\\\hline 0&0.4f_{4}(4+0)+0.6f_{4}(4-0)\\1&0.4f_{4}(4+1)+0.6f_{4}(4-1)\\2&0.4f_{4}(4+2)+0.6f_{4}(}}

{{mathimg|34c7bf686aae013ac7f2046a6752793987711daf|width=53.5ex|height=10.509ex|va=-4.671ex|alt={\displaystyle f_{3}(5)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 3,4\\\hline 0&0.4f_{4}(5+0)+0.6f_{4}(5-0)\\1&0.4f_{4}(5+1)+0.6f_{4}(5-1)\end{array\right.}}}

Since stage 4 is the last stage in our system, {\displaystyle f_{4}(\cdot )} represent boundary conditions that are easily computed as follows.

Boundary conditions

{{mathimg|10b7990c41c93fcbf5de297ec23fbba0ed2cbb3d|width=45.793ex|height=23.176ex|va=-11.005ex|alt={\displaystyle {\begin{array}{ll}f_{4}(0)=0&b_{4}(0)=0\\f_{4}(1)=0&b_{4}(1)=\{0,1\}\\f_{4}(2)=0&b_{4}(2)=\{0,1,2\}\\f_{4}(3)=0.4&b_{4}(3)=}}

At this point it is possible to proceed and recover the optimal policy and its value via a backward pass involving, at first, stage 3

Backward pass involving {\displaystyle f_{3}(\cdot )}

{{mathimg|6fc0c35ffd88594f5278d5118acbe0ba8f568769|width=53.307ex|height=7.509ex|va=-3.171ex|alt={\displaystyle f_{3}(0)=\min \left\\begin{array}{rr}b&{\text{success probability in periods 3,4\\\hline 0&0.4(0)+0.6(0)=0\\\end{array\right.}}}

{{mathimg|09d6ce70ec3331abd0821abb049300c0b6195d3e|width=68.076ex|height=10.509ex|va=-4.671ex|alt={\displaystyle f_{3}(1)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 3,4&{\mbox{max\\\hline 0&0.4(0)+0.6(0)=0&\leftarrow b_{3}(1)=0\\1&0.4(0)+0.6(0)=0&\leftarrow b_{3}(1)=1\\\end&#1}}

{{mathimg|bcd41fa1cbade5bcec8a23e90ddfd48816a488f2|width=68.076ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{3}(2)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 3,4&{\mbox{max\\\hline 0&0.4(0)+0.6(0)=0\\1&0.4(0.4)+0.6(0)=0.16&\leftarrow b_{3}(2)=1\\2&0.4(0.4)+0.6(0)=0.16&\leftarrow }}

{{mathimg|cc57bef584a6a881e6f0b2b68f4e2ce6207162d7|width=68.076ex|height=17.176ex|va=-8.005ex|alt={\displaystyle f_{3}(3)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 3,4&{\mbox{max\\\hline 0&0.4(0.4)+0.6(0.4)=0.4&\leftarrow b_{3}(3)=0\\1&0.4(0.4)+0.6(0)=0.16\\2&0.4(0.4)+0.6(0)=0.16\\3&0.}}

{{mathimg|5f4bcbbed0dcfabb7da2a50c46d2448c961926fb|width=68.076ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{3}(4)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 3,4&{\mbox{max\\\hline 0&0.4(0.4)+0.6(0.4)=0.4&\leftarrow b_{3}(4)=0\\1&0.4(0.4)+0.6(0.4)=0.4&\leftarrow b_{3}(4)&#6}}

{{mathimg|f4426be5bca4f15e7e97aa6ec7450cf6422a3838|width=68.076ex|height=10.509ex|va=-4.671ex|alt={\displaystyle f_{3}(5)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 3,4&{\mbox{max\\\hline 0&0.4(0.4)+0.6(0.4)=0.4\\1&0.4(1)+0.6(0.4)=0.64&\leftarrow b_{3}(5)=1\\\end{array\right.}}}

and, then, stage 2.

Backward pass involving {\displaystyle f_{2}(\cdot )}

{{mathimg|32baac15ab7c6772f92616e0ff5aa58705d6da8d|width=69.693ex|height=7.509ex|va=-3.171ex|alt={\displaystyle f_{2}(0)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 2,3,4&{\mbox{max\\\hline 0&0.4(0)+0.6(0)=0&\leftarrow b_{2}(0)=0\\\end{array\right.}}}

{{mathimg|a4a9c0d99b0e2dfd86ac16a3ffe7fa78a3e38ba5|width=69.885ex|height=10.509ex|va=-4.671ex|alt={\displaystyle f_{2}(1)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 2,3,4&{\mbox{max\\\hline 0&0.4(0)+0.6(0)=0\\1&0.4(0.16)+0.6(0)=0.064&\leftarrow b_{2}(1)=1\\\end{array\right.}}}

{{mathimg|6eb30842feb0e6b6b65a1574655820e22c601e48|width=69.885ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{2}(2)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 2,3,4&{\mbox{max\\\hline 0&0.4(0.16)+0.6(0.16)=0.16&\leftarrow b_{2}(2)=0\\1&0.4(0.4)+0.6(0)=0.16&\leftarrow b_{2}(2}}

{{mathimg|c5d52326aabeef8a5793f31ab506ba60df9d9eaf|width=69.885ex|height=17.176ex|va=-8.005ex|alt={\displaystyle f_{2}(3)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 2,3,4&{\mbox{max\\\hline 0&0.4(0.4)+0.6(0.4)=0.4&\leftarrow b_{2}(3)=0\\1&0.4(0.4)+0.6(0.16)=0.256\\2&0.4(0.64)+0.6(0)=0.2}}

{{mathimg|4d6527bceddfb155376d246548742de38ff7b499|width=69.885ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{2}(4)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 2,3,4&{\mbox{max\\\hline 0&0.4(0.4)+0.6(0.4)=0.4\\1&0.4(0.64)+0.6(0.4)=0.496&\leftarrow b_{2}(4)=1\\2&0.4(1)+0.6(0.16)=0.4}}

We finally recover the value {\displaystyle f_{1}(2)} of an optimal policy

{{mathimg|2e06e79d0766e8bd7af07e9248f859b38f0a52fe|width=71.695ex|height=13.843ex|va=-6.338ex|alt={\displaystyle f_{1}(2)=\min \left\\begin{array}{rrr}b&{\text{success probability in periods 1,2,3,4&{\mbox{max\\\hline 0&0.4(0.16)+0.6(0.16)=0.16\\1&0.4(0.4)+0.6(0.064)=0.1984&\leftarrow b_{1}(2)=1\\2&0.4(0.496)+0.6(0)}}

This is the optimal policy that has been previously illustrated. Note that there are multiple optimal policies leading to the same optimal value {\displaystyle f_{1}(2)=0.1984}; for instance, in the first game one may either bet $1 or $2.

Python implementation. The one that follows is a complete Python implementation of this example.

import functools

class memoize:
    def __init__(self, func):
        self.func = func
        self.memoized = {}
        self.method_cache = {}

    def __call__(self, *args):
        return self.cache_get(self.memoized, args, lambda: self.func(*args))

    def __get__(self, obj, objtype):
        return self.cache_get(
            self.method_cache,
            obj,
            lambda: self.__class__(functools.partial(self.func, obj)),
        )

    def cache_get(self, cache, key, func):
        try:
            return cache[key]
        except KeyError:
            cache[key] = func()
            return cache[key]

    def reset(self):
        self.memoized = {}
        self.method_cache = {}

class State:
    """The state of the gambler's ruin problem"""

    def __init__(self, t: int, wealth: float):
        """state constructor

        Arguments:
            t {int} -- time period
            wealth {float} -- initial wealth
        """
        self.t, self.wealth = t, wealth

    def __eq__(self, other):
        return self.__dict__ == other.__dict__

    def __str__(self):
        return str(self.t) + " " + str(self.wealth)

    def __hash__(self):
        return hash(str(self))

class GamblersRuin:
    def __init__(
        self,
        bettingHorizon: int,
        targetWealth: float,
        pmf: list[list[tuple[int, float]]],
    ):
        """The gambler's ruin problem.

        Arguments:
            bettingHorizon {int} -- betting horizon
            targetWealth {float} -- target wealth
            pmf {list[list[tuple[int, float]]]} -- probability mass function
        """

        # initialize instance variables
        self.bettingHorizon, self.targetWealth, self.pmf = (
            bettingHorizon,
            targetWealth,
            pmf,
        )

        # lambdas
        self.ag = lambda s: [
            i for i in range(0, min(self.targetWealth // 2, s.wealth) + 1)
        ]  # action generator
        self.st = lambda s, a, r: State(
            s.t + 1, s.wealth - a + a * r
        )  # state transition
        self.iv = (
            lambda s, a, r: 1 if s.wealth - a + a * r >= self.targetWealth else 0
        )  # immediate value function

        self.cache_actions = {}  # cache with optimal state/action pairs

    def f(self, wealth: float) -> float:
        s = State(0, wealth)
        return self._f(s)

    def q(self, t: int, wealth: float) -> float:
        s = State(t, wealth)
        return self.cache_actions[str(s)]

    @memoize
    def _f(self, s: State) -> float:
        # Forward recursion
        values = [sum([p[1]*(self._f(self.st(s, a, p[0])) if s.t < self.bettingHorizon - 1 
                             else self.iv(s, a, p[0]))   # value function
                       for p in self.pmf[s.t]])          # bet realisations
                  for a in self.ag(s)]                   # actions                          
                       

        v = max(values)
        try:
            self.cache_actions[str(s)] = self.ag(s)[values.index(v)]  # store best action
        except ValueError:
            self.cache_actions[str(s)] = None
            print("Error in retrieving best action")
        return v  # return expected total cost

instance = {
    "bettingHorizon": 4,
    "targetWealth": 6,
    "pmf": [[(0, 0.6), (2, 0.4)] for i in range(0, 4)],
}
gr, initial_wealth = GamblersRuin(**instance), 2

# f_1(x) is gambler's probability of attaining $targetWealth at the end of bettingHorizon
print("f_1(" + str(initial_wealth) + "): " + str(gr.f(initial_wealth)))

# Recover optimal action for period 2 when initial wealth at the beginning of period 2 is $1.
t, initial_wealth = 1, 1
print(
    "b_" + str(t + 1) + "(" + str(initial_wealth) + "): " + str(gr.q(t, initial_wealth))
)

Java implementation. GamblersRuin.java is a standalone Java 8 implementation of the above example.

Approximate dynamic programming#edit

Approximate dynamic programming (ADP) (also known as neuro-dynamic programming[3] or reinforcement learning[4]) is a general approach to modeling and algorithmic strategy, mostly for stochastic problems and sometimes for large and complex problems.[5] ADP, like SDP, was created by Richard Bellman, and later developed (at first independently) by the operations research, computer science, and engineering controls communities. Warren B. Powell wrote in an article in Annals of Operations Research how:[6]

More so than other communities, operations research continued to develop the theory behind the basic model introduced by Bellman with discrete states and actions, even while authors as early as Bellman himself recognized its limits due to the “curse of dimensionality” inherent in discrete state spaces.

The curse of dimensionality (the difficulty in analyzing data with multiple aspect (dimensions)) is a well established issue with the use of Bellman's equation, and ADP is often presented as a method for overcoming this issue. However, the main idea of ADP is "learning what to learn, and how to learn it, to make better decisions over time".[5]

Stochastic dual dynamic programming (SDDP)#edit

One method that can be regarded as an approximate dynamic programming method is stochastic dual dynamic programming (SDDP).[1] M. V. F. Periera and L. V. M. G. Pinto had proposed the idea in 1991 with "a methodology for the solution of multistage stochastic optimization problems, based on the approximation of the expected-cost-to-go functions of stochastic dynamic programming by piecewise linear functions." Their motivation was largely for a more efficient optimization method than stochastic dynamic programming (SDP) for operating Brazilian power plants.[7] Developing in part from stochastic dynamic programming (SDP), SDDP is an algorithm that addresses multistage stochastic problems by means of finding an optimal policy by means of computation or by means of an approximate solution. Along with SDP serving as a foundation to SDDP, stochastic programming also was part of the history of the development of SDDP.[1]

Sources#edit

Further reading#edit

  • Ross, S. M.; Bimbaum, Z. W.; Lukacs, E. (1983), Introduction to Stochastic Dynamic Programming, Elsevier, ISBN 978-0-12-598420-1.

See also#edit

References#edit

  1. ^ a b c Füllner, Christian; Rebennack, Steffen (2025-08-07). "Stochastic Dual Dynamic Programming and Its Variants: A Review". SIAM Review. 67 (3): 415–539. doi:10.1137/23M1575093. ISSN 0036-1445.
  2. ^ This problem is adapted from W. L. Winston, Operations Research: Applications and Algorithms (7th Edition), Duxbury Press, 2003, chap. 19, example 3.
  3. ^ "Approximate Dynamic Programming" (PDF).
  4. ^ Wu, Cathy. "Dynamic programming: What makes sequential decision making hard?" (PDF).
  5. ^ a b Powell, Warren B. (2009). "What you should know about approximate dynamic programming". Naval Research Logistics (NRL). 56 (3): 239–249.
  6. ^ Powell, Warren B. (2016-06-01). "Perspectives of approximate dynamic programming". Annals of Operations Research. 241 (1): 319–356. doi:10.1007/s10479-012-1077-6. ISSN 1572-9338.
  7. ^ Pereira, M. V. F.; Pinto, L. M. V. G. (1991-05-01). "Multi-stage stochastic optimization applied to energy planning". Mathematical Programming. 52 (1): 359–375. doi:10.1007/BF01582895. ISSN 1436-4646.

This article is mirrored from “Stochastic dynamic programming” on English Wikipedia, revision 1373671007, written by Wikipedia's contributors and licensed CC BY-SA 4.0. Editing it here creates a Quire copy with its own history.

Synced with Wikipedia revision 1373671007 · just now