Brute Force

Contents

Brute force

Search space of candidate solutions for exhaustive search.
\begin{algorithm}
\begin{algorithmic}
\FUNCTION{ExhaustiveSearch}{}
\FOR{each solution $\mathcal{S}$ in the search space}
\IF{solution $\mathcal{S}$ is valid}
\STATE \textbf{print} solution $\mathcal{S}$
\ENDIF
\ENDFOR
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}

Negatives

Positives

String matching

Given a text $T[1 \ldots n]$ and a pattern $P[1 \ldots m]$, find the location of the first occurrence of the pattern in the text.

Example:
Text: abaabbaab
Pattern: abba
Output: Index $4$

\begin{algorithm}
\begin{algorithmic}
\FUNCTION{StringMatching}{$T[1 \ldots n], P[1 \ldots m]$}
\FOR{$i \gets 0$ \TO $(n - m)$}
\STATE $j \gets 1$
\STATE \{ Check if pattern matches starting at position $i$ \}
\WHILE{$j \le m$ \AND $P[j] = T[i + j]$}
\STATE $j \gets j + 1$
\ENDWHILE
\STATE \{  If we reached end of pattern, match found \}
\IF{$j > m$}
    \RETURN $(i + 1)$ \COMMENT{return starting position (1-indexed)}
\ENDIF
\ENDFOR
\RETURN $-1$
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}
AlgorithmPreprocess timeMatching timeSpace
Brute forcenone$\mathcal{O}(mn)$$\Theta(m+n)$
Trie$\Theta(m)$$\Theta(\text{nodes} \cdot |\Sigma|)$$\Theta(\text{nodes} \cdot |\Sigma|)$
Suffix tree$\Theta(n)$$\mathcal{O}(m)$$\Theta(n)$
Rabin-Karp$\Theta(m)$$\mathcal{O}(mn)$$\Theta(1)$
Aho-Corasick$\Theta(m)$$\mathcal{O}(n)$$\Theta(m)$
Boyer-Moore$\Theta(m+|\Sigma|)$$\mathcal{O}(mn)$$\Theta(|\Sigma|)$
KMP$\Theta(m)$$\mathcal{O}(n)$$\Theta(m)$

Closest pair

Given $n$ points in 2-D space, find the closest pair of points.

\begin{algorithm}
\begin{algorithmic}
\FUNCTION{ClosestPair}{$x[1 \ldots n], y[1 \ldots n]$}
\STATE $minimum \gets \infty$
\FOR{$i \gets 1$ \TO $(n-1)$}
\FOR{$j \gets (i + 1)$ \TO $n$}
\STATE $distance \gets \sqrt{ (x[i] - x[j])^2 + (y[i] - y[j])^2 }$
\IF{$distance < minimum$}
\STATE $minimum \gets distance$
\STATE $a \gets i$; $b \gets j$
\ENDIF
\ENDFOR
\ENDFOR
\RETURN $\{ (x[a], y[a]), (x[b], y[b]) \}$
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}
AlgorithmTimeSpace
Brute force$\Theta(n^2)$$\Theta(1)$
D&C$\Theta(n \log^2 n)$$\Theta(n \log n)$
D&C improved$\Theta(n \log n)$$\Theta(n \log n)$

Traveling salesperson problem (TSP)

Find the shortest tour through a given set of $n$ cities that visits each city exactly once before returning to the city where it started. In other words, given a weighted connected graph, find the shortest “Hamiltonian circuit”.

Four cities a,b,c,d with edge weights for TSP example.

No.TourLengthShortest?
1$a \rightarrow b \rightarrow c \rightarrow d \rightarrow a$$2 + 8 + 1 + 7 = 18$
2$a \rightarrow b \rightarrow d \rightarrow c \rightarrow a$$2 + 3 + 1 + 5 = 11$
3$a \rightarrow c \rightarrow b \rightarrow d \rightarrow a$$5 + 8 + 3 + 7 = 23$
4$a \rightarrow c \rightarrow d \rightarrow b \rightarrow a$$5 + 1 + 3 + 2 = 11$
5$a \rightarrow d \rightarrow b \rightarrow c \rightarrow a$$7 + 3 + 8 + 5 = 23$
6$a \rightarrow d \rightarrow c \rightarrow b \rightarrow a$$7 + 1 + 8 + 2 = 18$

