Skip to content

3.3 Hands-on: Value Iteration and Q-Learning

Section goal: Run value iteration and Q-Learning in the same 4×4 GridWorld, observe how the goal reward reaches the starting state, and compare how the two algorithms obtain information.

Learning path: 3.1 State Values and the Bellman Expectation Equation3.2 Action Values and the Bellman Optimality Equation3.3 Value Iteration and Q-Learning

Code and resources: experiment script · GridWorld diagram · value iteration diagram · Q-Learning curves

3.3.1 Running the GridWorld Experiment

3.1 and 3.2 introduced state values, action values, and Bellman equations. We will now pause the introduction of new equations and place the Bellman optimality equation into a complete small experiment. This allows us to observe a value table as it starts from all zeros and is repeatedly updated until it stabilizes.

The task has only 16 states. The agent starts in the upper-left corner at and must reach in the lower-right corner; is a trap. At each step, the agent can move up, down, left, or right. If it hits a wall, its position does not change.

A 4×4 GridWorld with starting state S in the upper-left corner, trap X at coordinate (1,1), and goal G in the lower-right corner
Figure 3-3: Value iteration and Q-Learning use the same 4×4 GridWorld.

This experiment depends only on the Python standard library and completes within a few seconds on an ordinary computer. Run the following command from the repository root:

bash
python3 code/chapter03_mdp/gridworld_q_learning.py \
  --output-dir output/value-experiment

The script first gives value iteration access to the complete grid rules and repeatedly updates every state. It then lets Q-Learning start from the initial state and update its Q-table using only the experience it actually encounters. After the run, examine three results: how many sweeps value iteration takes to converge, how many sweeps the goal reward takes to reach the starting state, and whether Q-Learning finds the six-step shortest path after exploration is disabled.

3.3.2 Rewards in GridWorld

Entering the goal gives a reward of , while entering the trap gives a reward of ; both events end the current episode. Every other step gives a reward of . This small negative reward encourages the agent to reach the goal quickly: among successful routes, a six-step route produces a higher return than an eight-step route. We set the discount factor to .

First, calculate the shortest distance. The row coordinates of the starting state and goal differ by 3, as do their column coordinates, so the agent needs at least

steps.

The trap blocks some routes but does not block every six-step path. The agent can move right three times along the upper boundary and then down three times to reach the goal without encountering the trap. We therefore have an initial criterion for checking the result: if the learned route takes more than six steps, the algorithm has not yet found a shortest path.

Terminal Rewards Are Computed Upon Entry

Before updating the value table, consider the cell immediately to the left of the goal. From this cell, one step to the right enters the goal and gives a reward of :

The episode has ended, so no further actions or rewards follow the goal. The return for moving right from is therefore 1:

Written as a Bellman update,

where . This zero means that no further return is produced after entering the goal; the goal reward has already been counted on the transition into .

The trap is handled in the same way. The transition into gives a reward of , after which the episode ends, so .

The code returns the reward and termination flag in this temporal order:

python
def transition(state, action):
    if state in TERMINALS:
        return state, 0.0, True

    next_state = move_or_stay(state, action)
    if next_state == GOAL:
        return next_state, 1.0, True
    if next_state == TRAP:
        return next_state, -1.0, True
    return next_state, -0.01, False

Both value iteration and Q-Learning call this transition function, so they solve the same task.

3.3.3 Value Iteration: Reading the Environment Rules

Value iteration applies when the environment rules are known. Here, "known rules" means that for any cell and any action, we can determine the next cell, the reward, and whether the episode ends.

The algorithm first sets the value of every cell to 0:

How Far One Sweep Can Propagate Information

Next, the algorithm computes a new value table. For each nonterminal cell, it calculates the values of the four actions—up, down, left, and right—and retains the largest:

Here, is the old table before the update, and is the new table produced by this sweep. Computing the entire new table using only the preceding old table is called a synchronous update.

Consider the first sweep. From , one step to the right enters the goal, giving

The cell above the goal can also enter it in one step, so its value is also 1.

Now consider , which is two steps from the goal. Although the cell immediately to its right is , whose value was just computed, the first sweep can read only the old table, where is still 0:

Only in the second sweep can read from the new table:

These two cells illustrate value propagation. The first sweep updates cells one step from the goal, and the second sweep then affects cells two steps away. One synchronous update can propagate the goal reward outward by only one layer.

The implementation performs the same computation. values stores , while updated stores the currently being computed:

python
values = {state: 0.0 for state in all_states()}

for sweep in range(1000):
    updated = values.copy()
    for state in all_states():
        if state not in TERMINALS:
            updated[state] = max(
                reward if done else reward + GAMMA * values[next_state]
                for action in range(4)
                for next_state, reward, done in [transition(state, action)]
            )
    values = updated

