New references etc.

This commit is contained in:
Antti H S Laaksonen 2017-02-25 16:51:29 +02:00
parent 702f5ac9c3
commit c18f6a808f
9 changed files with 61 additions and 132 deletions

View File

@ -778,7 +778,7 @@ n! & = & n \cdot (n-1)! \\
\index{Fibonacci number}
The \key{Fibonacci numbers} arise in many situations.
The \key{Fibonacci numbers}\footnote{Fibonacci (c. 1175--1250) was an Italian mathematician.} arise in many situations.
They can be defined recursively as follows:
\[
\begin{array}{lcl}
@ -790,7 +790,8 @@ f(n) & = & f(n-1)+f(n-2) \\
The first Fibonacci numbers are
\[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, \ldots\]
There is also a closed-form formula
for calculating Fibonacci numbers:
for calculating Fibonacci numbers\footnote{This formula is sometimes called
\index{Binet's formula} \key{Binet's formula}.}:
\[f(n)=\frac{(1 + \sqrt{5})^n - (1-\sqrt{5})^n}{2^n \sqrt{5}}.\]
\subsubsection{Logarithms}

View File

@ -281,7 +281,11 @@ Still, there are many important problems for which
no polynomial algorithm is known, i.e.,
nobody knows how to solve them efficiently.
\key{NP-hard} problems are an important set
of problems for which no polynomial algorithm is known \cite{gar79}.
of problems for which no polynomial algorithm
is known\footnote{A classic book on this topic is
M. R. Garey's and D. S. Johnson's
\emph{Computers and Intractability: A Guide to the Theory
of NP-Completeness} \cite{gar79}.}.
\section{Estimating efficiency}
@ -352,7 +356,7 @@ time and even in $O(n)$ time.
Given an array of $n$ integers $x_1,x_2,\ldots,x_n$,
our task is to find the
\key{maximum subarray sum}\footnote{Bentley's
\key{maximum subarray sum}\footnote{J. Bentley's
book \emph{Programming Pearls} \cite{ben86} made this problem popular.}, i.e.,
the largest possible sum of numbers
in a contiguous region in the array.
@ -470,7 +474,9 @@ After this change, the time complexity is $O(n^2)$.
\subsubsection{Algorithm 3}
Surprisingly, it is possible to solve the problem
in $O(n)$ time, which means that we can remove
in $O(n)$ time\footnote{In \cite{ben86}, this linear algorithm
is attributed to J. B. Kadene, and the algorithm is sometimes
called \index{Kadene's algorithm} \key{Kadene's algorithm}.}, which means that we can remove
one more loop.
The idea is to calculate for each array position
the maximum sum of a subarray that ends at that position.

View File

@ -326,7 +326,8 @@ of the algorithm is at least $O(n^2)$.
It is possible to sort an array efficiently
in $O(n \log n)$ time using algorithms
that are not limited to swapping consecutive elements.
One such algorithm is \key{mergesort}
One such algorithm is \key{mergesort}\footnote{According to \cite{knu98},
mergesort was invented by J. von Neumann in 1945.}
that is based on recursion.
Mergesort sorts a subarray \texttt{t}$[a,b]$ as follows:

View File

@ -196,7 +196,7 @@ for (auto x : s) {
}
\end{lstlisting}
An important property of sets
An important property of sets is
that all the elements are \emph{distinct}.
Thus, the function \texttt{count} always returns
either 0 (the element is not in the set)
@ -723,7 +723,7 @@ $5 \cdot 10^6$ & $10{,}0$ s & $2{,}3$ s & $0{,}9$ s \\
\end{tabular}
\end{center}
Algorithm 1 and 2 are equal except that
Algorithms 1 and 2 are equal except that
they use different set structures.
In this problem, this choice has an important effect on
the running time, because algorithm 2

View File

@ -436,18 +436,18 @@ the $4 \times 4$ board are numbered as follows:
\end{tikzpicture}
\end{center}
Let $q(n)$ denote the number of ways
to place $n$ queens to te $n \times n$ chessboard.
The above backtracking
algorithm tells us that
there are 92 ways to place 8
queens to the $8 \times 8$ chessboard.
algorithm tells us that $q(n)=92$.
When $n$ increases, the search quickly becomes slow,
because the number of the solutions increases
exponentially.
For example, calculating the ways to
place 16 queens to the $16 \times 16$
chessboard already takes about a minute
on a modern computer
(there are 14772512 solutions).
For example, calculating $q(16)=14772512$
using the above algorithm already takes about a minute
on a modern computer\footnote{There is no known way to efficiently
calculate larger values of $q(n)$. The current record is
$q(27)=234907967154122528$, calculated in 2016 \cite{q27}.}.
\section{Pruning the search}
@ -716,7 +716,8 @@ check if the sum of any of the subsets is $x$.
The running time of such a solution is $O(2^n)$,
because there are $2^n$ subsets.
However, using the meet in the middle technique,
we can achieve a more efficient $O(2^{n/2})$ time solution.
we can achieve a more efficient $O(2^{n/2})$ time solution\footnote{This
technique was introduced in 1974 by E. Horowitz and S. Sahni \cite{hor74}.}.
Note that $O(2^n)$ and $O(2^{n/2})$ are different
complexities because $2^{n/2}$ equals $\sqrt{2^n}$.

View File

@ -530,7 +530,9 @@ the string \texttt{AB} or the string \texttt{C}.
\subsubsection{Huffman coding}
\key{Huffman coding} \cite{huf52} is a greedy algorithm
\key{Huffman coding}\footnote{D. A. Huffman discovered this method
when solving a university course assignment
and published the algorithm in 1952 \cite{huf52}.} is a greedy algorithm
that constructs an optimal code for
compressing a given string.
The algorithm builds a binary tree
@ -672,113 +674,3 @@ character & codeword \\
\texttt{D} & 111 \\
\end{tabular}
\end{center}
% \subsubsection{Miksi algoritmi toimii?}
%
% Huffmanin koodaus on ahne algoritmi, koska se
% yhdistää aina kaksi solmua, joiden painot ovat
% pienimmät.
% Miksi on varmaa, että tämä menetelmä tuottaa
% aina optimaalisen koodin?
%
% Merkitään $c(x)$ merkin $x$ esiintymiskertojen
% määrää merkkijonossa sekä $s(x)$
% merkkiä $x$ vastaavan koodisanan pituutta.
% Näitä merkintöjä käyttäen merkkijonon
% bittiesityksen pituus on
% \[\sum_x c(x) \cdot s(x),\]
% missä summa käy läpi kaikki merkkijonon merkit.
% Esimerkiksi äskeisessä esimerkissä
% bittiesityksen pituus on
% \[5 \cdot 1 + 1 \cdot 3 + 2 \cdot 2 + 1 \cdot 3 = 15.\]
% Hyödyllinen havainto on, että $s(x)$ on yhtä suuri kuin
% merkkiä $x$ vastaavan solmun \emph{syvyys} puussa
% eli matka puun huipulta solmuun.
%
% Perustellaan ensin, miksi optimaalista koodia vastaa
% aina binääripuu, jossa jokaisesta solmusta lähtee
% alaspäin joko kaksi haaraa tai ei yhtään haaraa.
% Tehdään vastaoletus, että jostain solmusta lähtisi
% alaspäin vain yksi haara.
% Esimerkiksi seuraavassa puussa tällainen tilanne on solmussa $a$:
% \begin{center}
% \begin{tikzpicture}[scale=0.9]
% \node[draw, circle, minimum size=20pt] (3) at (3,1) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (2) at (4,0) {$b$};
% \node[draw, circle, minimum size=20pt] (5) at (5,1) {$a$};
% \node[draw, circle, minimum size=20pt] (6) at (4,2) {\phantom{$a$}};
%
% \path[draw,thick,-] (2) -- (5);
% \path[draw,thick,-] (3) -- (6);
% \path[draw,thick,-] (5) -- (6);
% \end{tikzpicture}
% \end{center}
% Tällainen solmu $a$ on kuitenkin aina turha, koska se
% tuo vain yhden bitin lisää polkuihin, jotka kulkevat
% solmun kautta, eikä sen avulla voi erottaa kahta
% koodisanaa toisistaan. Niinpä kyseisen solmun voi poistaa
% puusta, minkä seurauksena syntyy parempi koodi,
% eli optimaalista koodia vastaavassa puussa ei voi olla
% solmua, josta lähtee vain yksi haara.
%
% Perustellaan sitten, miksi on joka vaiheessa optimaalista
% yhdistää kaksi solmua, joiden painot ovat pienimmät.
% Tehdään vastaoletus, että solmun $a$ paino on pienin,
% mutta sitä ei saisi yhdistää aluksi toiseen solmuun,
% vaan sen sijasta tulisi yhdistää solmu $b$
% ja jokin toinen solmu:
% \begin{center}
% \begin{tikzpicture}[scale=0.9]
% \node[draw, circle, minimum size=20pt] (1) at (0,0) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (2) at (-2,-1) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (3) at (2,-1) {$a$};
% \node[draw, circle, minimum size=20pt] (4) at (-3,-2) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (5) at (-1,-2) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (8) at (-2,-3) {$b$};
% \node[draw, circle, minimum size=20pt] (9) at (0,-3) {\phantom{$a$}};
%
% \path[draw,thick,-] (1) -- (2);
% \path[draw,thick,-] (1) -- (3);
% \path[draw,thick,-] (2) -- (4);
% \path[draw,thick,-] (2) -- (5);
% \path[draw,thick,-] (5) -- (8);
% \path[draw,thick,-] (5) -- (9);
% \end{tikzpicture}
% \end{center}
% Solmuille $a$ ja $b$ pätee
% $c(a) \le c(b)$ ja $s(a) \le s(b)$.
% Solmut aiheuttavat bittiesityksen pituuteen lisäyksen
% \[c(a) \cdot s(a) + c(b) \cdot s(b).\]
% Tarkastellaan sitten toista tilannetta,
% joka on muuten samanlainen kuin ennen,
% mutta solmut $a$ ja $b$ on vaihdettu keskenään:
% \begin{center}
% \begin{tikzpicture}[scale=0.9]
% \node[draw, circle, minimum size=20pt] (1) at (0,0) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (2) at (-2,-1) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (3) at (2,-1) {$b$};
% \node[draw, circle, minimum size=20pt] (4) at (-3,-2) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (5) at (-1,-2) {\phantom{$a$}};
% \node[draw, circle, minimum size=20pt] (8) at (-2,-3) {$a$};
% \node[draw, circle, minimum size=20pt] (9) at (0,-3) {\phantom{$a$}};
%
% \path[draw,thick,-] (1) -- (2);
% \path[draw,thick,-] (1) -- (3);
% \path[draw,thick,-] (2) -- (4);
% \path[draw,thick,-] (2) -- (5);
% \path[draw,thick,-] (5) -- (8);
% \path[draw,thick,-] (5) -- (9);
% \end{tikzpicture}
% \end{center}
% Osoittautuu, että tätä puuta vastaava koodi on
% \emph{yhtä hyvä tai parempi} kuin alkuperäinen koodi, joten vastaoletus
% on väärin ja Huffmanin koodaus
% toimiikin oikein, jos se yhdistää aluksi solmun $a$
% jonkin solmun kanssa.
% Tämän perustelee seuraava epäyhtälöketju:
% \[\begin{array}{rcl}
% c(b) & \ge & c(a) \\
% c(b)\cdot(s(b)-s(a)) & \ge & c(a)\cdot (s(b)-s(a)) \\
% c(b)\cdot s(b)-c(b)\cdot s(a) & \ge & c(a)\cdot s(b)-c(a)\cdot s(a) \\
% c(a)\cdot s(a)+c(b)\cdot s(b) & \ge & c(a)\cdot s(b)+c(b)\cdot s(a) \\
% \end{array}\]

View File

@ -708,7 +708,8 @@ depends on the values of the objects.
\index{edit distance}
\index{Levenshtein distance}
The \key{edit distance} or \key{Levenshtein distance}
The \key{edit distance} or \key{Levenshtein distance}\footnote{The distance
is named after V. I. Levenshtein who discussed it in connection with binary codes \cite{lev66}.}
is the minimum number of editing operations
needed to transform a string
into another string.

View File

@ -440,7 +440,8 @@ we can conclude that $\textrm{rmq}(2,7)=1$.
\index{binary indexed tree}
\index{Fenwick tree}
A \key{binary indexed tree} or \key{Fenwick tree} \cite{fen94}
A \key{binary indexed tree} or \key{Fenwick tree}\footnote{The
binary indexed tree structure was presented by P. M. Fenwick in 1994 \cite{fen94}.}
can be seen as a dynamic version of a prefix sum array.
This data structure supports two $O(\log n)$ time operations:
calculating the sum of elements in a range
@ -738,7 +739,9 @@ takes $O(1)$ time using bit operations.
\index{segment tree}
A \key{segment tree} is a data structure
A \key{segment tree}\footnote{The origin of this structure is unknown.
The bottom-up-implementation in this chapter corresponds to
the implementation in \cite{sta06}.} is a data structure
that supports two operations:
processing a range query and
modifying an element in the array.

View File

@ -107,7 +107,13 @@
Computer Science and Computational Biology},
Cambridge University Press, 1997.
\bibitem{hor74}
E. Horowitz and S. Sahni.
Computing partitions with applications to the knapsack problem.
\emph{Journal of the ACM}, 21(2):277--292, 1974.
\bibitem{huf52}
D. A. Huffman.
A method for the construction of minimum-redundancy codes.
\emph{Proceedings of the IRE}, 40(9):1098--1101, 1952.
@ -125,11 +131,20 @@
The statistics of dimers on a lattice: I. The number of dimer arrangements on a quadratic lattice.
\emph{Physica}, 27(12):1209--1225, 1961.
\bibitem{knu98}
D. E. Knuth.
\emph{The Art of Computer Programming. Volume 3: Sorting and Searching}, AddisonWesley, 1998 (2nd edition).
\bibitem{kru56}
J. B. Kruskal.
On the shortest spanning subtree of a graph and the traveling salesman problem.
\emph{Proceedings of the American Mathematical Society}, 7(1):48--50, 1956.
\bibitem{lev66}
V. I. Levenshtein.
Binary codes capable of correcting deletions, insertions, and reversals.
\emph{Soviet physics doklady}, 10(8):707--710, 1966.
\bibitem{mai84}
M. G. Main and R. J. Lorentz.
An $O(n \log n)$ algorithm for finding all repetitions in a string.
@ -145,11 +160,20 @@
Shortest connection networks and some generalizations.
\emph{Bell System Technical Journal}, 36(6):1389--1401, 1957.
\bibitem{q27}
27-Queens Puzzle: Massively Parallel Enumeration and Solution Counting.
\url{https://github.com/preusser/q27}
\bibitem{sha81}
M. Sharir.
A strong-connectivity algorithm and its applications in data flow analysis.
\emph{Computers \& Mathematics with Applications}, 7(1):67--72, 1981.
\bibitem{sta06}
P. Stańczyk.
\emph{Algorytmika praktyczna w konkursach Informatycznych},
MSc thesis, University of Warsaw, 2006.
\bibitem{str69}
V. Strassen.
Gaussian elimination is not optimal.