Algorithm
Table of Contents
- 1. Search
- 2. Sort
- 3. Select
- 4. Count
- 5. Greedy Algorithm
- 6. Dynamic Programming
- 7. Dijkstra's Algorithm
- 8. Spell Checker
- 9. Minimax Approximation
- 10. Linear Programming
- 11. Number Theory
- 12. Randomized Numerical Linear Algebra
- 13. Fast Fourier Transform
- 14. Gilbert-Johnson-Keerthi Algorithm
- 15. Expanding Polytope Algorithm
- 16. Maze Generating Algorithm
- 17. Reed-Solomon Error Correction
- 18. Reference
1. Search
1.1. Binary Search
1.2. Breadth First Search
1.3. Depth First Search
1.4. Boyer-Moore String-Search Algorithm
- Used in
grep
Algorithm for searching for a short pattern in a long text.
2. Sort
2.1. Bubble Sort
- Change with the next one if out of order.
- Time Complexity: \( O(N^2) \)
- Good for mostly sorted array.
2.2. Selection Sort
- Find the smallest element within the undetermined next part and let it be the first one within the part.
- Time Complexity: \(O(N^2)\)
- Consistently slow.
2.3. Insertion Sort
- Insert the next element into the correct position within the sorted previous part.
- Time Complexity: \(O(N^{2})\)
- Usually fast, but slow when the array is in reverse order, to the exact point of the selection sort.
- Exceptional when few elements added to a sorted array.
2.4. Radix Sort
- Sort the array digit by digit from the least significant digit.
- Uses an array of array that stores the elements in an outer array that matches its digit and append it in the end of the inner array, later to be read from the start.
- Time Complexity: \(O(kN)\) where \(k\) is the largest number of digits.
- Not in-place
2.5. Merge Sort
- Recursively perform merge sort on half of the input and merge those two halves.
- Time Complexity: \(O(N\log N)\)
- Not in-place Sort, in which the elements are temporarily stored outside of the array.
2.6. Quick Sort
- Determine a pivot (the last element, in this case) and gather the largers and the smallers, and then perform quick sort on those recursively.
- During the pivoting stage, two pointer are used one-pointer 1-for the end of the smallers, and the other-pointer 2-for the next element to swap position.
- March the pointer 2 until it finds an element smaller than the pivot
and swap it with the next element of the pointer 1, march the
pointer 1 by 1, again start marching the pointer 2 until it reaches
the end (in this case, the pivot).
- When set the last element to be the pivot the pivot swapped with the first larger element as the last step.
- Time Complexity: \(O(N\log N)\) on average, \(O(N^2)\) in the worst
case, but use of some technique prevents the worst case scenario.
- Pivot can be chosen to be the leftmost element or middle element, in simple implementation.
- The most common method that eliminates the problem is to use the median of the first, last, middle elements.
- Not stable, the order of same valued element is not preserved.
2.7. Heap Sort
- Find the largest element within the undetermined previous part and let it be the last one within the part.
- But unlike the selection sort it uses heap, a binary tree in which
each node has two or less child nodes, to find the maximum element.
- The binary tree can be encoded in an array, in this case, the
original array is the heap.
- Set the root node to be at the index 1. Child nodes have the index of 2i and 2i + 1 of the parent index i.
- First one need to make the heap into a max-heap, in which all the
nodes are larger than or equal to all of their childs.
- Starting from the nodes that has the depth of just 1 smaller than the leaf nodes, find the largest node among the node and its two children, and swaps with the child node if it's larger. Repeat this until we reach the root node.
- Note that after a node have swapped, the change needs to be propagated to the children of the swapped child node.
- After max-heap has been achieved than the first element is the
largest one, so swaps it with the last element of the unsorted
part, and make max-heap again without the just determined element.
- This reconstruction of max-heap is simple because it only moves one element at each depth.
- The binary tree can be encoded in an array, in this case, the
original array is the heap.
- Time Complexity: \(O(N\log N)\)
- Not stable
3. Select
3.1. Quickselect
- Hoare's Selection Algorithm
Find the \( k \)th smallest element in a list.
4. Count
4.1. Hyperloglog
Probablistically count the number of distinct elements.
Hash each element and find the maximum runs of zeros. If run is longer than there are more distinct elements.
- Start with a set of elements and few score variables that store the length of longest run.
- Calculate hash of an element
- Select one of the scores, and store the length of run of zeros if it is larger than the score.
- Repeat until exhausted
- Take the harmonic mean of the scores
- Larger the mean, larger the number of distinct elements.
We can run this algorithm in parallel, and select the larger score (at each position of score vector).
5. Greedy Algorithm
Repeatedly find the best option locally and get the approximation of the global best.
6. Dynamic Programming
It is recursion with memoization(??, ????)
"Correctness of bruteforcing and efficiency of greedy algorithm."
Old implementation of diff algorithm is one of them.(Tech With Nikola, ????)
It is about finding the longest common subsequence.
7. Dijkstra's Algorithm
7.1. A* Algorithm
8. Spell Checker
It uses dictionary to spot typos and calculates the edit distance to suggest the corrections.
8.1. spell
UNIX spell checker that showed recommendations for typos.
8.2. Levenshtein Distance Algorithm
Devised by Soviet scientist, Vladimir Levenshtein in 1965.
def lev(a: str, b: str) -> int:
if len(a) == 0:
return len(b)
if len(b) == 0:
return len(a)
if head(a) == head(b): # head(a) = a[0]
return lev(tail(a), tail(b)) # tail(a) = a[1:]
return 1 + min(
lev(tail(a), b), # case of insertion
lev(a, tail(b)), # case of deletion
lev(tail(a), tail(b)) # case of substitution
)
8.3. Wagner
- Robert Wagner and Micheal Fischer
- Used dynamic programming upon the Levenshtein distance algorithm.
9. Minimax Approximation
Process or the result of finding a polynomial \( p^*(x) \) such that the infinity norm \( \Vert f(x)-p^*(x)\Vert_\infty=\max_{\xi\in[a,b]}|f(\xi)-p^*(\xi)|\) is minimum.
9.1. One-Point Exchange Method
Given \(n\) points on the domain, it is possible to find degree \(n-2\) polynomial \(p(x)\), such that at every given points \(f(x_i)-p(x_i)\) is distinct, sign alternating, with same error \(h\), using matrix equation,
\begin{bmatrix} 1&\xi_1&\xi_1^2&1\\ 1&\xi_2&\xi_2^2&-1\\ 1&\xi_3&\xi_3^2&1\\ 1&\xi_4&\xi_4^2&-1 \end{bmatrix} \begin{bmatrix} a\\ b\\ c\\ h \end{bmatrix} = \begin{bmatrix} f(\xi_1)\\ f(\xi_2)\\ f(\xi_3)\\ f(\xi_4) \end{bmatrix}- We find the point with the largest error, and substitute it to the closest point with the same sign of error.
- Repeat this multiple times and we get the minimax approximation.
9.2. Remez Algorithm
Produce the minimax approximation of a function in an iterative way.
- One-point exchange method, but exchange all the points for the points where the errors are at the local maxima.
- Repeat this until every points of extremum errors is equal-magnitude and sign-alternating.
10. Linear Programming
- A linear program is comprises of
- set of variables
- set of linear inequalities
- a linear function, called objective function because it is what we want to maximize.
10.1. Simplex method
- Introduce slack variables for every inequality. Initially the slack variables are basic (loose), and the variables are non-basic (tight).
- Find a variable to loosen. One of the rules to find it is the Dantzig's pivot rule, which takes a variable with largest non-negative coefficient in the object function.
- Find a basic variable with largest non-positive constant over coefficient ratio, and tighten it.
- Rewrite the equations for the basic variables.
- Repeat step 2 through 4, until every variable in the object function has non-positive coefficient.
- Set the slack variables to zero, to obtain the maximum.
10.1.1. Example
The problem statement:
\begin{align*} x_1, x_2 &\ge 0 \\ x_1 &\le 3 \\ x_2 &\le 4 \\ x_1+x_2 &\le 5 \\[5px] \text{obj.}\ 1.2x_1 &+ 1.7x_2. \end{align*}Introduce slack variables \(s_1,s_2,s_3 \ge 0\). Roman letters indicates it is tight.
\begin{align*} s_1 &= 3 - \mathrm{x}_1\\ s_2 &= 4 - \mathrm{x}_2\\ s_3 &= 5 - \mathrm{x}_1 - \mathrm{x}_2\\[5px] \text{obj.}\ &1.2\mathrm{x}_1 + 1.7\mathrm{x}_2 \nonumber \end{align*}Loosen the appropriate variable: \(x_2\) with coefficient \(1.7\).
\begin{align*} s_1 &= 3 - \mathrm{x}_1\\ s_2 &= 4 - x_2\\ s_3 &= 5 - \mathrm{x}_1 - x_2\\[5px] \text{obj.}\ &1.2\mathrm{x}_1 + 1.7x_2 \end{align*}Tighten the appropriate variable: \(s_2\) with \(4\) (constant in the equation) over \(-1\) (coefficient of \(x_2\)).
\begin{align*} s_1 &= 3 - \mathrm{x}_1\\ \mathrm{s}_2 &= 4 - x_2\\ s_3 &= 5 - \mathrm{x}_1 - x_2\\[5px] \text{obj.}\ &1.2\mathrm{x}_1 + 1.7x_2 \end{align*}rewrite the equations.
\begin{align*} s_1 &= 3 - \mathrm{x}_1\\ x_2 &= 4 - \mathrm{s}_2\\ s_3 &= 1 - \mathrm{x}_1 + \mathrm{s}_2\\[5px] \text{obj.}\ &1.2\mathrm{x}_1 - 1.7\mathrm{s}_2 + 6.8 \end{align*}repeat.
\begin{align*} s_1 &= 3 - x_1\\ x_2 &= 4 - \mathrm{s}_2\\ s_3 &= 1 - x_1 + \mathrm{s}_2\\[5px] \text{obj.}\ &1.2x_1 - 1.7\mathrm{s}_2 + 6.8, \end{align*} \begin{align*} s_1 &= 3 - x_1\\ x_2 &= 4 - \mathrm{s}_2\\ \mathrm{s}_3 &= 1 - x_1 + \mathrm{s}_2\\[5px], \end{align*} \begin{align*} s_1 &= 2 + \mathrm{s}_3 - \mathrm{s}_2\\ x_2 &= 4 - \mathrm{s}_2\\ x_1 &= 1 - \mathrm{s}_3 + \mathrm{s}_2\\[5px] \text{obj.}\ &-1.2\mathrm{s}_3 - 0.5\mathrm{s}_2 + 8, \end{align*}- Now all coefficients are negative we can safely say \(s_2 = s_3 = 0\) and \(\max(\text{obj.)} = 8\).
10.2. Dual Linear Program
From a linear program, we can induce dual linear program by expressing the bound of the object function in terms of scalar \(y_i\) multiple of linear inequalities, while flipping the objective of the problem, maximum to minimum and vice versa.
\begin{align*} x_1, x_2 &\ge 0 \\ x_1 &\le 3 \\ x_2 &\le 4 \\ x_1+x_2 &\le 5 \\[5px] \text{obj.}\ \max\ 1.2x_1 &+ 1.7x_2 \end{align*}corresponds to
\begin{align*} y_1, y_2, y_3 &\ge 0 \\ y_1+y_3 &\ge 1.2 \\ y_2+y_3 &\ge 1.7 \\[5px] \text{obj.}\ \min\ 3y_1 &+ 4y_2+5y_3. \end{align*}10.2.1. Duality theorem
It states that a dual proves that the other is optimal.
10.3. Integer linear programming
It is solving a linear program with integer variables.
11. Number Theory
12. Randomized Numerical Linear Algebra
- Rand-NLA
Given a matrix \( \mathbf{A} \) and a vector \( \mathbf{b} \), we choose a selection matrix \( \mathbf{S} \) that reduces the dimension, and find the solution to the least squares problem:
\begin{align*} \mathbf{x}^{*} &:= \mathop{\rm arg\ min}_{\mathbf{x}} \Vert {\bf Ax - b} \Vert_2 \\ \tilde{\mathbf{x}} &:= \mathop{\rm arg\ min}_{\mathbf{x}} \Vert {\bf SAx - Sb} \Vert_2. \end{align*}With clever choice of \( \mathbf{S} \) we have \[ \Vert \mathbf{A}\tilde{\mathbf{x}} - \mathbf{b} \Vert_2 \approx \Vert \mathbf{A}\mathbf{x}^{*} - \mathbf{b} \Vert_2. \]
13. Fast Fourier Transform
- FFT
Perform efficiently.
- \(f(t_n)\to \hat{f}(\omega_n), n\in [0, N-1]\) where
- \(\omega_0\) is the DC offset
- \(\omega_{n< \text{Nyquist}}\) is the \(n\) cycles per field of view
- \(\omega_{n>\text{Nyquist}}\) is the \(-(N-n)\) cycles per field of view.
Divide into an even part and an odd part and evaluate: \[ \begin{bmatrix}z_0\\z_1\\z_2\\z_3\end{bmatrix}=\begin{bmatrix}1&1&1&1\\1&i&-1&-i\\1&-1&1&-1\\1&-i&-1&i\end{bmatrix}\begin{bmatrix}x_0\\x_1\\x_2\\x_3\end{bmatrix}\rightsquigarrow{\begin{bmatrix}1&1\\1&-1\end{bmatrix}\begin{bmatrix}x_0\\x_2\end{bmatrix} + \begin{bmatrix}1&0\\0&i\end{bmatrix}\begin{bmatrix}1&1\\1&-1\end{bmatrix}\begin{bmatrix}x_1\\x_3\end{bmatrix}\atop \begin{bmatrix}1&1\\1&-1\end{bmatrix}\begin{bmatrix}x_0\\x_2\end{bmatrix} - \begin{bmatrix}1&0\\0&i\end{bmatrix}\begin{bmatrix}1&1\\1&-1\end{bmatrix}\begin{bmatrix}x_1\\x_3\end{bmatrix}} \]
13.1. Implementation
def fft(x):
# x = [x_0, x_1, ..., x_{N-1}]
n = len(x) # n = 2^k
if n == 1:
return x
ω = e**{i*2*pi/n}
x_even, x_odd = x[::2], x[1::2]
z_even, z_odd = fft(x_even), fft(x_odd)
z = [0]*n
for j in range(n/2):
z[j] = z_even[j] + ω**j*z_odd[j]
z[j+n/2] = z_even[j] - ω**j*z_odd[j]
return z
14. Gilbert-Johnson-Keerthi Algorithm
- GJK Algorithm
Detect whether two shapes intersect.
15. Expanding Polytope Algorithm
It calculates the depth and the normal vector of collision. EPA Explanation & Implementation - YouTube
16. Maze Generating Algorithm
16.1. Depth First Search
16.2. Prim's Algorithm
16.3. Kruskal's Algorithm
16.4. Origin Shift Algorithm (CaptainLuma)
17. Reed-Solomon Error Correction
- Reed-Solomon Codes(RS Codes)
Used in CDs, DVDs, Blu-ray discs, QR coded, data transmission technologies.
Send one or two additional points that is on the Lagrange interpolation of the other points.
18. Reference
- 10 weird algorithms every developer should know - YouTube
- Boyer–Moore string-search algorithm - Wikipedia
- The Algorithm Behind Spell Checkers - YouTube
- Minimax Approximation and the Exchange Algorithm
- The Art of Linear Programming
- Is the Future of Linear Algebra.. Random? - YouTube
- The Fast Fourier Transform (FFT): Most Ingenious Algorithm Ever? - YouTube
- A Strange But Elegant Approach to a Surprisingly Hard Problem (GJK Algorithm)…
- Error Correcting Curves - Numberphile - YouTube
- Reed–Solomon error correction - Wikipedia