Karnaugh maps are a more formal way to approach minimization than looking for pairs to combine. Karnaugh maps rearrange a truth table so that assignments differing in only one variable are always adjacent. This is done in such a way that possible sub-terms using fewer variables appear as blocks of the same value (usually ones or true). Karnaugh maps are not particularly fast to use since they use the exponential space like a truth table but are useful when the structure of the function is unknown.
To arrange Karnaugh maps, we use Gray codes. An
-bit Gray code is
the sequence of all
-bit numbers with the property that each
pair of consecutive numbers differs in exactly one bit (this includes
wrapping the sequence too). Each Gray code is constructed from the
previous Gray code in the following fashion. Two copies of the
previous Gray code are made. The first one has a zero added to the
beginning of each number. The second one is reversed and has a one
added to the beginning of each number. These two sequences are then
concatenated together. For example,
| 1 bit | 0,1 |
| 2 bit | 00,01,11,10 |
| 3 bit | 000,001,011,010,110,111,101,100 |
| 4 bit | 0000,0001,0011,0010,0110,0111,0101,0100,1100,1101,1111,1110,1010,1011,1001,1000 |
The one and two bit Gray codes have the property mentioned
above - each number is adjacent to all the numbers differing in
exactly one bit. For a function with
inputs, we use an
-dimensional table for the
Karnaugh map. Moving along a dimension changes one or two
variables. For example,
| A,B=0,0 | A,B=0,1 | A,B=1,1 | A,B=1,0 | |
| C=0 | 0 | 0 | 1 | 0 |
| C=1 | 0 | 1 | 1 | 1 |
This is the Karnaugh map for the majority function. The sub-terms combined earlier are represented by adjacent bits. For example, the two bits set to one in the A,B=1,1 column represent the value of C not mattering once it is known that A is one and B is one.
Once the Karnaugh map is made (this is just a reordering of the truth table in a way), one looks for rectangular blocks with lengths of one, two, or four. A length of one corresponds to a sub-term using both variables. A length of two corresponds to the variable that changed along the row or column not mattering. A length of four corresponds to the two variables along that dimension not mattering. The remaining variables are used in the sub-term.
To generate a smaller DNF formula for a function, one repeatedly picks the largest block covering all ones which covers at least one more one than covered by the previous blocks. For example,
| A,B=0,0 | A,B=0,1 | A,B=1,1 | A,B=1,0 | |
| C,D=0,0 | 1 | 1 | 1 | 1 |
| C,D=0,1 | 1 | 1 | 1 | 1 |
| C,D=1,1 | 1 | 0 | 0 | 0 |
| C,D=1,0 | 1 | 0 | 0 | 1 |
The first block picked is for the sub-term
since
it covers eight ones. The next block is
since it covers four ones. The only uncovered one at this point is for
, but we use the term
since we are allowed to wrap blocks around the
edges.