AlgorithmComputesTimeSpace
Exact algorithms
Brute forceopt$\Theta((n-1)!)$$\Theta(n^2)$
Bellman-Held-Karp DPopt$\Theta(2^n n^2)$$\Theta(2^n n)$
Approximation algorithms for graphs satisfying triangle inequality
Rosenkrantz-Stearns-Lewis$\le 2$ opt$\Theta(n^2 \log n)$$\mathcal{O}(n^2)$
Christofides$\le 1.5$ opt$\Theta(n^3)$$\Theta(n^2)$

Knapsack problem

Given $n$ items of known weights $w[1 \ldots n]$ and values $v[1 \ldots n]$ and a knapsack of capacity $W$, find the most valuable subset of the items that fit into the knapsack.

SubsetTotal weightTotal valueOpt?
$\{\}$$0$$\$ 0$
$\{1\}$$7$$\$ 42$
$\{2\}$$3$$\$ 12$
$\{3\}$$4$$\$ 40$
$\{4\}$$5$$\$ 25$
$\{1,2\}$$7+3=10$$42+12=\$54$
$\{1,3\}$$7+4=11$$42+40=\$82$
$\{1,4\}$$7+5=12$$42+25=\$67$
$\{2,3\}$$3+4=7$$12+40=\$52$
$\{2,4\}$$3+5=8$$12+25=\$37$
$\{3,4\}$$4+5=9$$40+25=\$65$
$\{1,2,3\}$$7+3+4=14$$42+12+40=\$94$
$\{1,2,4\}$$7+3+5=15$$42+12+25=\$79$
$\{1,3,4\}$$7+4+5=16$$42+40+25=\$109$
$\{2,3,4\}$$3+4+5=12$$12+40+25=\$77$
$\{1,2,3,4\}$$7+3+4+5=19$$42+12+40+25=\$119$
\begin{algorithm}
\begin{algorithmic}
\INPUT Item weights $w[1 \ldots n]$, values $v[1 \ldots n]$, capacity $W$
\OUTPUT Maximum value achievable within capacity $W$ (and selected subset)
\FUNCTION{Knapsack}{$w[1 \ldots n], v[1 \ldots n], W$}
\RETURN \CALL{KnapsackRec}{$W, n$}
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}
\begin{algorithm}
\begin{algorithmic}
\INPUT Remaining capacity $capacity$, number of items considered $n$
\OUTPUT Best pair $(value, subset)$ using first $n$ items
\FUNCTION{KnapsackRec}{$capacity, n$}
\STATE \{ Base case: no items or no capacity \}
\IF{$n = 0$ \OR $capacity = 0$}
\RETURN $\langle 0, \{ \} \rangle$
\ENDIF
\STATE \{ If current item's weight exceeds capacity, skip it \}
\IF{$w[n] > capacity$}
\RETURN \CALL{KnapsackRec}{$capacity, n-1$}
\ELSE
\STATE \{ Exclude current item \}
\STATE $\langle valueexclude, subsetexclude \rangle \gets$ \CALL{KnapsackRec}{$capacity, n-1$}
\STATE \{ Include current item \}
\STATE $\langle valueinclude, subsetinclude \rangle \gets$ \CALL{KnapsackRec}{$capacity - w[n], n-1$}
\STATE $valueinclude \gets valueinclude + v[n]$
\STATE{}
\STATE \{ Return the better option \}
\IF{$valueinclude > valueexclude$}
\STATE $subsetinclude \gets subsetinclude.\text{Add}(n)$ \COMMENT{ add current item}
\RETURN $\langle valueinclude, subsetinclude \rangle$
\ELSE
\RETURN $\langle valueexclude, subsetexclude \rangle$
\ENDIF
\ENDIF
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}

Maximum subarray sum

Given an array of integers $A[1 \ldots n]$, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:
Input: $[-2, 1, -3, 4, -1, 2, 1, -5, 4]$
Output: $6$

