liveBook · Manning

Markov chain

As explained in Fabulous Adventures in Data Structures and Algorithms

A Markov process is a stochastic process in which the conditional distribution of the next state depends only on the current state.

Suppose a gambler’s chips rise or fall by one after each bet. To choose the next chip count, a simulation needs the current count, not the whole betting history. That is the Markov property: the distribution of the next state depends only on the current state. Sampling an initial state, then repeatedly sampling a transition distribution, produces a random sequence of states. States may be discrete or continuous, and the sequence may be finite or infinite. section 16.1

Listing 16.1 A general-purpose Markov process
sealed class Markov<T> : IDistribution<IEnumerable<T>>
{
    private readonly IDistribution<T> initial;
    private readonly Func<T, IDistribution<T>> transition;

    public static Markov<T> Distribution(
        IDistribution<T> initial,
        Func<T, IDistribution<T>> transition) =>
        new Markov<T>(initial, transition);

    private Markov(
      IDistribution<T> initial,
      Func<T, IDistribution<T>> transition)
    {
        this.initial = initial;
        this.transition = transition;
    }
    public IEnumerable<T> Sample()
    {
        var distribution = initial;
        while (distribution is not Empty<T>)
        {
            var state = distribution.Sample();
            yield return state;
            distribution = transition(state);
        }
    }
}

The C# implementation makes the distinction between a state and its possible successors explicit. `Markov<T>` stores an initial `IDistribution<T>` and a transition function from `T` to `IDistribution<T>`. `Sample()` yields each sampled state, then asks the transition function what can happen next. An `Empty<T>` distribution ends the sequence. section 16.1

Gambler’s ruin

Let the state be the number of chips in a pocket. From an intermediate count, the transition samples either one chip fewer or one chip more; at zero or ten, it returns an empty distribution. A sample might wander through `5,4,3,4,5` before eventually reaching zero. Repeated samples can be counted to examine how long these walks last. The stopping rule belongs in the transition function, not in a separate history of bets. section 16.1

A word can be a state too. For a small text generator, count the first words of existing sentences to form the initial distribution. For each word, count the words observed immediately after it to form that word’s transition distribution. Sampling then joins locally plausible word pairs into new sentences; the resulting text can sound recognizably like its source while making little sense overall. section 16.2

Listing 16.4 A mutable builder for Markov processes
sealed class MarkovBuilder<T> where T : notnull
{
    private CategoricalBuilder<T> initial = new();
    private Dictionary<T, CategoricalBuilder<T>> transitions = new();
    public void AddInitial(T t)
    {
        initial.Add(t);
    }
    public void AddTransition(T t1, T t2)
    {
        if (!transitions.ContainsKey(t1))
            transitions[t1] = new();
        transitions[t1].Add(t2);
    }
    public Markov<T> ToDistribution()
    {
        var init = initial.ToDistribution();
        var trans = transitions.ToDictionary(
          kv => kv.Key,
          kv => kv.Value.ToDistribution()); #1
        return Markov<T>.Distribution(init,
          k => trans.GetValueOrDefault(k, Empty<T>.Distribution));
    }
}

`MarkovBuilder<T>` keeps one categorical builder for initial states and a dictionary of categorical builders for transitions. Converting the recorded counts to distributions supplies the two inputs required by `Markov<T>`; a state with no recorded successor maps to `Empty<T>`. section 16.2

The same sequence structure also supports the Metropolis algorithm. Its states are samples from a target distribution: each transition proposes a value near the current one, then chooses either the proposal or the current value again. This connects a simple random walk to sampling continuous distributions, including posterior distributions. section 16.4 section 16.6

How Fabulous Adventures in Data Structures and Algorithms covers it

How deep it goes
Defines the current-state rule and builds a generic sampler and count-based word model, then reuses the sampler for Metropolis transitions.
Examples
Uses a gambler’s chip-count walk and a word-pair generator trained on Shakespearean sentences.
What it assumes
Assumes familiarity with C# generic types and distribution sampling while defining the Markov property through concrete examples.
What you can do after
Build it from scratch as a C# distribution of state sequences, with transitions that can also terminate a sequence.
How it connects
Connects initial distributions, transition functions, categorical distributions, language models, and posterior sampling.

Also explained in

Compare how 4 books explain Markov chain →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Fabulous Adventures in Data Structures and Algorithms. The section links point to the parts of the book it draws on.