View page as slide show

Click presentation screen icon to the right to see the slide show.

6. Recursion as a Problem-Solving Technique

  • backtracking - guess at a solution, then back up and try again
  • formal grammars

6.1 Bracktracking

How do you find your way to downtown Fort Collins?

6.1 Bracktracking

How do you find your way to downtown Fort Collins?

Start out in general direction. You will know when you have found it.

What do you do if you hit a dead end road, or you find yourself in La Porte?

6.1 Bracktracking

How do you find your way to downtown Fort Collins?

Start out in general direction. You will know when you have found it.

What do you do if you hit a dead end road, or you find yourself in La Porte?

Right. Go back a few blocks and make a different decision.

Continue like this until you find downtown.

That's “backtracking”.

The Eight Queens Problem

On a chess board, Queens attack along diagonals, rows, and columns.

The Eight Queens Problem is to place eight queens on the board so that no queen is attacking another.

Each queen must be in a column. Thank goodness a chess board has eight columns.

Now what?

The Eight Queens Problem

On a chess board, Queens attack along diagonals, rows, and columns.

The Eight Queens Problem is to place eight queens on the board so that no queen is attacking another.

Each queen must be in a column. Thank goodness a chess board has eight columns.

Now what?

Must figure out which row in which to place each queen.

If we place the first queen in row 1, how many rows are left for the other seven queens?

The Eight Queens Problem

On a chess board, Queens attack along diagonals, rows, and columns.

The Eight Queens Problem is to place eight queens on the board so that no queen is attacking another.

Each queen must be in a column. Thank goodness a chess board has eight columns.

Now what?

Must figure out which row in which to place each queen.

If we place the first queen in row 1, how many rows are left for the other seven queens?

Yes….seven, so put the second queen in row 2.

The Eight Queens Problem

If we place the first queen in row 1, how many rows are left for the other seven queens?

Yes….seven, so put the second queen in row 2.

Oops. Yep. First and second queen attack each other along diagonal, so put second queen in third row.

Can keep going this way, or just punt.

The Eight Queens Problem

If we place the first queen in row 1, how many rows are left for the other seven queens?

Yes….seven, so put the second queen in row 2.

Oops. Yep. First and second queen attack each other along diagonal, so put second queen in third row.

Can keep going this way, or just punt.

There are 8 rows to choose for the first queen, 7 for the second, 6 for the third, …..

So, possible row assignments. Is that too big to think about?

The Eight Queens Problem

If we place the first queen in row 1, how many rows are left for the other seven queens?

Yes….seven, so put the second queen in row 2.

Oops. Yep. First and second queen attack each other along diagonal, so put second queen in third row.

Can keep going this way, or just punt.

There are 8 rows to choose for the first queen, 7 for the second, 6 for the third, …..

So, possible row assignments. Is that too big to think about?

. Maybe we can succeed by trying some row assignments, then varying some decisions when we hit a dead end.

Backtracking!

The Eight Queens Problem

The backtracking step:

  • If you cannot find a valid row in the current column, , then forget all of your effort in column and try the next valid row for the queen in column .

At least three ways to go back to column

  1. Subtract 1
  2. Use stack to keep track of columns already worked on.
  3. Use recursive calls to work on next column, and return to go back to previous column.

The third choice may be most intuitive.

The Eight Queens Problem

Use recursive calls to work on next column, and return to go back to previous column.

Basic idea:

public class EightQueens {
 
   protected int[] rows;
 
   public EightQueens() {
      rows = new int[8];
   }
 
   public boolean placeQueens(int column) {
 
      // Base case
      if (column > 8)
         return true;  // YIPPEE    
 
      // Try each row sequentially, for current column.
 
      for (int row = 1; row <= 8; row++) {
 
         rows[column-1] = row;          // Remember which row used in current column.
 
         if (!attacked(row,column) &&   // Check for attack from previously placed queens.
                placeQueens(column+1))  // Recursive call, one fewer columns
            return true;
      }
      return false;
   }

The Eight Queens Problem

How would you code the attacked method?

   public boolean attacked(int row,int column) {
    .
    .
    .
   }

The Eight Queens Problem

How would you code the attacked method?

   public boolean attacked(int row,int column) {
    .
    .
    .
   }

Don't need to check for same column, since we are assigning to different columns sequentially.

The Eight Queens Problem

Must examine queen placements in each of the previous columns.

   public boolean attacked(int row,int column){
      for (int c = 0; c < column-1; c++) {
        .
        .
        .
   }

The Eight Queens Problem

Must examine queen placements in each of the previous columns.

Check for same row.

   public boolean attacked(int row,int column){
      for (int c = 0; c < column-1; c++) {
 
          if (rows[c] == row)
             return true;
        .
        .
        .
   }

Now for the diagonals. How?

The Eight Queens Problem

Now for the diagonals. How?

   public boolean attacked(int row,int column){
      for (int c = 0; c < column-1; c++) {
 
          if (rows[c] == row)
             return true;
 
          if (Math.abs(rows[c] - row) == Math.abs(c+1-column))
             return true;
      }                    
        .
        .
        .
   }

The Eight Queens Problem

Now for the diagonals. How?

   public boolean attacked(int row,int column){
      for (int c = 0; c < column-1; c++) {
 
          if (rows[c] == row)
             return true;
 
          if (Math.abs(rows[c] - row) == Math.abs(c+1-column))
             return true;
      }                    
        .
        .
        .
   }

And what if we drop out of bottom of for loop?

The Eight Queens Problem

And what if we drop out of bottom of for loop?

   public boolean attacked(int row,int column){
      for (int c = 0; c < column-1; c++) {
 
          if (rows[c] == row)
             return true;
 
          if (Math.abs(rows[c] - row) == Math.abs(c+1-column))
             return true;
      }                    
 
      return false;
   }

Don't forget to

import java.lang.Math;

(The compiler won't let you forget!)

The Eight Queens Problem

One more bit of code for fun. How do we print a chess board with the queens placed?

The Eight Queens Problem

One more bit of code for fun. How do we print a chess board with the queens placed?

   public String toString() {
      String oneRow = "--------\n";
      StringBuffer board = new StringBuffer(oneRow + oneRow + oneRow + oneRow + 
                                            oneRow + oneRow + oneRow + oneRow);
      for (int i = 0; i < 8; i++) {
         if (rows[i] > 0)
            board.setCharAt((rows[i]-1)*9 + i, 'Q');
      }
      return new String(board);
   }

The Eight Queens Problem

Now, a main to try it all out.

   public static void main(String [] args) {
 
      EightQueens q = new EightQueens();
      boolean result = q.placeQueens(1);
      if (result)
         System.out.println("Success");
      else
         System.out.println("Failure");
 
      System.out.println(q);
   }

And, ta-da, we get

Success
Q-------
------Q-
----Q---
-------Q
-Q------
---Q----
-----Q--
--Q-----
Recent changes RSS feed CC Attribution-Share Alike 3.0 Unported Driven by DokuWiki