-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
hamilton paths, knight tour, de bruikn sequences
- Loading branch information
1 parent
cc08cd7
commit 0221520
Showing
4 changed files
with
252 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# De Bruijn sequences | ||
|
||
A **De Bruijn sequence** | ||
is a string that contains | ||
every string of length $n$ | ||
exactly once as a substring, for a fixed | ||
alphabet of $k$ characters. | ||
The length of such a string is | ||
$k^n+n-1$ characters. | ||
For example, when $n=3$ and $k=2$, | ||
an example of a De Bruijn sequence is | ||
|
||
$$ | ||
0001011100 | ||
$$ | ||
|
||
The substrings of this string are all | ||
combinations of three bits: | ||
000, 001, 010, 011, 100, 101, 110 and 111. | ||
|
||
It turns out that each De Bruijn sequence | ||
corresponds to an Eulerian path in a graph. | ||
The idea is to construct a graph where | ||
each node contains a string of $n-1$ characters | ||
and each edge adds one character to the string. | ||
The following graph corresponds to the above scenario: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.8] | ||
\node[draw, circle] (00) at (-3,0) {00}; | ||
\node[draw, circle] (11) at (3,0) {11}; | ||
\node[draw, circle] (01) at (0,2) {01}; | ||
\node[draw, circle] (10) at (0,-2) {10}; | ||
|
||
\path[draw,thick,->] (00) edge [bend left=20] node[font=\small,label=1] {} (01); | ||
\path[draw,thick,->] (01) edge [bend left=20] node[font=\small,label=1] {} (11); | ||
\path[draw,thick,->] (11) edge [bend left=20] node[font=\small,label=below:0] {} (10); | ||
\path[draw,thick,->] (10) edge [bend left=20] node[font=\small,label=below:0] {} (00); | ||
|
||
\path[draw,thick,->] (01) edge [bend left=30] node[font=\small,label=right:0] {} (10); | ||
\path[draw,thick,->] (10) edge [bend left=30] node[font=\small,label=left:1] {} (01); | ||
|
||
\path[draw,thick,-] (00) edge [loop left] node[font=\small,label=below:0] {} (00); | ||
\path[draw,thick,-] (11) edge [loop right] node[font=\small,label=below:1] {} (11); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
An Eulerian path in this graph corresponds to a string | ||
that contains all strings of length $n$. | ||
The string contains the characters of the starting node | ||
and all characters of the edges. | ||
The starting node has $n-1$ characters | ||
and there are $k^n$ characters in the edges, | ||
so the length of the string is $k^n+n-1$. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
# Hamiltonian paths | ||
|
||
A **Hamiltonian path** | ||
is a path | ||
that visits each node of the graph exactly once. | ||
For example, the graph | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (1,5) {1}; | ||
\node[draw, circle] (2) at (3,5) {2}; | ||
\node[draw, circle] (3) at (5,4) {3}; | ||
\node[draw, circle] (4) at (1,3) {4}; | ||
\node[draw, circle] (5) at (3,3) {5}; | ||
|
||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (2) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (5); | ||
\path[draw,thick,-] (2) -- (5); | ||
\path[draw,thick,-] (4) -- (5); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
contains a Hamiltonian path from node 1 to node 3: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (1,5) {1}; | ||
\node[draw, circle] (2) at (3,5) {2}; | ||
\node[draw, circle] (3) at (5,4) {3}; | ||
\node[draw, circle] (4) at (1,3) {4}; | ||
\node[draw, circle] (5) at (3,3) {5}; | ||
|
||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (2) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (5); | ||
\path[draw,thick,-] (2) -- (5); | ||
\path[draw,thick,-] (4) -- (5); | ||
|
||
\path[draw=red,thick,->,line width=2pt] (1) -- node[font=\small,label={[red]left:1.}] {} (4); | ||
\path[draw=red,thick,->,line width=2pt] (4) -- node[font=\small,label={[red]south:2.}] {} (5); | ||
\path[draw=red,thick,->,line width=2pt] (5) -- node[font=\small,label={[red]left:3.}] {} (2); | ||
\path[draw=red,thick,->,line width=2pt] (2) -- node[font=\small,label={[red]north:4.}] {} (3); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
If a Hamiltonian path begins and ends at the same node, | ||
it is called a **Hamiltonian circuit**. | ||
The graph above also has an Hamiltonian circuit | ||
that begins and ends at node 1: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (1,5) {1}; | ||
\node[draw, circle] (2) at (3,5) {2}; | ||
\node[draw, circle] (3) at (5,4) {3}; | ||
\node[draw, circle] (4) at (1,3) {4}; | ||
\node[draw, circle] (5) at (3,3) {5}; | ||
|
||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (2) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (5); | ||
\path[draw,thick,-] (2) -- (5); | ||
\path[draw,thick,-] (4) -- (5); | ||
|
||
\path[draw=red,thick,->,line width=2pt] (1) -- node[font=\small,label={[red]north:1.}] {} (2); | ||
\path[draw=red,thick,->,line width=2pt] (2) -- node[font=\small,label={[red]north:2.}] {} (3); | ||
\path[draw=red,thick,->,line width=2pt] (3) -- node[font=\small,label={[red]south:3.}] {} (5); | ||
\path[draw=red,thick,->,line width=2pt] (5) -- node[font=\small,label={[red]south:4.}] {} (4); | ||
\path[draw=red,thick,->,line width=2pt] (4) -- node[font=\small,label={[red]left:5.}] {} (1); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
## Existence | ||
|
||
No efficient method is known for testing if a graph | ||
contains a Hamiltonian path, and the problem is NP-hard. | ||
Still, in some special cases, we can be certain | ||
that a graph contains a Hamiltonian path. | ||
|
||
A simple observation is that if the graph is complete, | ||
i.e., there is an edge between all pairs of nodes, | ||
it also contains a Hamiltonian path. | ||
Also stronger results have been achieved: | ||
|
||
- **Dirac's theorem**: | ||
If the degree of each node is at least $n/2$, | ||
the graph contains a Hamiltonian path. | ||
- **Ore's theorem**: | ||
If the sum of degrees of each non-adjacent pair of nodes | ||
is at least $n$, | ||
the graph contains a Hamiltonian path. | ||
|
||
A common property in these theorems and other results is | ||
that they guarantee the existence of a Hamiltonian path | ||
if the graph has _a large number_ of edges. | ||
This makes sense, because the more edges the graph contains, | ||
the more possibilities there is to construct a Hamiltonian path. | ||
|
||
## Construction | ||
|
||
Since there is no efficient way to check if a Hamiltonian | ||
path exists, it is clear that there is also no method | ||
to efficiently construct the path, because otherwise | ||
we could just try to construct the path and see | ||
whether it exists. | ||
|
||
A simple way to search for a Hamiltonian path is | ||
to use a backtracking algorithm that goes through all | ||
possible ways to construct the path. | ||
The time complexity of such an algorithm is at least $O(n!)$, | ||
because there are $n!$ different ways to choose the order of $n$ nodes. | ||
|
||
A more efficient solution is based on dynamic programming | ||
(see Chapter 10.5). | ||
The idea is to calculate values | ||
of a function `possible(S,x)`, | ||
where $S$ is a subset of nodes and $x$ | ||
is one of the nodes. | ||
The function indicates whether there is a Hamiltonian path | ||
that visits the nodes of $S$ and ends at node $x$. | ||
It is possible to implement this solution in $O(2^n n^2)$ time. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Knight’s tours | ||
|
||
A **knight's tour** is a sequence of moves | ||
of a knight on an $n \times n$ chessboard | ||
following the rules of chess such that the knight | ||
visits each square exactly once. | ||
A knight's tour is called a _closed_ tour | ||
if the knight finally returns to the starting square and | ||
otherwise it is called an _open_ tour. | ||
|
||
For example, here is an open knight's tour on a $5 \times 5$ board: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.7] | ||
\draw (0,0) grid (5,5); | ||
\node at (0.5,4.5) {1}; | ||
\node at (1.5,4.5) {4}; | ||
\node at (2.5,4.5) {11}; | ||
\node at (3.5,4.5) {16}; | ||
\node at (4.5,4.5) {25}; | ||
\node at (0.5,3.5) {12}; | ||
\node at (1.5,3.5) {17}; | ||
\node at (2.5,3.5) {2}; | ||
\node at (3.5,3.5) {5}; | ||
\node at (4.5,3.5) {10}; | ||
\node at (0.5,2.5) {3}; | ||
\node at (1.5,2.5) {20}; | ||
\node at (2.5,2.5) {7}; | ||
\node at (3.5,2.5) {24}; | ||
\node at (4.5,2.5) {15}; | ||
\node at (0.5,1.5) {18}; | ||
\node at (1.5,1.5) {13}; | ||
\node at (2.5,1.5) {22}; | ||
\node at (3.5,1.5) {9}; | ||
\node at (4.5,1.5) {6}; | ||
\node at (0.5,0.5) {21}; | ||
\node at (1.5,0.5) {8}; | ||
\node at (2.5,0.5) {19}; | ||
\node at (3.5,0.5) {14}; | ||
\node at (4.5,0.5) {23}; | ||
\end{tikzpicture} | ||
</script> | ||
|
||
A knight's tour corresponds to a Hamiltonian path in a graph | ||
whose nodes represent the squares of the board, | ||
and two nodes are connected with an edge if a knight | ||
can move between the squares according to the rules of chess. | ||
|
||
A natural way to construct a knight's tour is to use backtracking. | ||
The search can be made more efficient by using | ||
_heuristics_ that attempt to guide the knight so that | ||
a complete tour will be found quickly. | ||
|
||
## Warnsdorf's rule | ||
|
||
**Warnsdorf's rule** is a simple and effective heuristic | ||
for finding a knight's tour[^1]. | ||
Using the rule, it is possible to efficiently construct a tour | ||
even on a large board. | ||
The idea is to always move the knight so that it ends up | ||
in a square where the number of possible moves is as | ||
_small_ as possible. | ||
|
||
For example, in the following situation, there are five | ||
possible squares to which the knight can move (squares $a \ldots e$): | ||
|
||
___ | ||
|
||
[^1] This heuristic was proposed in Warnsdorf's book [69] in 1823. There are also polynomial algorithms for finding knight's tours [52], but they are more complicated. |