Corrections

This commit is contained in:
Antti H S Laaksonen 2017-02-13 23:16:30 +02:00
parent 3dd874a4fa
commit 3f31020076
3 changed files with 87 additions and 86 deletions

View File

@ -2,7 +2,7 @@
\key{Complete search} \key{Complete search}
is a general method that can be used is a general method that can be used
for solving almost any algorithm problem. to solve almost any algorithm problem.
The idea is to generate all possible The idea is to generate all possible
solutions to the problem using brute force, solutions to the problem using brute force,
and then select the best solution or count the and then select the best solution or count the
@ -30,7 +30,7 @@ or use bit operations of integers.
An elegant way to go through all subsets An elegant way to go through all subsets
of a set is to use recursion. of a set is to use recursion.
The following function \texttt{gen} The following function
generates the subsets of the set generates the subsets of the set
$\{1,2,\ldots,n\}$. $\{1,2,\ldots,n\}$.
The function maintains a vector The function maintains a vector
@ -128,8 +128,8 @@ which corresponds to an integer between $0 \ldots 2^n-1$.
The ones in the bit sequence indicate The ones in the bit sequence indicate
which elements are included in the subset. which elements are included in the subset.
The usual convention is that element $k$ The usual convention is that the $k$th element
is included in the subset if the $k$th last bit is included in the subset exactly when the $k$th last bit
in the sequence is one. in the sequence is one.
For example, the bit representation of 25 For example, the bit representation of 25
is 11001, that corresponds to the subset $\{1,4,5\}$. is 11001, that corresponds to the subset $\{1,4,5\}$.
@ -143,8 +143,8 @@ for (int b = 0; b < (1<<n); b++) {
} }
\end{lstlisting} \end{lstlisting}
The following code shows how we can derive The following code shows how we can find
the elements in a subset from the bit sequence. the elements of a subset that corresponds to a bit sequence.
When processing each subset, When processing each subset,
the code builds a vector that contains the the code builds a vector that contains the
elements in the subset. elements in the subset.
@ -165,14 +165,14 @@ for (int b = 0; b < (1<<n); b++) {
Next we will consider the problem of generating Next we will consider the problem of generating
all permutations of a set of $n$ elements. all permutations of a set of $n$ elements.
Again, there are two approaches: Again, there are two approaches:
we can either use recursion or go trough the we can either use recursion or go through the
permutations iteratively. permutations iteratively.
\subsubsection{Method 1} \subsubsection{Method 1}
Like subsets, permutations can be generated Like subsets, permutations can be generated
using recursion. using recursion.
The following function \texttt{gen} goes The following function goes
through the permutations of the set $\{1,2,\ldots,n\}$. through the permutations of the set $\{1,2,\ldots,n\}$.
The function builds a vector that contains The function builds a vector that contains
the elements in the permutation, the elements in the permutation,
@ -180,7 +180,7 @@ and the search begins when the function is
called without parameters. called without parameters.
\begin{lstlisting} \begin{lstlisting}
void haku() { void gen() {
if (v.size() == n) { if (v.size() == n) {
// process permutation v // process permutation v
} else { } else {
@ -188,7 +188,7 @@ void haku() {
if (p[i]) continue; if (p[i]) continue;
p[i] = 1; p[i] = 1;
v.push_back(i); v.push_back(i);
haku(); gen();
p[i] = 0; p[i] = 0;
v.pop_back(); v.pop_back();
} }
@ -275,8 +275,9 @@ any of the queens placed before.
A solution has been found when all A solution has been found when all
$n$ queens have been placed to the board. $n$ queens have been placed to the board.
For example, when $n=4$, the backtracking For example, when $n=4$,
algorithm generates the following tree: some partial solutions generated by
the backtracking algorithm are as follows:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=.55] \begin{tikzpicture}[scale=.55]
@ -436,7 +437,7 @@ the $4 \times 4$ board are numbered as follows:
\end{center} \end{center}
The above backtracking The above backtracking
algorithm shows that algorithm tells us that
there are 92 ways to place 8 there are 92 ways to place 8
queens to the $8 \times 8$ chessboard. queens to the $8 \times 8$ chessboard.
When $n$ increases, the search quickly becomes slow, When $n$ increases, the search quickly becomes slow,
@ -453,7 +454,7 @@ on a modern computer
We can often optimize backtracking We can often optimize backtracking
by pruning the search tree. by pruning the search tree.
The idea is to add ''intelligence'' to the algorithm The idea is to add ''intelligence'' to the algorithm
so that it will realize as soon as possible so that it will notice as soon as possible
if a partial solution cannot be extended if a partial solution cannot be extended
to a complete solution. to a complete solution.
Such optimizations can have a tremendous Such optimizations can have a tremendous
@ -484,7 +485,8 @@ One of the paths is as follows:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Next we will concentrate on the $7 \times 7$ case. We will concentrate on the $7 \times 7$ case,
because its level of difficulty is appropriate to our needs.
We begin with a straightforward backtracking algorithm, We begin with a straightforward backtracking algorithm,
and then optimize it step by step using observations and then optimize it step by step using observations
how the search can be pruned. how the search can be pruned.
@ -509,7 +511,7 @@ recursive calls: 76 billions
\subsubsection{Optimization 1} \subsubsection{Optimization 1}
In any solution, we first move a step In any solution, we first move one step
down or right. down or right.
There are always two paths that There are always two paths that
are symmetric are symmetric
@ -551,7 +553,7 @@ For example, the following paths are symmetric:
\end{center} \end{center}
Hence, we can decide that we always first Hence, we can decide that we always first
move down, move one step down,
and finally multiply the number of the solutions by two. and finally multiply the number of the solutions by two.
\begin{itemize} \begin{itemize}
@ -683,9 +685,9 @@ i.e., at the top of the search tree.
\key{Meet in the middle} is a technique \key{Meet in the middle} is a technique
where the search space is divided into where the search space is divided into
two equally large parts. two parts of about equal size.
A separate search is performed A separate search is performed
for each of the parts, for both of the parts,
and finally the results of the searches are combined. and finally the results of the searches are combined.
The technique can be used The technique can be used
@ -727,8 +729,8 @@ to a list $S_A$.
Correspondingly, the second search creates Correspondingly, the second search creates
a list $S_B$ from $B$. a list $S_B$ from $B$.
After this, it suffices to check if it is possible After this, it suffices to check if it is possible
to choose one number from $S_A$ and another to choose one element from $S_A$ and another
number from $S_B$ so that their sum is $x$. element from $S_B$ so that their sum is $x$.
This is possible exactly when there is a way to This is possible exactly when there is a way to
form the sum $x$ using the numbers in the original list. form the sum $x$ using the numbers in the original list.
@ -736,7 +738,7 @@ For example, suppose that the list is $[2,4,5,9]$ and $x=15$.
First, we divide the list into $A=[2,4]$ and $B=[5,9]$. First, we divide the list into $A=[2,4]$ and $B=[5,9]$.
After this, we create lists After this, we create lists
$S_A=[0,2,4,6]$ and $S_B=[0,5,9,14]$. $S_A=[0,2,4,6]$ and $S_B=[0,5,9,14]$.
In this case, the sum $x=15$ is possible to form In this case, the sum $x=15$ is possible to form,
because we can choose the number $6$ from $S_A$ because we can choose the number $6$ from $S_A$
and the number $9$ from $S_B$, and the number $9$ from $S_B$,
which corresponds to the solution $[2,4,9]$. which corresponds to the solution $[2,4,9]$.

View File

@ -12,8 +12,8 @@ the final solution.
For this reason, greedy algorithms For this reason, greedy algorithms
are usually very efficient. are usually very efficient.
The difficulty in designing a greedy algorithm The difficulty in designing greedy algorithms
is to invent a greedy strategy is to find a greedy strategy
that always produces an optimal solution that always produces an optimal solution
to the problem. to the problem.
The locally optimal choices in a greedy The locally optimal choices in a greedy
@ -32,7 +32,7 @@ $\{c_1,c_2,\ldots,c_k\}$,
and each coin can be used as many times we want. and each coin can be used as many times we want.
What is the minimum number of coins needed? What is the minimum number of coins needed?
For example, if the coins are euro coins (in cents) For example, if the coins are the euro coins (in cents)
\[\{1,2,5,10,20,50,100,200\}\] \[\{1,2,5,10,20,50,100,200\}\]
and the sum of money is 520, and the sum of money is 520,
we need at least four coins. we need at least four coins.
@ -71,13 +71,13 @@ because we could replace
coins $2+2+2$ by coins $5+1$ and coins $2+2+2$ by coins $5+1$ and
coins $20+20+20$ by coins $50+10$. coins $20+20+20$ by coins $50+10$.
Moreover, an optimal solution cannot contain Moreover, an optimal solution cannot contain
coins $2+2+1$ or $20+20+10$ coins $2+2+1$ or $20+20+10$,
because we could replace them by coins $5$ and $50$. because we could replace them by coins $5$ and $50$.
Using these observations, Using these observations,
we can show for each coin $x$ that we can show for each coin $x$ that
it is not possible to optimally construct it is not possible to optimally construct
sum $x$ or any larger sum by only using coins a sum $x$ or any larger sum by only using coins
that are smaller than $x$. that are smaller than $x$.
For example, if $x=100$, the largest optimal For example, if $x=100$, the largest optimal
sum using the smaller coins is $50+20+20+5+2+2=99$. sum using the smaller coins is $50+20+20+5+2+2=99$.
@ -113,10 +113,10 @@ correct answer.
\section{Scheduling} \section{Scheduling}
Many scheduling problems can be solved Many scheduling problems can be solved
using a greedy strategy. using greedy algorithms.
A classic problem is as follows: A classic problem is as follows:
Given $n$ events with their starting and ending Given $n$ events with their starting and ending
times, we should plan a schedule times, our goal is to plan a schedule
that includes as many events as possible. that includes as many events as possible.
It is not possible to select an event partially. It is not possible to select an event partially.
For example, consider the following events: For example, consider the following events:
@ -172,7 +172,7 @@ selects the following events:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
However, select short events is not always However, selecting short events is not always
a correct strategy, but the algorithm fails, a correct strategy, but the algorithm fails,
for example, in the following case: for example, in the following case:
\begin{center} \begin{center}
@ -269,9 +269,9 @@ and the greedy algorithm is correct.
\section{Tasks and deadlines} \section{Tasks and deadlines}
Let us now consider a problem where Let us now consider a problem where
we are given $n$ tasks with durations and deadlines, we are given $n$ tasks with durations and deadlines
and our task is to choose an order to perform the tasks. and our task is to choose an order to perform the tasks.
For each task, we get $d-x$ points For each task, we earn $d-x$ points
where $d$ is the task's deadline where $d$ is the task's deadline
and $x$ is the moment when we finished the task. and $x$ is the moment when we finished the task.
What is the largest possible total score What is the largest possible total score
@ -367,7 +367,7 @@ Here $a>b$, so we should swap the tasks:
\end{scope} \end{scope}
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Now $X$ gives $b$ points less and $Y$ gives $a$ points more, Now $X$ gives $b$ points fewer and $Y$ gives $a$ points more,
so the total score increases by $a-b > 0$. so the total score increases by $a-b > 0$.
In an optimal solution, In an optimal solution,
for any two consecutive tasks, for any two consecutive tasks,
@ -470,7 +470,7 @@ which means that the length of each
codeword is the same. codeword is the same.
For example, we can compress the string For example, we can compress the string
\texttt{AABACDACA} as follows: \texttt{AABACDACA} as follows:
\[000001001011001000\] \[00\,00\,01\,00\,10\,11\,00\,10\,00\]
Using this code, the length of the compressed Using this code, the length of the compressed
string is 18 bits. string is 18 bits.
However, we can compress the string better However, we can compress the string better
@ -496,7 +496,7 @@ An optimal code produces a compressed string
that is as short as possible. that is as short as possible.
In this case, the compressed string using In this case, the compressed string using
the optimal code is the optimal code is
\[001100101110100,\] \[0\,0\,110\,0\,10\,111\,0\,10\,0,\]
so only 15 bits are needed instead of 18 bits. so only 15 bits are needed instead of 18 bits.
Thus, thanks to a better code it was possible to Thus, thanks to a better code it was possible to
save 3 bits in the compressed string. save 3 bits in the compressed string.
@ -539,12 +539,12 @@ in the string,
and each character's codeword can be read and each character's codeword can be read
by following a path from the root to by following a path from the root to
the corresponding node. the corresponding node.
A move to the left correspons to bit 0, A move to the left corresponds to bit 0,
and a move to the right corresponds to bit 1. and a move to the right corresponds to bit 1.
Initially, each character of the string is Initially, each character of the string is
represented by a node whose weight is the represented by a node whose weight is the
number of times the character appears in the string. number of times the character occurs in the string.
Then at each step two nodes with minimum weights Then at each step two nodes with minimum weights
are combined by creating are combined by creating
a new node whose weight is the sum of the weights a new node whose weight is the sum of the weights

View File

@ -14,7 +14,7 @@ There are two uses for dynamic programming:
\begin{itemize} \begin{itemize}
\item \item
\key{Findind an optimal solution}: \key{Finding an optimal solution}:
We want to find a solution that is We want to find a solution that is
as large as possible or as small as possible. as large as possible or as small as possible.
\item \item
@ -24,14 +24,14 @@ possible solutions.
\end{itemize} \end{itemize}
We will first see how dynamic programming can We will first see how dynamic programming can
be used for finding an optimal solution, be used to find an optimal solution,
and then we will use the same idea for and then we will use the same idea for
counting the solutions. counting the solutions.
Understanding dynamic programming is a milestone Understanding dynamic programming is a milestone
in every competitive programmer's career. in every competitive programmer's career.
While the basic idea of the technique is simple, While the basic idea of the technique is simple,
the challenge is how to apply it for different problems. the challenge is how to apply it to different problems.
This chapter introduces a set of classic problems This chapter introduces a set of classic problems
that are a good starting point. that are a good starting point.
@ -47,7 +47,7 @@ In Chapter 6, we solved the problem using a
greedy algorithm that always selects the largest greedy algorithm that always selects the largest
possible coin. possible coin.
The greedy algorithm works, for example, The greedy algorithm works, for example,
when coins are euro coins, when the coins are the euro coins,
but in the general case the greedy algorithm but in the general case the greedy algorithm
does not necessarily produce an optimal solution. does not necessarily produce an optimal solution.
@ -60,15 +60,15 @@ that goes through all possibilities how to
form the sum, like a brute force algorithm. form the sum, like a brute force algorithm.
However, the dynamic programming However, the dynamic programming
algorithm is efficient because algorithm is efficient because
it uses \emph{memoization} to it uses \emph{memoization} and
calculate the answer to each subproblem only once. calculates the answer to each subproblem only once.
\subsubsection{Recursive formulation} \subsubsection{Recursive formulation}
The idea in dynamic programming is to The idea in dynamic programming is to
formulate the problem recursively so formulate the problem recursively so
that the answer to the problem can be that the answer to the problem can be
calculated from the answers for smaller calculated from answers to smaller
subproblems. subproblems.
In the coin problem, a natural recursive In the coin problem, a natural recursive
problem is as follows: problem is as follows:
@ -107,8 +107,8 @@ and $f(5)=2$ because the sum 5 can
be formed using coins 1 and 4. be formed using coins 1 and 4.
The essential property in the function is The essential property in the function is
that the value $f(x)$ can be calculated that each value of $f(x)$ can be calculated
recursively from the smaller values of the function. recursively from smaller values of the function.
For example, if the coin set is $\{1,3,4\}$, For example, if the coin set is $\{1,3,4\}$,
there are three ways to select the first coin there are three ways to select the first coin
in a solution: we can choose coin 1, 3 or 4. in a solution: we can choose coin 1, 3 or 4.
@ -133,9 +133,8 @@ In addition, it is convenient to define
\[f(x)=\infty\hspace{8px}\textrm{if $x<0$}.\] \[f(x)=\infty\hspace{8px}\textrm{if $x<0$}.\]
This means that an infinite number of coins This means that an infinite number of coins
is needed for forming a negative sum of money. is needed for forming a negative sum of money.
This prevents the situation that the recursive This prevents the function from constructing
function would form a solution where the a solution where the initial sum of money is negative.
initial sum of money is negative.
Once a recursive function that solves the problem Once a recursive function that solves the problem
has been found, has been found,
@ -159,7 +158,7 @@ and the value $10^9$ denotes infinity.
This function works but it is not efficient yet, This function works but it is not efficient yet,
because it goes through a large number because it goes through a large number
of ways to construct the sum. of ways to construct the sum.
However, the function becomes efficient by However, the function can be made efficient by
using memoization. using memoization.
\subsubsection{Memoization} \subsubsection{Memoization}
@ -170,20 +169,20 @@ Dynamic programming allows us to calculate the
value of a recursive function efficiently value of a recursive function efficiently
using \key{memoization}. using \key{memoization}.
This means that an auxiliary array is used This means that an auxiliary array is used
for storing the values of the function for recording the values of the function
for different parameters. for different parameters.
For each parameter, the value of the function For each parameter, the value of the function
is calculated recursively only once, and after this, is calculated recursively only once, and after this,
the value can be directly retrieved from the array. the value can be directly retrieved from the array.
In this problem, we can use the array In this problem, we can use an array
\begin{lstlisting} \begin{lstlisting}
int d[N]; int d[N];
\end{lstlisting} \end{lstlisting}
where $\texttt{d}[x]$ will contain where $\texttt{d}[x]$ will contain
the value $f(x)$. the value of $f(x)$.
The constant $N$ should be chosen so The constant $N$ has to be chosen so
that all required values of the function fit that all required values of the function fit
in the array. in the array.
@ -208,23 +207,23 @@ The function handles the base cases
$x=0$ and $x<0$ as previously. $x=0$ and $x<0$ as previously.
Then the function checks if Then the function checks if
$f(x)$ has already been calculated $f(x)$ has already been calculated
and stored in $\texttt{d}[x]$. in $\texttt{d}[x]$.
If $f(x)$ is found in the array, If the value of $f(x)$ is found in the array,
the function directly returns it. the function directly returns it.
Otherwise the function calculates the value Otherwise the function calculates the value
recursively and stores it in $\texttt{d}[x]$. recursively and stores it in $\texttt{d}[x]$.
Using memoization the function works Using memoization the function works
efficiently, because the answer for each $x$ efficiently, because the answer for each parameter $x$
is calculated recursively only once. is calculated recursively only once.
After a value of $f(x)$ has been stored in the array, After a value of $f(x)$ has been stored in the array,
it can be efficiently retrieved whenever the it can be efficiently retrieved whenever the
function will be called again with parameter $x$. function will be called again with the parameter $x$.
The time complexity of the resulting algorithm The time complexity of the resulting algorithm
is $O(xk)$ where the sum is $x$ and the number of is $O(xk)$ where the sum is $x$ and the number of
coins is $k$. coins is $k$.
In practice, the algorithm is usable if In practice, the algorithm can be used if
$x$ is so small that it is possible to allocate $x$ is so small that it is possible to allocate
an array for all possible function parameters. an array for all possible function parameters.
@ -294,7 +293,7 @@ while (x > 0) {
\subsubsection{Counting the number of solutions} \subsubsection{Counting the number of solutions}
Let us now consider a variation of the problem Let us now consider a variant of the problem
that is otherwise like the original problem, that is otherwise like the original problem,
but we should count the total number of solutions instead but we should count the total number of solutions instead
of finding the optimal solution. of finding the optimal solution.
@ -319,7 +318,7 @@ The difference is that when finding the optimal solution,
we maximize or minimize something in the recursion, we maximize or minimize something in the recursion,
but now we will calculate sums of numbers of solutions. but now we will calculate sums of numbers of solutions.
In the coin problem, we can define a function $f(x)$ To solve the problem, we can define a function $f(x)$
that returns the number of ways to construct that returns the number of ways to construct
the sum $x$ using the coins. the sum $x$ using the coins.
For example, $f(5)=6$ when the coins are $\{1,3,4\}$. For example, $f(5)=6$ when the coins are $\{1,3,4\}$.
@ -330,7 +329,7 @@ because to form the sum $x$, we have to first
choose some coin $c_i$ and then form the sum $x-c_i$. choose some coin $c_i$ and then form the sum $x-c_i$.
The base cases are $f(0)=1$, because there is exactly The base cases are $f(0)=1$, because there is exactly
one way to form the sum 0 using an empty set of coins, one way to form the sum 0 using an empty set of coins,
and $f(x)=0$, when $x<0$, because it's not possible and $f(x)=0$, when $x<0$, because it is not possible
to form a negative sum of money. to form a negative sum of money.
If the coin set is $\{1,3,4\}$, the function is If the coin set is $\{1,3,4\}$, the function is
@ -370,8 +369,8 @@ that it is not required to calculate the exact number
but it is enough to give the answer modulo $m$ but it is enough to give the answer modulo $m$
where, for example, $m=10^9+7$. where, for example, $m=10^9+7$.
This can be done by changing the code so that This can be done by changing the code so that
all calculations are done in modulo $m$. all calculations are done modulo $m$.
In the above code, it is enough to add the line In the above code, it suffices to add the line
\begin{lstlisting} \begin{lstlisting}
d[i] %= m; d[i] %= m;
\end{lstlisting} \end{lstlisting}
@ -380,7 +379,7 @@ after the line
d[i] += d[i-c[j]]; d[i] += d[i-c[j]];
\end{lstlisting} \end{lstlisting}
Now we have covered all basic Now we have discussed all basic
techniques related to techniques related to
dynamic programming. dynamic programming.
Since dynamic programming can be used Since dynamic programming can be used
@ -397,7 +396,7 @@ Given an array that contains $n$
numbers $x_1,x_2,\ldots,x_n$, numbers $x_1,x_2,\ldots,x_n$,
our task is to find the our task is to find the
\key{longest increasing subsequence} \key{longest increasing subsequence}
in the array. of the array.
This is a sequence of array elements This is a sequence of array elements
that goes from left to right, that goes from left to right,
and each element in the sequence is larger and each element in the sequence is larger
@ -496,8 +495,8 @@ where $i<k$ and $x_i<x_k$. In this case $f(k)=f(i)+1$.
For example, in the above example $f(7)=4$, For example, in the above example $f(7)=4$,
because the subsequence $[2,5,7]$ of length 3 because the subsequence $[2,5,7]$ of length 3
ends at position 5, and after adding the element ends at position 5, and by adding the element
at position 7 to the subsequence, at position 7 to this subsequence,
we get the optimal subsequence $[2,5,7,8]$ of length 4. we get the optimal subsequence $[2,5,7,8]$ of length 4.
An easy way to calculate the An easy way to calculate the
@ -514,7 +513,7 @@ Our next problem is to find a path
in an $n \times n$ grid in an $n \times n$ grid
from the upper-left corner to from the upper-left corner to
the lower-right corner such that the lower-right corner such that
we can only move down and right. we only move down and right.
Each square contains a number, Each square contains a number,
and the path should be constructed so and the path should be constructed so
that the sum of numbers along that the sum of numbers along
@ -570,17 +569,17 @@ upper-left corner to the lower-right corner.
We can approach the problem by We can approach the problem by
calculating for each square $(y,x)$ calculating for each square $(y,x)$
the largest possible sum on a path the maximum sum on a path
from the upper-left corner to square $(y,x)$. from the upper-left corner to square $(y,x)$.
Let $f(y,x)$ denote this sum, Let $f(y,x)$ denote this sum,
so $f(n,n)$ is the largest sum on a path so $f(n,n)$ is the maximum sum on a path
from the upper-left corner to from the upper-left corner to
the lower-right corner. the lower-right corner.
The recursive formula is based on the observation The recursive formula is based on the observation
that a path that ends at square $(y,x)$ that a path that ends at square $(y,x)$
can either come from square $(y,x-1)$ can come either from square $(y,x-1)$
or from square $(y-1,x)$: or square $(y-1,x)$:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=.65] \begin{tikzpicture}[scale=.65]
\begin{scope} \begin{scope}
@ -682,7 +681,7 @@ denote the smallest possible total weight
when a subset of objects when a subset of objects
$1 \ldots k$ is selected such $1 \ldots k$ is selected such
that the total weight is $u$. that the total weight is $u$.
The solution for the problem is the The solution to the problem is the
largest value $u$ largest value $u$
for which $0 \le u \le s$ and $f(n,u) \le x$ for which $0 \le u \le s$ and $f(n,u) \le x$
where $s=\sum_{i=1}^n a_i$. where $s=\sum_{i=1}^n a_i$.
@ -711,8 +710,8 @@ depends on the values of the objects.
The \key{edit distance} or \key{Levenshtein distance} The \key{edit distance} or \key{Levenshtein distance}
is the minimum number of editing operations is the minimum number of editing operations
needed for transforming the first string needed to transform a string
into the second string. into another string.
The allowed editing operations are as follows: The allowed editing operations are as follows:
\begin{itemize} \begin{itemize}
\item insert a character (e.g. \texttt{ABC} $\rightarrow$ \texttt{ABCA}) \item insert a character (e.g. \texttt{ABC} $\rightarrow$ \texttt{ABCA})
@ -721,10 +720,10 @@ The allowed editing operations are as follows:
\end{itemize} \end{itemize}
For example, the edit distance between For example, the edit distance between
\texttt{LOVE} and \texttt{MOVIE} is 2 \texttt{LOVE} and \texttt{MOVIE} is 2,
because we can first perform operation because we can first perform the operation
\texttt{LOVE} $\rightarrow$ \texttt{MOVE} \texttt{LOVE} $\rightarrow$ \texttt{MOVE}
(change) and then operation (change) and then the operation
\texttt{MOVE} $\rightarrow$ \texttt{MOVIE} \texttt{MOVE} $\rightarrow$ \texttt{MOVIE}
(insertion). (insertion).
This is the smallest possible number of operations, This is the smallest possible number of operations,
@ -736,7 +735,7 @@ Suppose we are given strings
$n$ and $m$ characters, respectively, $n$ and $m$ characters, respectively,
and we wish to calculate the edit distance and we wish to calculate the edit distance
between them. between them.
This can be efficiently done using This can be done using
dynamic programming in $O(nm)$ time. dynamic programming in $O(nm)$ time.
Let $f(a,b)$ denote the edit distance Let $f(a,b)$ denote the edit distance
between the first $a$ characters of \texttt{x} between the first $a$ characters of \texttt{x}
@ -756,7 +755,7 @@ and in the general case the formula is
where $c=0$ if the $a$th character of \texttt{x} where $c=0$ if the $a$th character of \texttt{x}
equals the $b$th character of \texttt{y}, equals the $b$th character of \texttt{y},
and otherwise $c=1$. and otherwise $c=1$.
The formula considers all ways how to shorten the strings: The formula considers all possible ways to shorten the strings:
\begin{itemize} \begin{itemize}
\item $f(a,b-1)$ means that a character is inserted to \texttt{x} \item $f(a,b-1)$ means that a character is inserted to \texttt{x}
\item $f(a-1,b)$ means that a character is removed from \texttt{x} \item $f(a-1,b)$ means that a character is removed from \texttt{x}
@ -819,7 +818,7 @@ in the example case:
\end{center} \end{center}
The lower-right corner of the table The lower-right corner of the table
indicates that the edit distance between tells us that the edit distance between
\texttt{LOVE} and \texttt{MOVIE} is 2. \texttt{LOVE} and \texttt{MOVIE} is 2.
The table also shows how to construct The table also shows how to construct
the shortest sequence of editing operations. the shortest sequence of editing operations.
@ -889,7 +888,7 @@ the edit distance between \texttt{LOV} and \texttt{MOV}, etc.
\section{Counting tilings} \section{Counting tilings}
Sometimes the states in a dynamic programming solution Sometimes the states of a dynamic programming solution
are more complex than fixed combinations of numbers. are more complex than fixed combinations of numbers.
As an example, As an example,
we consider the problem of calculating we consider the problem of calculating
@ -971,9 +970,9 @@ so that the shorter side has length $m$,
because the factor $4^{2m}$ dominates the time complexity. because the factor $4^{2m}$ dominates the time complexity.
It is possible to make the solution more efficient It is possible to make the solution more efficient
by using a better representation for the rows as strings. by using a better representation for the rows.
It turns out that it is sufficient to know the It turns out that it is sufficient to know which
columns of the previous row that contain the first square columns of the previous row contain the upper square
of a vertical tile. of a vertical tile.
Thus, we can represent a row using only characters Thus, we can represent a row using only characters
$\sqcap$ and $\Box$, where $\Box$ is a combination $\sqcap$ and $\Box$, where $\Box$ is a combination