Daniel Sutantyo, Department of Computing, Macquarie University
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
"a"
""
"ab"
"a"
"b"
""
"abc"
"ab"
"ac"
"a"
"bc"
"b"
"c"
a ?
b ?
c ?
""
""
d ?
"abd"
"ab"
"bcd"
"bc"
"d"
""
... ...
... ...
(and so on)
3.3 - Recursive Backtracking
// generate combinations of length 'size' of the characters in the array 'characters'
public static void generate_combinations_of_size(char[] characters, int i,
ArrayList<Character> result, int size) {
// if i reaches the end of the array, we're done
if (i >= characters.length) {
// print it out if we have the required size
if (result.size() == size) System.out.println(result);
}
else {
// current element
Character ch = characters[i];
// recurse, include the i-th character
result.add(ch);
generate_combinations_of_size(characters,i+1,result,limit);
// recurse, don't include the i-th character
result.remove(ch);
generate_combinations_of_size(characters,i+1,result,limit);
}
}
3.3 - Recursive Backtracking
public static boolean solve(int[] b, int i, int L) {
// if L == 0, we are done
if (L == 0){
return true;
}
// if we get to the end of array but still can't make the sum,
// return false
if (i >= b.length) {
return false;
}
// else keep on going with the remaining sum
return solve(b,i+1,L-b[i]) || solve(b,i+1,L);
}
// recurse, include the i-th character
result.add(ch);
generate_combinations_of_size(characters,i+1,result,limit);
// recurse, don't include the i-th character
result.remove(ch);
generate_combinations_of_size(characters,i+1,result,limit);
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
"a"
""
"ab"
"a"
"b"
""
"abc"
"ab"
"ac"
"a"
"bc"
"b"
"c"
a ?
b ?
c ?
""
""
d ?
"abcd"
(and so on)
"abcde"
e ?
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
// generate combinations of length 'size' of the characters in the array 'characters'
public static void generate_combinations_of_size(char[] characters, int i,
ArrayList<Character> result, int size) {
// if i reaches the end of the array, we're done
if (i >= characters.length) {
// print it out if we have the required size
if (result.size() == size) System.out.println(result);
}
else {
// current element
Character ch = characters[i];
// recurse, include the i-th character
result.add(ch);
generate_combinations_of_size(characters,i+1,result,limit);
// recurse, don't include the i-th character
result.remove(ch);
generate_combinations_of_size(characters,i+1,result,limit);
}
}
3.3 - Recursive Backtracking
// generate all permutations of the characters in the set h
public static void generate_permutation_using_set(HashSet<Character> h,
ArrayList<Character> result) {
// no character left in the set, so we are done
if (h.isEmpty()) {
System.out.println(result);
}
HashSet<Character> temp = new HashSet<Character>(h);
for(Character c : temp) {
// choose a character to add
h.remove(c);
result.add(c);
generate_permutation_using_set(h,result);
// backtracking
result.remove(c);
h.add(c);
}
}
3.3 - Recursive Backtracking
"a"
"b"
"z"
"c"
""
"d"
... ...
""
"a"
"b"
"y"
"c"
"d"
... ...
"b"
"c"
"z"
"d"
... ...
HashSet<Character> temp = new HashSet<Character>(h);
for(Character c : temp) {
// choose a character to add
h.remove(c);
result.add(c);
generate_permutation_using_set(h,result);
// backtracking
result.remove(c);
h.add(c);
}
3.3 - Recursive Backtracking
// generate all permutations of the array result
// start with call to generate_permutation(result,0,result.length-1)
// where result is the array that you want to permute
public static void generate_permutation(char[] result, int start, int end) {
// print out the result
if (start == end)
System.out.println(result);
else {
for(int i = start; i <= end; i++) {
// swap the elements in start and i
swap(result,start,i);
generate_permutation(result,start+1,end);
swap(result,start,i);
}
}
}
3.3 - Recursive Backtracking
for(int i = start; i <= end; i++) {
swap(result,start,i);
generate_permutation(result,start+1,end);
swap(result,start,i);
}
3.3 - Recursive Backtracking
for(int i = start; i <= end; i++) {
swap(result,start,i);
generate_permutation(result,start+1,end);
swap(result,start,i);
}
ABCD
ABCD
BACD
DBCA
CBAD
ABCD
ACBD
ADCB
ABCD
ABDC
BACD
BCAD
BDCA
CBAD
CABD
CDAB
DBCA
DCBA
DACB
DACB
DABC
(swap A with A)
(swap A with B)
(swap A with C)
(swap A with D)
B ~ B
B ~ C
B ~ D
C ~ C
C ~ D
A ~ A
A ~ C
A ~ D
B ~ B
B ~ A
B ~ D
B ~ B
B ~ C
B ~ D
C ~ C
C ~ B
3.3 - Recursive Backtracking
"a"
""
"ab"
"a"
"b"
""
"abc"
"ab"
"ac"
"a"
"bc"
"b"
"c"
a ?
b ?
c ?
""
""
3.3 - Recursive Backtracking
"a"
""
"ab"
"a"
"b"
""
"abc"
"ab"
"ac"
"a"
"bc"
"b"
"c"
a ?
b ?
c ?
""
""
1
0
11
10
01
11
111
110
101
100
011
010
011
000
3.3 - Recursive Backtracking
"a"
""
"ab"
"a"
"b"
""
"abc"
"ab"
"ac"
"a"
"bc"
"b"
"c"
a ?
b ?
c ?
""
""
1
0
11
10
01
11
111
110
101
100
011
010
011
000
3.3 - Recursive Backtracking
"a"
""
"ab"
"a"
"b"
""
"abc"
"ab"
"ac"
"a"
"bc"
"b"
"c"
a ?
b ?
c ?
""
""
1
0
11
10
01
11
111
110
101
100
011
010
011
000
3.3 - Recursive Backtracking
// if i reaches the end of the array, we're done
if (i >= characters.length) {
// print it out if we have the required size
if (result.size() == size) System.out.println(result);
}
"a"
""
"ab"
"a"
"b"
""
"abc"
"ab"
"ac"
"a"
"bc"
"b"
"c"
a ?
b ?
c ?
""
""
d ?
"abcd"
3.3 - Recursive Backtracking
// generate combinations of length 'size' of the characters in the array 'characters'
public static void generate_combinations_of_size(char[] characters, int i,
ArrayList<Character> result, int size) {
// if we already have more than 'size' characters in result, then we don't need
// to go any further
if (result.size() > size)
return;
// if i reaches the end of the array, we're done
if (i >= characters.length) {
// print it out if we have the required size
if (result.size() == size) System.out.println(result);
}
else { ... }
}
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
public static boolean solve(int[] b, int i, int L) {
// if L == 0, we are done
if (L == 0){
return true;
}
// if we get to the end of array but still can't make the sum,
// return false
if (i >= b.length) {
return false;
}
// else keep on going with the remaining sum
return solve(b,i+1,L-b[i]) || solve(b,i+1,L);
}
3.3 - Recursive Backtracking
[ 10 , 12 , 5 , 7 , 11 ] L = 25
[ 12 , 5 , 7 , 11 ] L = 15
[ 5 , 7 , 11 ] L = 3
pick 12
don't pick 12
...
...
...
...
...
...
[ 5 , 7 , 11 ] L = 15
...
pick 10
pick 12
don't pick 10
don't pick 12
...
[ 12 , 5 , 7 , 11 ] L = 25
[ 5 , 7 , 11 ] L = 13
[ 5 , 7 , 11 ] L = 25
3.3 - Recursive Backtracking
[ 50 , 2 , 18 , 11 , 9 , 23 , 5 , 10 , 30 , 6 , 17 ] L = 27
[ 2 , 18 , 11 , ... , 17 ] L = -23
[ 2 , 18 , 11 , ... , 17 ] L = 27
[18 , 11 , ... , 17 ] L = -25
pick 2
don't pick 2
...
...
...
...
...
...
[ 18 , 11, ... , 17] L = -23
[18 , 11, ... , 17 ] L = 25
[ 18 , 11 , ... , 17 ] L = 27
...
...
pick 50
pick 2
don't pick 50
don't pick 2
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
public static boolean solve(int[] b, int i, int L) {
// if L == 0, we are done
if (L == 0){
return true;
}
// if we get to the end of array but still can't make the sum,
// return false
if (i >= b.length) {
return false;
}
// else keep on going with the remaining sum
return solve(b,i+1,L-b[i]) || solve(b,i+1,L);
}
public static boolean solve(int[] b, int i, int L) {
// if L == 0, we are done
if (L == 0){
return true;
}
// if L is negative or we get to the end of the array
// return false
if (i >= b.length || L < 0) {
return false;
}
// else keep on going with the remaining sum
return solve(b,i+1,L-b[i]) || solve(b,i+1,L);
}
3.3 - Recursive Backtracking
public static boolean solve(int[] b, int i, int L) {
// if L == 0, we are done
if (L == 0){
return true;
}
// if L is negative or we get to the end of the array
// return false
if (i >= b.length || L < 0) {
return false;
}
// else keep on going with the remaining sum
return solve(b,i+1,L-b[i]) || solve(b,i+1,L);
}
3.3 - Recursive Backtracking
public static boolean solve(int[] b, int i, int L) {
// if L == 0, we are done
if (L == 0){
return true;
}
// if L is negative or we get to the end of the array
// return false
if (i >= b.length || L < 0 || sum(b,i) < L) {
return false;
}
// else keep on going with the remaining sum
return solve(b,i+1,L-b[i]) || solve(b,i+1,L);
}
3.3 - Recursive Backtracking
[ 50 , 2 , 18 , 11 , 9 , 23 , 5 , 10 , 30 , 6 , 17 ] L = 27
[ 2 , 18 , 11 , ... , 17 ] L = -23
[ 2 , 18 , 11 , ... , 17 ] L = 27
[18 , 11 , ... , 17 ] L = -25
pick 2
don't pick 2
[ 18 , 11, ... , 17] L = -23
[18 , 11, ... , 17 ] L = 25
[ 18 , 11 , ... , 17 ] L = 27
...
pick 50
pick 2
don't pick 50
don't pick 2
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking
3.3 - Recursive Backtracking