The blocks world has two kinds of components:

- A table top with three
places
**p**,**q**, and**r** - A variable number of blocks
**A**,**B**,**C**, etc., that can be arranged in places on the table or stacked on one another

- The moved block must not have another block on top of it
- No other blocks are moved in the process

Here is a simple blocks world problem:

And here is its shortest solution:

A two-dimensional array may be appropriate (as in the 8-puzzle), however:
**Stacks** are a natural structure for piles of blocks.

- Unlike our previous problems, which had fixed elements, the blocks world has multiple problems with multiple numbers of blocks
- Different size arrays are required for problems with different numbers of blocks

This section discusses blocks world move representation and its effect
on the state space search space.

It is straightforward to think of a move in the blocks world as transferring
from one **place** (the source) to another **place** (the destination).
**doMove** method in the blocks world move class must
return **null** if there is no block on the source place.

So the name of the block is not necessary to uniquely specify a move.

The three moves used in the example (see to the left) are:

- Move block from
**p**to**r** - Move block from
**p**to**q** - Move block from
**r**to**q**

The number of move objects to create is dependent on the number of
places, but not on the number of blocks.

In general, if there are **n** places, there should be
**n*(n-1)** move objects.

In our blocks world there are 3 places and so 6 move objects.

Since a blocks world search tree node can expand to as many as 6 children while an 8-puzzle search tree node can expand to a maximum of 4, blocks problems can generate larger search spaces.

You will need to devise an informed **blocks world heuristic function**.

This section discusses heuristics for the blocks world.

We show a heuristic that significantly underestimates, and one that overestimates.

As with the 8-puzzle, a natural heuristic to consider is the **number of blocks
that are out of place** relative to the final state.

For example, in the current state below there are three blocks out of place (shown in red):

Since the actual number of moves required is five, this is not a poor estimate.

However, the heuristic is *naive* because it does not take into
account whether a block, even if it is in the correct place, has
correctly placed blocks under it, as some counterexamples show.

Consider this situation:

The number of blocks out of place is two, but the actual number of moves
required is at least ten — five to get place **p** clear and at
least five more to move blocks back into place.

So the heuristic *underestimates* considerably.

As a second example, consider:

The current state has only three blocks out of place but the number of moves required is 21.

You should implement the number-of-blocks-out-of-place heuristic for
testing purposes, but you should also come up with a more
informed heuristic that does not *over*estimate.

Note that the "sum of Manhattan distances" heuristic does overestimate for the blocks world problem. Suppose:

The "Manhattan distance" of **A** from its destination is six, but only one
move is required to get it there.

This section shows three simple two-block problems with the minimum
number of moves required to solve them (the **Heuristic Analysis Tool**
will be described at another time).

If your heuristic can distinguish these situations and make good estimates for them that don't overestimate, you should be on your way to solving more complex problems efficiently.

I have experimented with several blocks world heuristics:
**h**_{0}, resulting in
an **uninformed** breadth-first search), is shown in this section in
terms of the number of priority queue operations and the maximum
priority queue size.

- Number of blocks out of place (
**h**), which is_{1}**not very informed** - Number of blocks that must be moved (
**h**), which is_{2}**somewhat informed** - A heuristic that attempts to be
**very informed**(**h**)_{3}

You can compare your own heuristic's performance against these.

Problem | Solution Length |
Heuristic | Number of PQ Ops |
Maximum PQ Size |
---|---|---|---|---|

3 | h_{0} |
55 | 18 | |

5 | h_{0} |
349 | 158 | |

6 | h_{0} |
5,216 | 2,647 | |

8 | h_{0} |
14,050 | 7,071 | |

12 | h_{0} |
Out of memory (1,310,000 PQ ops) | ||

17 | h_{0} |
— | — | |

21 | h_{0} |
— | — |

Problem | Solution Length |
Heuristic | Number of PQ Ops |
Maximum PQ Size |
---|---|---|---|---|

3 | h_{0} |
55 | 18 | |

h_{1} |
17 | 8 | ||

5 | h_{0} |
349 | 158 | |

h_{1} |
60 | 29 | ||

6 | h_{0} |
5,216 | 2,647 | |

h_{1} |
135 | 74 | ||

8 | h_{0} |
14,050 | 7,071 | |

h_{1} |
490 | 253 | ||

12 | h_{0} |
Out of memory (1,310,000 PQ ops) | ||

h_{1} |
55,982 | 33,873 | ||

17 | h_{0} |
— | — | |

h_{1} |
913,121 | 562,042 | ||

21 | h_{0} |
— | — | |

h_{1} |
Out of memory (1,020,000 PQ ops) |

Problem | Solution Length |
Heuristic | Number of PQ Ops |
Maximum PQ Size |
---|---|---|---|---|

3 | h_{0} |
55 | 18 | |

h_{1} |
17 | 8 | ||

h_{2} |
17 | 8 | ||

5 | h_{0} |
349 | 158 | |

h_{1} |
60 | 29 | ||

h_{2} |
47 | 24 | ||

6 | h_{0} |
5,216 | 2,647 | |

h_{1} |
135 | 74 | ||

h_{2} |
108 | 57 | ||

8 | h_{0} |
14,050 | 7,071 | |

h_{1} |
490 | 253 | ||

h_{2} |
329 | 180 | ||

12 | h_{0} |
Out of memory (1,310,000 PQ ops) | ||

h_{1} |
55,982 | 33,873 | ||

h_{2} |
55,586 | 33,551 | ||

17 | h_{0} |
— | — | |

h_{1} |
913,121 | 562,042 | ||

h_{2} |
434,162 | 266,555 | ||

21 | h_{0} |
— | — | |

h_{1} |
Out of memory (1,020,000 PQ ops) | |||

h_{2} |
Out of memory (1,020,000 PQ ops) |

Problem | Solution Length |
Heuristic | Number of PQ Ops |
Maximum PQ Size |
---|---|---|---|---|

3 | h_{0} |
55 | 18 | |

h_{1} |
17 | 8 | ||

h_{2} |
17 | 8 | ||

h_{3} |
13 | 6 | ||

5 | h_{0} |
349 | 158 | |

h_{1} |
60 | 29 | ||

h_{2} |
47 | 24 | ||

h_{3} |
28 | 13 | ||

6 | h_{0} |
5,216 | 2,647 | |

h_{1} |
135 | 74 | ||

h_{2} |
108 | 57 | ||

h_{3} |
36 | 17 | ||

8 | h_{0} |
14,050 | 7,071 | |

h_{1} |
490 | 253 | ||

h_{2} |
329 | 180 | ||

h_{3} |
213 | 108 | ||

12 | h_{0} |
Out of memory (1,310,000 PQ ops) | ||

h_{1} |
55,982 | 33,873 | ||

h_{2} |
55,586 | 33,551 | ||

h_{3} |
511 | 294 | ||

17 | h_{0} |
— | — | |

h_{1} |
913,121 | 562,042 | ||

h_{2} |
434,162 | 266,555 | ||

h_{3} |
988 | 531 | ||

21 | h_{0} |
— | — | |

h_{1} |
Out of memory (1,020,000 PQ ops) | |||

h_{2} |
Out of memory (1,020,000 PQ ops) | |||

h_{3} |
71,368 | 33,889 |