# Topics

• Combinatorial generation
• Permutations
• Combinations
• Subsets

# Combinatorial generation

• “Combinatorics is the study of the ways in which discrete objects can be arranged into various kinds of patterns.” wrote Donald Knuth in The Art of Computer Programming, Vol 4A, Combinatorial Algorithms, Part 1.
• In this lecture note we will touch on the fascinating subject of Combinatorial Generation.
• Generating a combinatorial object is the basis of various algorithms.
• Backtracking can be viewed as a modification of the regular algorithm for generating combinatorial objects. Backtracking takes an algorithm for generating a certain type of combinatorial objects and modifies it so that only objects satisfying certain constraints are generated.

# Permutations

• Let $$S$$ be a finite set. A permutation on $$S$$ is a 1-1 and onto function from $$S$$ into itself. Put simply, it’s an arrangement of all the elements of $$S$$ in a line, taking order into consideration. E.g. if $$S = \{ a, b, c \}$$ then $$bca$$ is a permutation of $$S$$ and $$cab$$ is another. In fact, these are all the permutations of $$S$$
• $$abc$$
• $$acb$$
• $$bac$$
• $$bca$$
• $$cab$$
• $$cba$$
• E.g., in the $$n$$-queen puzzle every valid placement of $$n$$ queens on the $$n\times n$$ chessboard can be described as “a permutation $$pi$$ of the set $$\{ 0, 1, \ldots, n-1 \}$$ such that placing queen $$i$$ at position $$pi(i)$$ for all $$0\le i<n$$, does not put any two queens on mutually-attacking squares.” The program nQueensRandomized.kt demonstrated in class uses backtracking for the n-queen puzzle in this way. It takes the basic algorithm for generating the permutations on $$\{0,1,\ldots, n-1\}$$ and modifies it so that any branch of the permutation generation algorithm that will generate a mutually-attacking queen pair is abandoned.

# Algorithm to generate all permutations

• Here is an algorithm to generate all the permutations on the set $$\{ 0, 1, \dots, n-1 \}$$.

fun main(args: Array<String>) {
val n = args[0].toInt()
val a = IntArray(n) { it }
fun swap(i: Int, k: Int) {
val temp = a[i]
a[i] = a[k]
a[k] = temp
}
fun perm(k: Int) {
if (k == n) println(a.joinToString(separator=" "))
else for (i in k until n) {
swap(i, k)
perm(k+1)
swap(i, k)
}
}
perm(0)
}

# Combinations

• Let $$S$$ be a finite set. A $$k$$-combination of $$S$$ is a subset of $$S$$ of size $$k$$.
• E.g., if $$S = \{a, b, c, d\}$$, then all the 2-combinations of $$S$$ are
• $$ab$$
• $$ac$$
• $$ad$$
• $$bc$$
• $$bd$$
• $$cd$$

Note that order of symbols does not matter in the above listing: $$ab$$ or $$ba$$ means the same subset.

# Algorithm to generate all k-combinations

• Here is an algorithm to generate all the $$k$$-combinations of the set $$\{ 0, 1, \dots, n-1 \}$$.

fun main(args: Array<String>) {
val n = args[0].toInt()
val k = args[1].toInt()
val b = BooleanArray(n)
fun comb(start: Int, i: Int) {
if (i == k+1) {
for (j in b.indices)
if (b[j]) print(" $j") println() } else for (j in start until (n-k+i)) { b[j] = true comb(j+1, i+1) b[j] = false } } comb(0, 1) } # Subsets • Let $$S$$ be a finite set. A subset of $$S$$ is any set $$T$$ such that every member of $$T$$ is also a member of $$S$$. • E.g., if $$S = \{ 0, 1, 2 \}$$ then the subsets of $$S$$ are • $$\emptyset$$ • $$0$$ • $$1$$ • $$2$$ • $$0 1$$ • $$0 2$$ • $$1 2$$ • $$0 1 2$$ where order does not matter in the above listing. # Algorithm to generate all subsets • Here is an algorithm to generate all the subsets of the set $$\{ 0, 1, \dots, n-1 \}$$. fun main(args: Array<String>) { val n = args[0].toInt() val b = BooleanArray(n) fun subsets(i: Int) { if (i == n) { for (j in b.indices) if (b[j]) print("$j")
println()
} else {
b[i] = false
subsets(i+1)
b[i] = true
subsets(i+1)
}
}
subsets(0)
}