The following figure shows the value tables after sweeps 0, 1, 3, and 6. Begin with the darker blue cells: they appear near the goal and spread gradually toward the upper-left corner as the number of updates increases. In , only the two cells adjacent to the goal have positive values. The goal reward reaches the starting state along a six-step path only in .

GridWorld value tables after value-iteration sweeps 0, 1, 3, and 6, followed by the converged values and optimal policy
Figure 3-4: Synchronous value iteration. Each sweep uses the complete value table from the preceding sweep.

Reading a Policy from the Value Table

After the sixth sweep, the value table no longer changes. The program computes one more sweep, finds that every cell retains the same value, and stops after sweep 7. This state is called convergence.

The final result is

Row / column0123
00.7290.7770.8290.883
10.7770.000 (trap)0.8830.940
20.8290.8830.9401.000
30.8830.9401.0000.000 (goal)

Now check the value of the starting state. Along a shortest path, each of the first five steps gives , and the final step enters the goal and gives . Discounting these six rewards in order gives

The result is approximately 0.729, matching the value in the upper-left corner of the table. Thus, the starting-state value computed by the program can be verified directly from a concrete shortest path.

Multiple arrows in the figure indicate that a cell has more than one optimal action. From the starting state, for example, moving right first or moving down first can both avoid the trap and reach the goal within six steps.

3.3.4 Q-Learning: Learning from Interaction

Whenever value iteration updates a cell, it can query the results of all four actions directly. Q-Learning does not have this information. It does not know where an action will lead, so it must start at the initial state, select an action, and observe the reward and next state .

After one step, we obtain an experience tuple : from state , the agent takes action , receives reward , and enters state . Q-Learning uses this experience to update one Q-value:

The first part inside the brackets,

is called the TD target. It combines the reward already received on this step with the currently estimated best value of the next state. The learning rate determines how far the current update moves toward the TD target.

If is the goal or trap, the episode has ended, so the next-state value is 0:

python
next_state, reward, done = transition(state, action)
next_best = 0.0 if done else max(Q[next_state])
td_target = reward + gamma * next_best
Q[state][action] += alpha * (td_target - Q[state][action])

The distinction between the two algorithms is now clear. One sweep of value iteration visits every nonterminal state and compares all four actions in each state. One Q-Learning update uses only the single transition just experienced. Q-Learning must run many episodes before the different state–action pairs have all been updated.

How the Exploration Rate Affects Training Return

At the start of training, every entry in the Q-table is 0, so the agent does not yet know which direction to take. If it always selects an action with the largest current Q-value, many untried routes may never be updated. We therefore use an -greedy policy: with probability , the agent selects a random action; with probability , it selects an action with the largest current Q-value.

The experiment uses a learning rate of and trains for 500 episodes. To prevent one random run from being unusually good or bad by chance, each setting is run independently with 30 different random seeds.

To plot the curves, we first average the reward at each episode across the 30 runs and then compute a 20-episode moving average. This preserves the overall trend while reducing fluctuations caused by individual random runs.

We compare three -greedy settings:

  • decreases linearly from to ;
  • fixed ;
  • fixed .
Q-Learning training curves across multiple random seeds under three exploration-rate settings
Figure 3-5: Training returns under different exploration rates. Each curve aggregates 30 random seeds.
Exploration-rate settingMean reward over final 100 episodesSuccess rate without explorationMean path length
0.803100%6.0 steps
Fixed 0.900100%6.0 steps
Fixed 0.563100%6.0 steps

With fixed , each step still has a 30% probability of selecting a random action. Even after the Q-table has been learned, the agent may take detours or enter the trap during training, so the curve remains at a lower level. This does not necessarily mean that the Q-table has failed to learn a shortest path; exploratory actions may simply have reduced the score in the current episode.

To inspect the learned policy separately, we set after training. The agent then stops exploring randomly and always selects an action with the largest Q-value. All three settings reach the goal in six steps, with an undiscounted episode reward of

The training curve records the rewards obtained while the agent is both exploring and acting. Testing with exploration disabled always selects an action with the largest Q-value and therefore evaluates the final policy represented by the Q-table.

A fixed lowers the training return. In this small environment and under the current training budget, all three settings nevertheless learn a shortest path of the same length.

Section Summary

  • Value iteration uses a complete environment model and updates every state synchronously. In this section's GridWorld, the goal reward reaches the starting state after six update sweeps.
  • No future return follows a terminal state. The terminal reward is received upon entering the goal or trap, and the value of the terminal state is set to 0.
  • Q-Learning does not require an environment model. Each interaction produces one transition sample and updates the Q-value of one state–action pair.
  • Exploratory actions during training affect episode rewards. Setting to 0 for evaluation reveals the greedy policy represented by the Q-table.

The next section, Dynamic Programming, Monte Carlo, and Temporal Difference, begins with this distinction and compares three update methods: complete sweeps, full-episode sampling, and one-step bootstrapping.

Hands-on Modern Reinforcement Learning