Professional Documents
Culture Documents
Coloring a map
You wish to color a map with not more than four colors red, yellow, green, blue Adjacent countries must be in different colors
Solving a maze
Given a maze, find a path from start to finish At each intersection, you have to decide between three or fewer choices:
Outline
Introduction to Backtracking Method The General method The 8-queens Problem Sum of Subsets
Backtracking
Suppose you have to make a series of decisions, among various choices, where
You dont have enough information to know what to choose Each decision leads to a new set of choices Some sequence of choices (possibly more than one) may be a solution to your problem
Backtracking is a methodical way of trying out various sequences of decisions, until you find one that works
5
The Idea
Problem solving: search in a space of possible states.
Target state1
Initial state
Target state2
Backtracking
dead end ? dead end start ? ? ? success! ? dead end dead end dead end
A given problem has a set of constraints and possibly an objective function The solution optimizes an objective function, and/or is feasible. We can represent the solution space for the problem using a state space tree
The root of the tree represents 0 choices, Nodes at depth 1 represent first choice Nodes at depth 2 represent the second choice, etc. In this tree a path from a root to a leaf represents a candidate solution
Terminology I
A tree is composed of nodes
There are three kinds of nodes: The (one) root node Internal nodes Leaf nodes Backtracking can be thought of as searching a tree for a particular goal leaf node
10
Terminology II
Each non-leaf node in a tree is a parent of one or more other nodes (its children) Each node in the tree, other than the root, has exactly one parent
parent Usually, however, we draw our trees downward, with the root at the top children children
11
parent
Backtracking is really quite simple--we explore each node, as follows: To explore node N:
1. If N is a goal node, return success 2. If N is a leaf node, return failure 3. For each child C of N, 3.1. Explore C 3.1.1. If C was successful, return success 4. Return failure
12
General Method
Backtracking
Requires less than m trials to determine the solution. Form a solution (partial vector) and check at every step if this has any chance of success. If the solution at any point seems non-promising, ignore it. If the partial vector (x1, x2, . . . , xi) does not yield an optimal solution, ignore mi+1 mn possible test vectors even without looking at them.
All the solutions require a set of constraints divided into two categories: explicit and implicit constraints
13
Definition 1
Explicit constraints are rules that restrict each xi to take on values only from a given set. Explicit constraints depend on the particular instance I of problem being solved. All tuples that satisfy the explicit constraints define a possible solution space for I.
14
Definition 2: Implicit constraints are rules that determine which of the tuples in the solution space of I satisfy the criterion function.
Implicit constraints describe the way in which the xi s must relate to each other. Determine problem solution by systematically searching the solution space for the given problem instance. Use a tree organization for solution space.
15
Backtracking Concept
Backtracking is a systematic way to go through all the possible configurations of a search space. In the general case, we assume our solution is a vector: a = (a[1], a[2], , a[n]) where each element a[i] is selected from a finite ordered set S[i].
16
Backtracking Concept
We build a partial solution of length k a = (a[1], a[2], , a[k]) and try to extend it by adding another element. After extending it, we will test whether what we have so far is still possible as a partial solution.
17
Backtracking Concept
If it is still a candidate solution, great!
If not, we delete a[k] and try the next element from S[k].
18
Backtracking
Construct the state space tree: Root represents an initial state Nodes reflect specific choices made for a solutions components. Promising and nonpromising nodes Leaves Explore the state space tree using depth-first search Prune non-promising nodes DFS stops exploring subtree rooted at nodes leading to no solutions and... backtracks to its parent node
19
20
21
22
23
24
25
N columns
ro ws N
26
27
28
ROW 1, COL 1
29
ROW 1, COL 1
filled
30
filled
31
filled
32
filled
33
filled
34
filled
35
filled
36
filled
37
filled
38
filled
39
filled
40
filled
41
filled
42
filled
43
filled
44
Conflict occurs
filled
45
filled
46
filled
47
filled
48
filled
49
filled
50
filled
51
filled
52
ROW 1, COL 1
filled
53
filled
54
ROW 1, COL2
filled
55
filled
56
filled
57
filled
58
filled
59
filled
60
filled
61
filled
62
filled
63
filled
64
Initialize a stack where we can keep track of our decisions. Place the first queen, pushing its position onto the stack and setting filled to 0. repeat these steps if there are no conflicts with the queens... else if there is a conflict and there is room to shift the current queen rightward... else if there is a conflict and there is no room to shift the current queen rightward...
65
Increase filled by 1. If filled is now N, then the algorithm is done. Otherwise, move to the next row and place a queen in the first column.
66
repeat these steps if there are no conflicts with the queens... else if there is a conflict and there is room to shift the current queen rightward...
Move the current queen rightward, adjusting the record on top of the stack to indicate the new position.
67
repeat these steps if there are no conflicts with the queens... else if there is a conflict and there is room to shift the current queen rightward... else if there is a conflict and there is no room to shift the current queen rightward...
Backtrack! Keep popping the stack, and reducing filled by 1, until you reach a row where the queen can be shifted rightward. Shift this queen right.
68
Stacks have many applications. The application shown above is called backtracking. The key to backtracking: Each choice 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.
69
A solution
Not a solution
70
No queen can reside in a row or a column that contains another queen Now: only 40,320 (8!) arrangements of queens to be checked for attacks along diagonals
71
72
Base case If there are no more columns to consider You are finished Recursive step If you successfully place a queen in the current column Consider the next column If you cannot place a queen in the current column You need to backtrack
73
void placeQueen() // Recursive method which tries to place queen k in row k. { if (k == n) // All queens have been placed. { h++; if (h <= hmax) printSolution(); } else for (int i = 0; i < n; i++) if (coln[i] && main[i - k + n - 1] && anti[i + k]) // Place queen k at position i of row k. { pstn[k] = i; coln[i] = main[i - k + n - 1] = anti[i + k] = false; k++; placeQueen(); k--; coln[i] = main[i - k + n - 1] = anti[i + k] = true; }
74
Analysis
Here coln[], main[] and anti[] are boolean arrays which have been initialized with all positions equal to true. They are used to mark occupied columns, diagonals and antidiagonals, respectively.
The time consumption of the program is O(n * c(n)) where c(n) gives the number of calls to the method placeQueen().
75
For a given call, the state of the board from previous placements is known (i.e. where are the other queens?)
76
78
Comments
Backtracking provides the hope to solve some problem instances of nontrivial sizes by pruning non-promising branches of the state-space tree. The success of backtracking varies from problem to problem and from instance to instance. Backtracking possibly generates all possible candidates in an exponentially growing state-space tree. 79
Sum of subsets
Problem: Given n positive integers w1, ... wn and a positive integer S. Find all subsets of w1, ...
wn that sum to S.
Example: Given n=3, S=6, and w1=2, w2=4, w3=6 Solutions: {2,4} and {6}
80
Sum of subsets
We will assume a binary state space tree. The nodes at depth 1 are for including item 1, the nodes at depth 2 are for item 2, etc. The left branch includes wi, and the right branch excludes wi. The nodes contain the sum of the weights included so far.
81
w1 = 2, w2 = 4, w3 = 6 and S = 6
with 2
without 2
i1
with 4
2
without 4
with 4
0
without 4
i2
with 6
6
without 6 with 6
2
without 6
with 6
4
without 6
with 6
0
without 6
i3
12
10
w1 = 2, w2 = 4, w3 = 6 and S = 6
1
i1
1
2
0
1
0
0
i2
1
6
0
1
2
0
1
4
0
1
0
0
i3
12
10
Problems can be solved using depth first search of the (implicit) state space tree. Each node will save its depth and its (possibly partial) current solution DFS can check whether node v is a leaf.
If it is a leaf then check if the current solution satisfies the constraints Code can be added to find the optimal solution
84
A DFS solution
Such a DFS algorithm will be very slow. It does not check for every solution state (node) whether a solution has been reached, or whether a partial solution can lead to a feasible solution Is there a more efficient solution?
85
Backtracking
Definition: We call a node nonpromising if it cannot lead to a feasible (or optimal) solution, otherwise it is promising. Main idea: Backtracking consists of doing a DFS of the state space tree, checking whether each node is promising and if the node is nonpromising, backtrack to the nodes parent.
86
Backtracking
The state space tree consisting of expanded nodes only is called the pruned state space tree. The following slide shows the pruned state space tree for the sum of subsets example.
87
w/o 3 0
w/o 4 3 5 8
w/o 6 w/o 5
4 4 5 9
w/o 5
w/o 4
13 Solution
Solution: {3,4,6}
There are only 15 nodes in the pruned state 88 space tree. The full state space tree has 31 nodes.
Backtracking
Live node: A node which has been generated and all whose children have not yet been generated. E-node: The live node whose children are currently being generated. Dead node: A generated node which is not to be expanded further or all of whose children have been generated. Bounding functions are used to kill live nodes without generating all their children. Depth first node generation with bounding functions is called backtracking.
89
Backtracking algorithm
void checknode (node v) { node u if (promising ( v )) if (aSolutionAt( v )) write the solution else //expand the node for ( each child u of v ) checknode ( u ) }
90
Checknode
promising(v) which checks that the partial solution represented by v can lead to the required solution. aSolutionAt(v) which checks whether the partial solution represented by node v solves the problem.
91
totalPossibleLeft = weight of the remaining items i+1 to n (for a node at depth i) A node at depth i is non-promising if (weightSoFar + totalPossibleLeft < S ) or (weightSoFar + w[i+1] > S ) If (weightSoFar == S) then it is a promising node at depth i.
92
2
4
3 0
11
4 3 0
0 0
3
5
7 0
8
5
12 13
9 5
4 0
15
4
12
5
6
9
0 7
10
14
6 13 solution
- backtrack
Nodes are numbered in call order.
93
include [ i + 1 ] = "no
94
boolean promising (i ) {
return ( weightSoFar + totalPossibleLeft S) && ( weightSoFar == S || weightSoFar + w[i + 1] S )
95
{ K:=1; while (k 0) do
if ( there remains an untried x[k] T(x[1], , x[k-1]) and Bk (x[1], x[2], , x[k]) is true ) then
{
if (x[1], x[2], , x[k] is a path to an answer node) then write (x[1:k]); k := k + 1; // Consider the next set
}
else k := k 1;
}
}
96
for (each x[k] T(x[1], , x[k-1]) do { if (Bk (x[1], x[2], , x[k]) 0) then { if (x[1], x[2], , x[k] is a path to an answer node) then write (x[1:k]); if (k < n) then Backtrack(k+1); } }
97
Generate all possible solutions DFS technique is used to generate the solutions. Backtracking algorithm time complexity is exponential.
98
What are the requirements that are needed for performing Backtracking?
To solve any problem using backtracking, it requires that all the solutions satisfy a complex set of constraints. They are: Explicit constraints Implicit constraints
99
What are the factors that influence the efficiency of the backtracking algorithm?
The efficiency of the backtracking algorithm depends on the following four factors. The time needed to generate the next xk The number of xk satisfying the explicit constraints. The time for the bounding functions Bk The number of xk satisfying the Bk.
100
Analysis
Once
the state space tree organization is selected, The first three factors are relatively independent of the problem instance being solved. Only the fourth factor varies from one problem instance to another.
101
Analysis
A backtracking algorithm on one problem instance might generate only O(n) nodes whereas on a different instance it might generate almost all the nodes in the state space tree.
102
Analysis
If the number of nodes in the solution space is 2n or n!
103
Importance of backtracking
Ability to solve some instances with large n in a very small amount of time.
Difficult task.! Predicting the behavior of a backtracking algorithm for the problem instance we wish to solve.
104
Estimate the number of nodes that will be generated by a backtracking algorithm working on a certain instance.
105
{ K:=1; m := 1; r := 1;
repeat
Tk := { x[k] | x[k] T(x[1], , x[k-1]) and Bk (x[1], x[2], , x[k]) is true ) }; if ( Size( Tk ) = 0) then return m; r := r * Size( Tk ) ; m := m + r; x[k] := Choose ( Tk ); k := k + 1;
} until (false)
}
106
As can be seen from both the analysis and performance measurements the randomized algorithm is far more efficient than the algorithm that uses recursive backtracking.
108
Summar y : Concept
Backtracking
Recursion can be used for elegant and easy implementation of backtracking. Backtracking can easily be used to iterate through all subsets or permutations of a set. Backtracking ensures correctness by enumerating all possibilities. For backtracking to be efficient, we must prune the search space.
109