Markov and Partially Observable Decision Processes › Worked Example: Solving a Two-State MDP by Hand
World Models HandbookAll chapters Markov and Partially Observable Decision Processes › Worked Example: Solving a Two-State MDP by HandOne section · Sections in this chapter5 / 14 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Before writing any code, let us solve a complete MDP analytically. The problem is small enough to do with algebra, which makes the Bellman machinery concrete.
A machine is either working (W) or broken (B). When working, you may operate it, earning reward 4 per step, but each step it breaks with probability 0.1. Alternatively you may service it, earning nothing but keeping it working. When broken, you may repair it at a cost of 2, returning it to working state in one step, or wait and earn nothing while it stays broken. The discount factor is .
First, guess the structure of the optimal policy: operate when working, repair when broken. We will verify the guess afterward. This guess-and-verify pattern is a standard analytical technique: in small problems you can hypothesize the shape of the solution, solve the resulting linear system, and then check that no alternative action contradicts the hypothesis. Under this policy, the Bellman expectation equations read:
Substituting the second equation into the first:
Solving, , and then .
Now verify the guess by checking that neither alternative action beats the assumed one. Servicing instead of operating when working yields , which is less than 35.05. Waiting instead of repairing when broken yields , less than 29.54. Both alternatives lose, so the guessed policy is indeed optimal, and the values are correct.
The guess-and-verify calculation has already certified that operating in W and repairing in B are the winning actions. We can therefore iterate the fixed-policy Bellman backup for those two actions from zero; it reaches the same values that the full max-based optimality operator would compute.
## Two-state maintenance MDP: states W(0), B(1); actions operate/repair taken optimally.
gamma_2s = 0.9
P_opt = np.array(
[
[0.9, 0.1], # working, operating
[1.0, 0.0],
]
) # broken, repairing
r_vec = np.array([4.0, -2.0])
v_hand = np.array([35.05, 29.54]) # analytic solution from above
v_iter = np.zeros(2)
two_state_errors = []
for sweep in range(300):
v_next = r_vec + gamma_2s * (P_opt @ v_iter)
two_state_errors.append(np.max(np.abs(v_next - v_iter)))
v_iter = v_next
if two_state_errors[-1] < 1e-10:
break
ref_line = two_state_errors[0] * gamma_2s ** np.arange(len(two_state_errors))
The iterates settle onto the exact fixed point computed by substitution, while the displayed hand values are rounded to and . With the stopping rule used here, the remaining numerical fixed-point error is on the order of ; the larger dotted offset against the two-decimal hand value is therefore rounding, not failed convergence. The error falls along the reference slope.
Three observations are worth drawing out. First, the value of a working machine, about 35, vastly exceeds any single-step reward, because it prices in the entire expected future stream. Value is a stock of future income, not a flow, and the discount factor determines the exchange rate between them. Second, the value gap is exact: . The immediate repair cost contributes 2, while the remaining term prices the repair transition against the working state's discounted future. Third, the same numbers would fall out of value iteration automatically: the algebra we did by hand is what the fixed-point iteration computes numerically. Starting from zeros, applying repeatedly converges to these same two numbers without ever forming a linear system explicitly. When a problem is too large to solve as a linear system, iterative methods take its place.