Chapter 12 first version

This commit is contained in:
Antti H S Laaksonen 2017-01-07 19:17:37 +02:00
parent a0abff3f0a
commit ca5ac0d7a7
1 changed files with 77 additions and 174 deletions

View File

@ -345,31 +345,29 @@ while (!q.empty()) {
} }
\end{lstlisting} \end{lstlisting}
\section{Sovelluksia} \section{Applications}
Verkon läpikäynnin avulla Using the graph search algorithms,
saa selville monia asioita we can check many properties of the graph.
verkon rakenteesta. Usually, either depth-first search or
Läpikäynnin voi yleensä aina toteuttaa bredth-first search can be used,
joko syvyyshaulla tai leveyshaulla, but in practice, depth-first search
mutta käytännössä syvyyshaku on parempi valinta, is a better choice because it is
koska sen toteutus on helpompi. easier to implement.
Oletamme seuraavaksi, että käsiteltävänä on In the following applications we will
suuntaamaton verkko. assume that the graph is undirected.
\subsubsection{Yhtenäisyyden tarkastaminen} \subsubsection{Connectivity check}
\index{yhtenxisyys@yhtenäisyys} \index{connected graph}
Verkko on yhtenäinen, A graph is connected if there is a path
jos mistä tahansa solmuista between any two nodes in the graph.
pääsee kaikkiin muihin solmuihin. Thus, we can check if a graph is connected
Niinpä verkon yhtenäisyys selviää by selecting an arbitrary node and
aloittamalla läpikäynti finding out if we can reach all other nodes.
jostakin verkon solmusta ja
tarkastamalla, pääseekö siitä kaikkiin solmuihin.
Esimerkiksi verkossa For example, in the graph
\begin{center} \begin{center}
\begin{tikzpicture} \begin{tikzpicture}
\node[draw, circle] (2) at (7,5) {$2$}; \node[draw, circle] (2) at (7,5) {$2$};
@ -384,8 +382,8 @@ Esimerkiksi verkossa
\path[draw,thick,-] (2) -- (5); \path[draw,thick,-] (2) -- (5);
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
solmusta $1$ alkava syvyyshaku löytää seuraavat a depth-first search from node $1$ visits
solmut: the following nodes:
\begin{center} \begin{center}
\begin{tikzpicture} \begin{tikzpicture}
\node[draw, circle] (2) at (7,5) {$2$}; \node[draw, circle] (2) at (7,5) {$2$};
@ -405,22 +403,22 @@ solmut:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Koska syvyyshaku ei pääse kaikkiin solmuihin, Since the search didn't visit all the nodes,
tämä tarkoittaa, että verkko ei ole yhtenäinen. we can conclude that the graph is not connected.
Vastaavalla tavalla voi etsiä myös verkon komponentit In a similar way, we can also find all components
käymällä solmut läpi ja aloittamalla uuden syvyyshaun in a graph by iterating trough the nodes and always
aina, jos käsiteltävä solmu ei kuulu vielä mihinkään komponenttiin. starting a new depth-first search if the node
doesn't belong to a component.
\subsubsection{Syklin etsiminen} \subsubsection{Finding cycles}
\index{sykli@sykli} \index{cycle}
Verkossa on sykli, A graph contains a cycle if during a graph search,
jos jonkin komponentin läpikäynnin we find a node whose neighbor (other than the
aikana tulee vastaan solmu, previous node in the current path) has already been
jonka naapuri on jo käsitelty visited.
ja solmuun ei ole saavuttu kyseisen naapurin kautta. For example, the graph
Esimerkiksi verkossa
\begin{center} \begin{center}
\begin{tikzpicture} \begin{tikzpicture}
\node[draw, circle,fill=lightgray] (2) at (7,5) {$2$}; \node[draw, circle,fill=lightgray] (2) at (7,5) {$2$};
@ -442,46 +440,39 @@ Esimerkiksi verkossa
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
on sykli, koska tultaessa solmusta 2 solmuun 5 contains a cycle because when we move from
havaitaan, että naapurina oleva solmu 3 on jo käsitelty. node 2 to node 5 it turns out
Niinpä verkossa täytyy olla solmun 3 kautta that the neighbor node 3 has already been visited.
kulkeva sykli. Thus, the graph contains a cycle that goes through node 3,
Tällainen sykli on esimerkiksi for example, $3 \rightarrow 2 \rightarrow 5 \rightarrow 3$.
$3 \rightarrow 2 \rightarrow 5 \rightarrow 3$.
Syklin olemassaolon voi myös päätellä laskemalla, Another way to find out whether a graph contains a cycle
montako solmua ja kaarta komponentissa on. is to simply calculate the number of nodes and edges
Jos komponentissa on $c$ solmua ja siinä ei ole sykliä, in every component.
niin siinä on oltava tarkalleen $c-1$ kaarta. If a component contains $c$ nodes and no cycle,
Jos kaaria on $c$ tai enemmän, niin komponentissa it must contain exactly $c-1$ edges.
on varmasti sykli. If there are $c$ or more edges, the component
always contains a cycle.
\subsubsection{Kaksijakoisuuden tarkastaminen} \subsubsection{Bipartiteness check}
\index{kaksijakoisuus@kaksijakoisuus} \index{bipartite graph}
Verkko on kaksijakoinen, A graph is bipartite if its nodes can be colored
jos sen solmut voi värittää using two colors so that there are no adjacent
kahdella värillä nodes with same color.
niin, että kahta samanväristä It is suprisingly easy to check if a graph
solmua ei ole vierekkäin. is bipartite using graph search algorithms.
On yllättävän helppoa selvittää
verkon läpikäynnin avulla,
onko verkko kaksijakoinen.
Ideana on värittää alkusolmu The idea is to color the starting node blue,
siniseksi, sen kaikki naapurit all its neighbors red, all their neighbors blue, and so on.
punaiseksi, niiden kaikki naapurit If at some point of the search we notice that
siniseksi, jne. two adjacent nodes have the same color,
Jos jossain vaiheessa this means that the graph is not bipartite.
ilmenee ristiriita Otherwise the graph is bipartite and one coloring
(saman solmun tulisi olla sekä has been found.
sininen että punainen),
verkko ei ole kaksijakoinen.
Muuten verkko on kaksijakoinen
ja yksi väritys on muodostunut.
Esimerkiksi verkko For example, the graph
\begin{center} \begin{center}
\begin{tikzpicture} \begin{tikzpicture}
\node[draw, circle] (2) at (5,5) {$2$}; \node[draw, circle] (2) at (5,5) {$2$};
@ -498,9 +489,8 @@ Esimerkiksi verkko
\path[draw,thick,-] (5) -- (3); \path[draw,thick,-] (5) -- (3);
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
ei ole kaksijakoinen, koska is not bipartite because a search from node 1
läpikäynti solmusta 1 alkaen produces the following situation:
aiheuttaa seuraavan ristiriidan:
\begin{center} \begin{center}
\begin{tikzpicture} \begin{tikzpicture}
\node[draw, circle,fill=red!40] (2) at (5,5) {$2$}; \node[draw, circle,fill=red!40] (2) at (5,5) {$2$};
@ -522,107 +512,20 @@ aiheuttaa seuraavan ristiriidan:
\path[draw=red,thick,->,line width=2pt] (5) -- (2); \path[draw=red,thick,->,line width=2pt] (5) -- (2);
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Tässä vaiheessa havaitaan, We notice that the color or both node 2 and node 5
että sekä solmun 2 että solmun 5 väri on punainen, is red, while they are adjacent nodes in the graph.
vaikka solmut ovat vierekkäin verkossa, Thus, the graph is not bipartite.
joten verkko ei ole kaksijakoinen.
Tämä algoritmi on luotettava tapa selvittää This algorithm always works because when there
verkon kaksijakoisuus, are only two colors available,
koska kun värejä on vain kaksi, the color of the starting node in a component
ensimmäisen solmun värin valinta determines the colors of all other nodes in the component.
määrittää kaikkien muiden It doesn't make any difference whether the
samassa komponentissa olevien starting node is red or blue.
solmujen värin.
Ei ole merkitystä,
kumman värin ensimmäinen
solmu saa.
Huomaa, että yleensä ottaen on vaikeaa
selvittää, voiko verkon solmut
värittää $k$ värillä niin,
ettei missään kohtaa ole vierekkäin
kahta samanväristä solmua.
Edes tapaukseen $k=3$ ei tunneta
mitään tehokasta algoritmia,
vaan kyseessä on NP-vaikea ongelma.
%
% \section{Labyrintin käsittely}
%
% Labyrintti on ruudukko, joka muodostuu lattia- ja seinäruuduista,
% ja labyrintissa on sallittua kulkea lattiaruutuja pitkin.
% Labyrinttia
% \begin{center}
% \begin{tikzpicture}[scale=0.7]
% \fill[color=gray] (0,0) rectangle (8,1);
% \fill[color=gray] (0,5) rectangle (8,6);
% \fill[color=gray] (0,0) rectangle (1,6);
% \fill[color=gray] (7,0) rectangle (8,6);
%
% \fill[color=gray] (2,0) rectangle (3,4);
% \fill[color=gray] (4,2) rectangle (6,4);
%
% \draw (0,0) grid (8,6);
%
% \node at (1.5,1.5) {$a$};
% \node at (6.5,3.5) {$b$};
% \end{tikzpicture}
% \end{center}
% vastaa luontevasti verkko
% \begin{center}
% \begin{tikzpicture}[scale=0.7]
% \node[draw,circle,minimum size=20pt] (a) at (1,1) {$a$};
% \node[draw,circle,minimum size=20pt] (b) at (1,2.5) {};
% \node[draw,circle,minimum size=20pt] (c) at (1,4) {};
% \node[draw,circle,minimum size=20pt] (d) at (1,5.5) {};
% \node[draw,circle,minimum size=20pt] (e) at (2.5,5.5) {};
% \node[draw,circle,minimum size=20pt] (f) at (4,5.5) {};
% \node[draw,circle,minimum size=20pt] (g) at (5.5,5.5) {};
% \node[draw,circle,minimum size=20pt] (h) at (7,5.5) {};
% \node[draw,circle,minimum size=20pt] (i) at (8.5,5.5) {};
% \node[draw,circle,minimum size=20pt] (j) at (8.5,4) {$b$};
% \node[draw,circle,minimum size=20pt] (k) at (8.5,2.5) {};
% \node[draw,circle,minimum size=20pt] (l) at (8.5,1) {};
% \node[draw,circle,minimum size=20pt] (m) at (7,1) {};
% \node[draw,circle,minimum size=20pt] (n) at (5.5,1) {};
% \node[draw,circle,minimum size=20pt] (o) at (4,1) {};
% \node[draw,circle,minimum size=20pt] (p) at (4,2.5) {};
% \node[draw,circle,minimum size=20pt] (q) at (4,4) {};
%
% \path[draw,thick,-] (a) -- (b);
% \path[draw,thick,-] (b) -- (c);
% \path[draw,thick,-] (c) -- (d);
% \path[draw,thick,-] (d) -- (e);
% \path[draw,thick,-] (e) -- (f);
% \path[draw,thick,-] (f) -- (g);
% \path[draw,thick,-] (g) -- (h);
% \path[draw,thick,-] (h) -- (i);
% \path[draw,thick,-] (i) -- (j);
% \path[draw,thick,-] (j) -- (k);
% \path[draw,thick,-] (k) -- (l);
% \path[draw,thick,-] (l) -- (m);
% \path[draw,thick,-] (m) -- (n);
% \path[draw,thick,-] (n) -- (o);
% \path[draw,thick,-] (o) -- (p);
% \path[draw,thick,-] (p) -- (q);
% \path[draw,thick,-] (q) -- (f);
% \end{tikzpicture}
% \end{center}
% jossa verkon solmuja ovat labyrintin lattiaruudut
% ja solmujen välillä on kaari, jos lattiaruudusta
% toiseen pääsee kulkemaan yhdellä askeleella.
% Niinpä erilaiset labyrinttiin liittyvät ongelmat
% palautuvat verkko-ongelmiksi.
%
% Esimerkiksi syvyyshaulla pystyy selvittämään,
% onko ruudusta $a$ reittiä ruutuun $b$
% ja leveyshaku kertoo lisäksi,
% mikä on pienin mahdollinen askelten määrä reitillä.
% Samoin voi esimerkiksi vaikkapa, kuinka monta
% toisistaan erillistä huonetta labyrintissa on
% sekä kuinka monta ruutua huoneissa on.
%
% Labyrintin tapauksessa ei kannata muodostaa erikseen
% verkkoa, vaan syvyyshaun ja leveyshaun voi toteuttaa
% suoraan labyrintin ruudukkoon.
Note that in the general case,
it is difficult to find out if the nodes
in a graph can be colored using $k$ colors
so that no adjacent nodes have the same color.
Even when $k=3$, no efficient algorithm is known
but the problem is NP-hard.