Data Structures and Algorithms

Slides:



Advertisements
Similar presentations
BackTracking Algorithms
Advertisements

 Chapter 7 introduces the stack data type.  Several example applications of stacks are given in that chapter.  This presentation shows another use called.
Stacks CS 3358 – Data Structures. What is a stack? It is an ordered group of homogeneous items of elements. Elements are added to and removed from the.
Announcements Assignment #4 is due tonight. Last lab program is going to be assigned this Wednesday. ◦ A backtracking problem.
B ACKTRACK SEARCH ALGORITHM. B ACKTRACKING Suppose you have to make a series of decisions, among various choices, where You don’t have enough information.
P Chapter 6 introduces the stack data type. p Several example applications of stacks are given in that chapter. p This presentation shows another use called.
The N-Queens Problem lab01.
Backtracking COP Backtracking  Backtracking is a technique used to solve problems with a large search space, by systematically trying and eliminating.
CS420 lecture ten BACKTRACK. Solution vectors In optimization problems, or more general in search problems, a set of choices are to be made to arrive.
CSC212 Data Structure - Section FG Lecture 12 Stacks and Queues Instructor: Zhigang Zhu Department of Computer Science City College of New York.
Algorithms & Data Structures for Games
Backtracking.
Dr. Jouhaina Chaouachi Siala
Lecture 5: Backtracking Depth-First Search N-Queens Problem Hamiltonian Circuits.
CSE 143 Lecture 17 More Recursive Backtracking reading: "Appendix R" on course web site slides created by Marty Stepp and Hélène Martin
Back Tracking Project Due August 11, 1999 N-queens: –A classic puzzle for chess buffs is the N- Queens problem. Simply stated: is it possible to place.
HISTORY The problem was originally proposed in 1848 by the chess player Max Bezzel, and over the years, many mathematicians, including Gauss have worked.
NxN Queens Problem Q- -- -Q Q- -- -Q Q- -- QQ -- Q- Q- Q- -Q QQ -- -Q -- -Q Q- -Q -Q Q- Q- -Q Q- -- Q- -- QQ Q- -Q -Q -Q -- QQ -- -Q START.
CSE 143 Lecture 17 More Recursive Backtracking reading: "Appendix R" on course web site slides created by Marty Stepp and Hélène Martin
Contents of Chapter 7 Chapter 7 Backtracking 7.1 The General method
Announcements This Wednesday, Class and Labs are cancelled! The last lab is due this Wednesday … how many people are planning on doing it? Finally posted.
Data Structures Using C++ 2E1 Recursion and Backtracking: DFS Depth first search (a way to traverse a tree or graph) Backtracking can be regarded as a.
Two Dimensional Arrays. Two-dimensional Arrays Declaration: int matrix[4][11]; 4 x 11 rows columns
The "8 Queens" problem Consider the problem of trying to place 8 queens on a chess board such that no queen can attack another queen. What are the "choices"?
Algorithms April-May 2013 Dr. Youn-Hee Han The Project for the Establishing the Korea ㅡ Vietnam College of Technology in Bac Giang.
CSE 143 Lecture 18 More Recursive Backtracking slides created by Marty Stepp
Backtracking & Brute Force Optimization Intro2CS – weeks
CSE 143 Lecture 13 Recursive Backtracking slides created by Ethan Apter
© 2006 Pearson Addison-Wesley. All rights reserved 6-1 Chapter 6 Recursion as a Problem- Solving Technique.
Analysis & Design of Algorithms (CSCE 321)
February 11, 2016Introduction to Artificial Intelligence Lecture 6: Search in State Spaces II 1 State-Space Graphs There are various methods for searching.
Backtracking. 2 Suppose you have to make a series of decisions, among various choices, where You don’t have enough information to know what to choose.
CSE 143 read: 12.5 Lecture 18: recursive backtracking.
Unit – 5: Backtracking For detail discussion, students are advised to refer the class discussion.
1 Tirgul 11: Recursion & Backtracking. 2 Elements of a recursive solution (Reminder) A base case that is so simple we need no computation to solve it.
 Chapter 7 introduces the stack data type.  Several example applications of stacks are given in that chapter.  This presentation shows another use called.