\begin{algorithm}
\begin{algorithmic}
\INPUT Array $A[1 \ldots n]$
\OUTPUT Maximum subarray sum
\FUNCTION{MaxSubarraySum-BruteForce}{$A[1 \ldots n]$}
\STATE $maxsum \gets -\infty$
\STATE \{ Consider all possible starting points \}
\FOR{$start \gets 1$ \TO $n$}
\STATE \{ Consider all possible ending points \}
\FOR{$end \gets start$ \TO $n$}
\STATE $currentsum \gets 0$
\STATE \{ Calculate sum from start to end \}
\FOR{$k \gets start$ \TO $end$}
\STATE $currentsum \gets currentsum + A[k]$
\ENDFOR
\STATE \{ Update maximum sum \}
\IF{$currentsum > maxsum$}
\STATE $maxsum \gets currentsum$
\ENDIF
\ENDFOR
\ENDFOR
\RETURN $maxsum$
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}
\begin{algorithm}
\begin{algorithmic}
\INPUT Array $A[1 \ldots n]$
\OUTPUT Maximum subarray sum
\FUNCTION{MaxSubarraySum-BruteForceImproved}{$A[1 \ldots n]$}
\STATE $maxsum \gets -\infty$
\STATE \{ Consider all possible starting points \}
\FOR{$start \gets 1$ \TO $n$}
\STATE $currentsum \gets 0$
\STATE \{ Consider all possible ending points \}
\FOR{$end \gets start$ \TO $n$}
\STATE \{ Update running sum from start to end \}
\STATE $currentsum \gets currentsum + A[end]$
\STATE \{ Update maximum sum \}
\IF{$currentsum > maxsum$}
\STATE $maxsum \gets currentsum$
\ENDIF
\ENDFOR
\ENDFOR
\RETURN $maxsum$
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}
AlgorithmTimeSpace
Brute force$\Theta(n^3)$$\Theta(1)$
Brute force optimized$\Theta(n^2)$$\Theta(1)$
Dynamic programming$\Theta(n)$$\Theta(n)$

Straightforward approach

Counting inversions

Given an array of distinct integers $A[1 \ldots n]$, count the number of inversions in the array.
An inversion is defined as a pair of indices $(i, j)$ such that:
$i < j$ and $A[i] > A[j]$
Inversion = out of order pair.

Example:
Input: $[2, 4, 1, 3, 5]$
Inversion pairs: $(2, 1)$, $(4, 1)$, $(4, 3)$
Output: $3$

\begin{algorithm}
\begin{algorithmic}
\INPUT Array $A[1 \ldots n]$
\OUTPUT Number of inversions in $A$
\FUNCTION{CountInversions}{$A[1 \ldots n]$}
\STATE $count \gets 0$
\FOR{$i \gets 1$ \TO $(n-1)$}
\FOR{$j \gets (i+1)$ \TO $n$}
\IF{$A[i] > A[j]$}
\STATE $count \gets count + 1$
\ENDIF
\ENDFOR
\ENDFOR
\RETURN $count$
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}
AlgorithmTimeSpace
Brute force$\Theta(n^2)$$\Theta(1)$
Divide-and-conquer$\Theta(n\log n)$$\Theta(n)$

Random permutation generation

Generate random permutations of $A[1 \ldots n]$.

Does not generate a uniformly random permutation

\begin{algorithm}
\begin{algorithmic}
\INPUT Array $A[1 \ldots n]$
\OUTPUT A non-uniform random permutation of $A$
\FUNCTION{GenerateNonuniformRandomPermutation}{$A[1 \ldots n]$}
\FOR{$i \gets 1$ \TO $(n-1)$}
\STATE $j \gets \text{Random}([1 \ldots n])$
\STATE $\text{swap}(A[i], A[j])$
\ENDFOR
\RETURN $A[1 \ldots n]$
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}
Reason:

Generates a uniformly random permutation

\begin{algorithm}
\begin{algorithmic}
\INPUT Array $A[1 \ldots n]$
\OUTPUT A uniformly random permutation of $A$
\FUNCTION{GenerateUniformRandomPermutation}{$A[1 \ldots n]$}
\FOR{$i \gets 1$ \TO $(n-1)$}
\STATE $j \gets \text{Random}([i \ldots n])$
\STATE $\text{swap}(A[i], A[j])$
\ENDFOR
\RETURN $A[1 \ldots n]$
\ENDFUNCTION
\end{algorithmic}
\end{algorithm}