CSG3F3/ Desain dan Analisis Algoritma
ADT Stack What Is a Stack? Standard Template Library Stack Class
Backtracking.
BackTracking CS255.
Depth-First Search N-Queens Problem Hamiltonian Circuits
Intro to Computer Science II
CSCI 104 Backtracking Search
Backtracking And Branch And Bound
Fundamentals of Programming II Backtracking with Stacks
Sit-In Lab 1 Ob-CHESS-ion
The "8 Queens" problem Consider the problem of trying to place 8 queens on a chess board such that no queen can attack another queen. What are the "choices"?
CSE 143 Lecture 19 More Recursive Backtracking
Using a Stack Chapter 6 introduces the stack data type.
Recursion Copyright (c) Pearson All rights reserved.
Analysis and design of algorithm
Using a Stack Chapter 6 introduces the stack data type.
CSS 342 Data Structures, Algorithms, and Discrete Mathematics I
Exercise: Dice roll sum
Stacks.
adapted from Recursive Backtracking by Mike Scott, UT Austin
Using a Stack Chapter 6 introduces the stack data type.
Haskell Tips You can turn any function that takes two inputs into an infix operator: mod 7 3 is the same as 7 `mod` 3 takeWhile returns all initial.
Using a Stack Chapter 6 introduces the stack data type.
Backtracking.
Exercise: Dice roll sum Write a method diceSum similar to diceRoll, but it also accepts a desired sum and prints only arrangements that add up to.
Exercise: Dice roll sum
Backtracking.
CSE 143 Lecture 18 More Recursive Backtracking
CSE 143 Lecture 18 More Recursive Backtracking
Exercise: Dice roll sum
The "8 Queens" problem Consider the problem of trying to place 8 queens on a chess board such that no queen can attack another queen. What are the "choices"?
Tree A tree is a data structure in which each node is comprised of some data as well as node pointers to child nodes
Announcements Assignment #4 is due tonight. Last lab program is going to be assigned this Wednesday. ◦ A backtracking problem.
Backtracking.
Presentation transcript:

Data Structures and Algorithms Backtracking CENG 707 Data Structures and Algorithms Yusuf Sahillioğlu 1

Backtracking Stacks and trees can be utilized to solve problems such as crosswords, Sudoku, 8-queens puzzle, and many other puzzles

Backtracking Stacks and trees can be utilized to solve problems such as crosswords, Sudoku, 8-queens puzzle, and many other puzzles You are faced w/ a set of options, one of which must be chosen After you make the choice, you get a new set accordingly Repeat until you reach a final state If your choices were good, your final state is a goal state Else, it is not a goal state

Backtracking Stacks and trees can be utilized to solve problems such as crosswords, Sudoku, 8-queens puzzle, and many other puzzles In other words, Each choice (tree children) is recorded (in a stack) When you run out of choices for the current decision, you pop the stack, and continue trying different choices for the previous decision

Backtracking Conceptually you start at the root of a tree Tree has some good some bad leaves (all may be good/bad) You want to get to a good leaf At each node, beginning w/ root, you choose one of its children to move to, and repeat ‘till you get to a leaf Suppose you get to a bad leaf Do backtrack to continue the search for a good leaf by canceling your most recent choice (pop stack) and trying out the next option in that set of options Recursion or stack If you end up at the root w/ no options left, no good leaf 

Backtracking Starting at Root, your options are A and B. You choose A. At A, your options are C and D. You choose C. C is bad. Go back to A. At A, you have already tried C, and it failed. Try D. D is bad. Go back to A. At A, you have no options left to try. Go back to Root. At Root, you have already tried A. Try B. At B, your options are E and F. Try E. E is good. Congratulations!

Backtracking Generic backtracking algorithm w/ recursion boolean solve(Node n) { if n is a leaf node { if the leaf is a goal node, return true else return false } else { for each child c of n if solve(c) succeeds, return true return false }

Backtracking Generic backtracking algorithm w/o recursion (w/ stacks) boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false

Backtracking Example puzzle: Balls on the move n black balls, n white balls, 2n+1 spaces, middle empty Represent the board as an array for the coding: 1,1,-1,2,2 (left) Blacks/whites can only move to right/left, no backing up A ball can move 1 space ahead, if clear Jump over 1 opposite-color ball, if clear

Backtracking Example puzzle: Balls on the move A stuck/bad leaf

Backtracking Example puzzle: Balls on the move Each move will yield new boards, which become the children of the current board After some observation on ball movements bool canMove(int[] board, int idx) If idx is empty, no move possible (return false) If idx contains a black ball, check for a valid move to go right If idx contains a white ball, check for a valid move to go left

Backtracking Example puzzle: Balls on the move Each move will yield new boards, which become the children of the current board After some observation on ball movements int[] makeMove(int[] oldBoard, int idx) Make a move from idx on oldBoard and return the new board

Backtracking Example puzzle: Balls on the move Resulting recursive code boolean solvable(int[] board) { if (puzzleSolved(board)) { return true; } for (int position = 0; position < BOARD_SIZE; position++) { if (canMove(board, position)) { int[] newBoard = makeMove(board, position); if (solvable(newBoard)) { printBoard(newBoard); return false;}

Backtracking Example puzzle: Balls on the move Output of the recursive code (notice the reverse order)

Backtracking Example puzzle: Balls on the move Resulting non-recursive code boolean solvable(int[] board) { //This is part of your homework # 2; see the next slides for help }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack M is a good leaf  boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking Let’s see the execution trace along with the Stack Assume M was a bad leaf backtrace ‘till G (most recent unmarked node) G pushes O and N, which later push P and R boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false }

Backtracking N-queen problem: safely place N queens on an NxN chessboard Safe: no 2 queens on the same row, same column, same diagonal N=8 case for the ordinary chessboard:

Backtracking bool isSafe(int i, int j) //return True if Q can be placed at row i, col j //x[i] global array w/ first i-1 entries set already: x[a]=b //means that for row a, Q is safely sitting at col b for k = 1 to i-1 //check rows if (x[k] == j OR //same column |k-i| == |x[k]-j| //same diagonal (deltaX=deltaY, slope=1) return False return True (i,j) (k,l) Same diagonal since |i-k|=|j-l|

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 : remaining j’s for this i

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 : remaining j’s for this i

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 : remaining j’s for this i no safe column

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 : remaining j’s for this i remaining j suggested a new safe place, and ..

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 : remaining j’s for this i remaining j suggested a new safe place, and called i=3 again

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 i=4 no safe column

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 i=4 i=3 no safe column

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 i=4 i=3 i=2 no remaining left

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 i=4 i=3 i=2 i=1 next safe cell

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 i=4 i=3 i=2 i=1 i=2

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 i=4 i=3 i=2 i=1 i=3

Backtracking void NQueens(int i, int n) //initial call’ll be NQueens(1, N) for j = 1 to n //check columns if (isSafe(i, j)) x[i] = j if (i == n) printResult(x); //done! else NQueens(i+1, n) i=1 i=2 i=3 i=2 i=3 i=4 i=3 i=2 i=1 i=4 printResult()

Backtracking Let’s see the execution trace along with the Stack Recall the generic algorithm boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false

Backtracking Let’s see the execution trace along with the Stack bad because I cannot do the next row boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false

Backtracking Let’s see the execution trace along with the Stack (cont’d) boolean solve(Node n) { push node n on the stack S; while S is not empty { if S.top() node is a leaf { if it is a goal node, return true else pop it off S } else if S.top() node is unmarked { Mark S.top() node for each child c of S.top() node push c to S else //not a leaf and marked (we are backing out) pop it off S return false

Backtracking Tree is just for visualization; you don’t have to use Tree in code Algorithm with a Stack is as follow F=1 //# of filled rows F=2

Backtracking Tree is just for visualization; you don’t have to use Tree in code Algorithm with a Stack is as follow F=2 //pop; F--; found 2,4; F++ //(continue from where you left off: 2,3) F=3

Backtracking Tree is just for visualization; you don’t have to use Tree in code Algorithm with a Stack is as follow F=1 //pop; F--; try 3,3 and 3,4 in r3; unsafe //pop; F--; no where to try in row2; //pop; F--; found 1,2 in row1; F++; F=2

Backtracking Tree is just for visualization; you don’t have to use Tree in code Algorithm with a Stack is as follow F=3 F=4; F reached N (4x4 board); finish

Backtracking Tree is just for visualization; you don’t have to use Tree in code Notice how similar this execution trace to our Tree visualization F=4; F reached N (4x4 board); finish