1361 lines
51 KiB
TeX
1361 lines
51 KiB
TeX
|
\chapter{Network flows}
|
|||
|
|
|||
|
Annettuna on suunnattu, painotettu verkko,
|
|||
|
josta on valittu tietty alkusolmu ja loppusolmu.
|
|||
|
Tarkastelemme seuraavia ongelmia:
|
|||
|
|
|||
|
\begin{itemize}
|
|||
|
\item \key{Maksimivirtauksen etsiminen}:
|
|||
|
Kuinka paljon virtausta on mahdollista kuljettaa
|
|||
|
verkon alkusolmusta loppusolmuun kaaria pitkin?
|
|||
|
\item \key{Minimileikkauksen etsiminen}:
|
|||
|
Mikä on yhteispainoltaan pienin joukko kaaria,
|
|||
|
joiden poistaminen erottaa alkusolmun loppusolmusta?
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
Osoittautuu, että nämä ongelmat vastaavat toisiaan
|
|||
|
ja ne on mahdollista ratkaista samanaikaisesti
|
|||
|
toistensa avulla.
|
|||
|
|
|||
|
Käytämme esimerkkinä seuraavaa verkkoa,
|
|||
|
jossa solmu 1 on alkusolmu ja solmu 6 on loppusolmu:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,2) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,1) {$5$};
|
|||
|
\path[draw,thick,->] (1) -- node[font=\small,label=5] {} (2);
|
|||
|
\path[draw,thick,->] (2) -- node[font=\small,label=6] {} (3);
|
|||
|
\path[draw,thick,->] (3) -- node[font=\small,label=5] {} (4);
|
|||
|
\path[draw,thick,->] (1) -- node[font=\small,label=below:4] {} (5);
|
|||
|
\path[draw,thick,->] (5) -- node[font=\small,label=below:1] {} (6);
|
|||
|
\path[draw,thick,->] (6) -- node[font=\small,label=below:2] {} (4);
|
|||
|
\path[draw,thick,<-] (2) -- node[font=\small,label=left:3] {} (5);
|
|||
|
\path[draw,thick,->] (3) -- node[font=\small,label=left:8] {} (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
\subsubsection{Maksimivirtaus}
|
|||
|
|
|||
|
\index{virtaus@virtaus}
|
|||
|
\index{maksimivirtaus@maksimivirtaus}
|
|||
|
|
|||
|
\key{Maksimivirtaus} on suurin
|
|||
|
mahdollinen verkossa kulkeva virtaus,
|
|||
|
joka lähtee liikkeelle alkusolmusta ja
|
|||
|
päätyy loppusolmuun.
|
|||
|
Kunkin kaaren paino on kapasiteetti,
|
|||
|
joka ilmaisee, kuinka paljon virtausta kaaren
|
|||
|
kautta voi kulkea.
|
|||
|
Kaikissa verkon solmuissa alku-
|
|||
|
ja loppusolmua lukuun ottamatta
|
|||
|
lähtevän ja tulevan virtauksen on oltava yhtä suuri.
|
|||
|
|
|||
|
Esimerkkiverkon maksimivirtaus on seuraava:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,2) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,1) {$5$};
|
|||
|
\path[draw,thick,->] (1) -- node[font=\small,label=3/5] {} (2);
|
|||
|
\path[draw,thick,->] (2) -- node[font=\small,label=6/6] {} (3);
|
|||
|
\path[draw,thick,->] (3) -- node[font=\small,label=5/5] {} (4);
|
|||
|
\path[draw,thick,->] (1) -- node[font=\small,label=below:4/4] {} (5);
|
|||
|
\path[draw,thick,->] (5) -- node[font=\small,label=below:1/1] {} (6);
|
|||
|
\path[draw,thick,->] (6) -- node[font=\small,label=below:2/2] {} (4);
|
|||
|
\path[draw,thick,<-] (2) -- node[font=\small,label=left:3/3] {} (5);
|
|||
|
\path[draw,thick,->] (3) -- node[font=\small,label=left:1/8] {} (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Merkintä $v/k$ kaaressa tarkoittaa,
|
|||
|
että kaaressa kulkee virtausta $v$
|
|||
|
ja kaaren kapasiteetti on $k$.
|
|||
|
Jokaiselle kaarelle tulee päteä $v \le k$.
|
|||
|
Tässä verkossa
|
|||
|
maksimivirtauksen suuruus on 7, koska alkusolmusta
|
|||
|
lähtevä virtaus on $3+4=7$ ja loppusolmuun
|
|||
|
tuleva virtaus on $5+2=7$.
|
|||
|
|
|||
|
Huomaa, että jokaisessa välisolmussa tulevan ja
|
|||
|
lähtevän virtauksen määrä on yhtä suuri.
|
|||
|
Esimerkiksi solmuun 2 tulee virtausta $3+3=6$ yksikköä solmuista 1 ja 4
|
|||
|
ja siitä lähtee virtausta $6$ yksikköä solmuun 3.
|
|||
|
|
|||
|
\subsubsection{Minimileikkaus}
|
|||
|
|
|||
|
\index{leikkaus@leikkaus}
|
|||
|
\index{minimileikkaus@minimileikkaus}
|
|||
|
|
|||
|
\key{Minimileikkaus} on yhteispainoltaan
|
|||
|
pienin mahdollinen joukko verkon kaaria,
|
|||
|
joiden poistaminen estää kulkemisen
|
|||
|
alkusolmusta loppusolmuun.
|
|||
|
Leikkauksen jälkeen alkuosaan kuuluvat
|
|||
|
solmut, joihin pääsee alkusolmusta,
|
|||
|
ja loppuosaan kuuluvat muut verkon solmut,
|
|||
|
mukaan lukien loppusolmu.
|
|||
|
|
|||
|
Esimerkkiverkon minimileikkaus on seuraava:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,2) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,1) {$5$};
|
|||
|
\path[draw,thick,->] (1) -- node[font=\small,label=5] {} (2);
|
|||
|
\path[draw,thick,->] (2) -- node[font=\small,label=6] {} (3);
|
|||
|
\path[draw,thick,->] (3) -- node[font=\small,label=5] {} (4);
|
|||
|
\path[draw,thick,->] (1) -- node[font=\small,label=below:4] {} (5);
|
|||
|
\path[draw,thick,->] (5) -- node[font=\small,label=below:1] {} (6);
|
|||
|
\path[draw,thick,->] (6) -- node[font=\small,label=below:2] {} (4);
|
|||
|
\path[draw,thick,<-] (2) -- node[font=\small,label=left:3] {} (5);
|
|||
|
\path[draw,thick,->] (3) -- node[font=\small,label=left:8] {} (6);
|
|||
|
|
|||
|
\path[draw=red,thick,-,line width=2pt] (4-.3,3-.3) -- (4+.3,3+.3);
|
|||
|
\path[draw=red,thick,-,line width=2pt] (4-.3,3+.3) -- (4+.3,3-.3);
|
|||
|
\path[draw=red,thick,-,line width=2pt] (4-.3,1-.3) -- (4+.3,1+.3);
|
|||
|
\path[draw=red,thick,-,line width=2pt] (4-.3,1+.3) -- (4+.3,1-.3);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tässä leikkauksessa alkuosassa ovat solmut $\{1,2,4\}$
|
|||
|
ja loppuosassa ovat solmut $\{3,5,6\}$.
|
|||
|
Minimileikkauksen paino on 7,
|
|||
|
koska alkuosasta loppuosaan kulkevat
|
|||
|
kaaret $2 \rightarrow 3$ ja $4 \rightarrow 5$,
|
|||
|
joiden yhteispaino on $6+1=7$.
|
|||
|
\\\\
|
|||
|
Ei ole sattumaa, että esimerkkiverkossa
|
|||
|
sekä maksimivirtauksen suuruus
|
|||
|
että minimileikkauksen paino on 7.
|
|||
|
Virtauslaskennan keskeinen tulos on,
|
|||
|
että verkon maksimivirtaus ja
|
|||
|
minimileikkaus
|
|||
|
ovat \textit{aina} yhtä suuret,
|
|||
|
eli käsitteet kuvaavat saman asian
|
|||
|
kahta eri puolta.
|
|||
|
|
|||
|
Seuraavaksi tutustumme Ford–Fulkersonin
|
|||
|
algoritmiin, jolla voi etsiä verkon
|
|||
|
maksimivirtauksen ja
|
|||
|
minimileikkauksen.
|
|||
|
Algoritmi auttaa myös ymmärtämään,
|
|||
|
\textit{miksi} maksimivirtaus ja
|
|||
|
minimileikkaus ovat yhtä suuret.
|
|||
|
|
|||
|
\section{Ford–Fulkersonin algoritmi}
|
|||
|
|
|||
|
\index{Ford–Fulkersonin algoritmi}
|
|||
|
|
|||
|
\key{Ford–Fulkersonin algoritmi} etsii verkon maksimivirtauksen.
|
|||
|
Algoritmi aloittaa tilanteesta,
|
|||
|
jossa virtaus on 0, ja alkaa sitten etsiä verkosta polkuja,
|
|||
|
jotka tuottavat siihen lisää virtausta.
|
|||
|
Kun mitään polkua ei enää pysty muodostamaan,
|
|||
|
maksimivirtaus on tullut valmiiksi.
|
|||
|
|
|||
|
Algoritmi käsittelee verkkoa muodossa,
|
|||
|
jossa jokaiselle kaarelle on vastakkaiseen
|
|||
|
suuntaan kulkeva pari.
|
|||
|
Kaaren paino kuvastaa, miten paljon
|
|||
|
lisää virtausta sen kautta pystyy vielä kulkemaan.
|
|||
|
Aluksi alkuperäisen verkon kaarilla on
|
|||
|
painona niiden kapasiteetti
|
|||
|
ja käänteisillä kaarilla on painona 0.
|
|||
|
|
|||
|
\begin{samepage}
|
|||
|
Esimerkkiverkosta syntyy seuraava verkko:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
|||
|
\node[draw, circle] (1) at (1,1.3) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,2.6) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,2.6) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,1.3) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,0) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,0) {$5$};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=5] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=6] {} (3);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:0] {} (2);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=2] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (6);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:8] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:0] {} (3);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
\end{samepage}
|
|||
|
|
|||
|
\subsubsection{Algoritmin toiminta}
|
|||
|
|
|||
|
Ford–Fulkersonin algoritmi etsii verkosta joka vaiheessa polun,
|
|||
|
joka alkaa alkusolmusta,
|
|||
|
päättyy loppusolmuun ja jossa jokaisen kaaren
|
|||
|
paino on positiivinen.
|
|||
|
Jos vaihtoehtoja on useita, mikä tahansa valinta kelpaa.
|
|||
|
|
|||
|
Esimerkkiverkossa voimme valita vaikkapa seuraavan polun:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
|||
|
\node[draw, circle] (1) at (1,1.3) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,2.6) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,2.6) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,1.3) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,0) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,0) {$5$};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=5] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=6] {} (3);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:0] {} (2);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=2] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (6);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:8] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:0] {} (3);
|
|||
|
|
|||
|
\path[draw=red,thick,->,line width=2pt] (1) edge [bend left=10] (2);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (2) edge [bend left=10] (3);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (3) edge [bend left=10] (6);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (6) edge [bend left=10] (4);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Polun valinnan jälkeen virtaus lisääntyy $x$ yksikköä,
|
|||
|
jossa $x$ on pienin kaaren kapasiteetti polulla.
|
|||
|
Samalla jokaisen polulla olevan kaaren kapasiteetti
|
|||
|
vähenee $x$:llä ja jokaisen käänteisen kaaren kapasiteetti kasvaa $x$:llä.
|
|||
|
|
|||
|
Yllä valitussa polussa
|
|||
|
kaarten kapasiteetit ovat 5, 6, 8 ja 2.
|
|||
|
Pienin kapasiteetti on 2,
|
|||
|
joten virtaus kasvaa 2:lla
|
|||
|
ja verkko muuttuu seuraavasti:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
|||
|
\node[draw, circle] (1) at (1,1.3) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,2.6) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,2.6) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,1.3) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,0) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,0) {$5$};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=3] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:2] {} (1);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=4] {} (3);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:2] {} (2);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:6] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:2] {} (3);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Muutoksessa on ideana, että virtauksen lisääminen
|
|||
|
vähentää polkuun kuuluvien kaarten kykyä välittää virtausta.
|
|||
|
Toisaalta virtausta on mahdollista peruuttaa myöhemmin
|
|||
|
käyttämällä käänteisiä kaaria, jos osoittautuu, että
|
|||
|
virtausta on järkevää reitittää verkossa toisella tavalla.
|
|||
|
|
|||
|
Algoritmi kasvattaa virtausta
|
|||
|
niin kauan, kuin verkossa on olemassa polku
|
|||
|
alkusolmusta loppusolmuun positiivisia kaaria pitkin.
|
|||
|
Tässä tapauksessa
|
|||
|
voimme valita seuraavan polun vaikkapa näin:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
|||
|
\node[draw, circle] (1) at (1,1.3) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,2.6) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,2.6) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,1.3) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,0) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,0) {$5$};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=3] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:2] {} (1);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=4] {} (3);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:2] {} (2);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:6] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:2] {} (3);
|
|||
|
|
|||
|
\path[draw=red,thick,->,line width=2pt] (1) edge [bend left=10] (5);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (5) edge [bend left=10] (2);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (2) edge [bend left=10] (3);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (3) edge [bend left=10] (4);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tämän polun pienin kapasiteetti on 3,
|
|||
|
joten polku kasvattaa virtausta 3:lla
|
|||
|
ja kokonaisvirtaus polun käsittelyn jälkeen on 5.
|
|||
|
|
|||
|
\begin{samepage}
|
|||
|
Nyt verkko muuttuu seuraavasti:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
|||
|
\node[draw, circle] (1) at (1,1.3) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,2.6) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,2.6) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,1.3) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,0) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,0) {$5$};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=3] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:2] {} (1);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=1] {} (3);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:5] {} (2);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=2] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:3] {} (3);
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=1] {} (5);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:3] {} (1);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:0] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:3] {} (5);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:6] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:2] {} (3);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
\end{samepage}
|
|||
|
|
|||
|
Maksimivirtaus tulee valmiiksi
|
|||
|
lisäämällä virtausta vielä polkujen $1 \rightarrow 2 \rightarrow 3 \rightarrow 6$ ja
|
|||
|
$1 \rightarrow 4 \rightarrow 5 \rightarrow 3 \rightarrow 6$ avulla.
|
|||
|
Molemmat polut tuottavat 1 yksikön lisää virtausta,
|
|||
|
ja lopullinen verkko on seuraava:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
|||
|
\node[draw, circle] (1) at (1,1.3) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,2.6) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,2.6) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,1.3) {$6$};
|
|||
|
\node[draw, circle] (5) at (3,0) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,0) {$5$};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=2] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:3] {} (1);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=0] {} (3);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:6] {} (2);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=0] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:5] {} (3);
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=0] {} (5);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:4] {} (1);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=0] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:1] {} (5);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:0] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:3] {} (5);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:7] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:1] {} (3);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Nyt virtausta ei pysty enää kasvattamaan,
|
|||
|
koska verkossa ei ole mitään polkua
|
|||
|
alkusolmusta loppusolmuun,
|
|||
|
jossa jokaisen kaaren paino olisi positiivinen.
|
|||
|
Niinpä algoritmi pysähtyy ja verkon maksimivirtaus on 7.
|
|||
|
|
|||
|
\subsubsection{Polun valinta}
|
|||
|
|
|||
|
Ford–Fulkersonin algoritmi ei ota kantaa siihen,
|
|||
|
millä tavoin virtausta kasvattava polku valitaan verkossa.
|
|||
|
Valintatavasta riippumatta algoritmi pysähtyy
|
|||
|
ja tuottaa maksimivirtauksen ennemmin tai myöhemmin,
|
|||
|
mutta polun valinnalla on vaikutusta algoritmin tehokkuuteen.
|
|||
|
|
|||
|
Yksinkertainen tapa on valita virtausta kasvattava
|
|||
|
polku syvyyshaulla.
|
|||
|
Tämä toimii usein hyvin, mutta pahin tapaus on,
|
|||
|
että jokainen polku
|
|||
|
kasvattaa virtausta vain 1:llä ja algoritmi toimii hitaasti.
|
|||
|
Onneksi tämän ilmiön pystyy estämään käyttämällä
|
|||
|
jompaakumpaa seuraavaa algoritmia:
|
|||
|
|
|||
|
\index{Edmonds–Karpin algoritmi}
|
|||
|
|
|||
|
\key{Edmonds–Karpin algoritmi} on
|
|||
|
Ford–Fulkersonin algoritmin toteutus,
|
|||
|
jossa virtausta kasvattava polku valitaan
|
|||
|
aina niin, että siinä on mahdollisimman vähän kaaria.
|
|||
|
Tämä onnistuu etsimällä polku syvyyshaun
|
|||
|
sijasta leveyshaulla.
|
|||
|
Osoittautuu, että tämä varmistaa virtauksen
|
|||
|
kasvamisen nopeasti ja
|
|||
|
maksimivirtauksen etsiminen vie aikaa $O(m^2 n)$.
|
|||
|
|
|||
|
\index{skaalaava algoritmi@skaalaava algoritmi}
|
|||
|
|
|||
|
\key{Skaalaava algoritmi}
|
|||
|
asettaa minimiarvon, joka on ensin alkusolmusta
|
|||
|
lähtevien kaarten kapasiteettien summa $c$.
|
|||
|
Joka vaiheessa verkosta etsitään
|
|||
|
syvyyshaulla polku, jonka jokaisen kaaren kapasiteetti
|
|||
|
on vähintään minimiarvo.
|
|||
|
Aina jos kelvollista polkua ei löydy,
|
|||
|
minimiarvo jaetaan 2:lla,
|
|||
|
kunnes lopuksi minimiarvo on 1.
|
|||
|
Algoritmin aikavaativuus on $O(m^2 \log c)$.
|
|||
|
|
|||
|
Käytännössä skaalaava algoritmi on mukavampi koodattava,
|
|||
|
koska siinä riittää etsiä polku syvyyshaulla.
|
|||
|
Molemmat algoritmit ovat yleensä aina riittävän
|
|||
|
nopeita ohjelmointikisoissa esiintyviin tehtäviin.
|
|||
|
|
|||
|
\subsubsection{Minimileikkaus}
|
|||
|
|
|||
|
\index{minimileikkaus@minimileikkaus}
|
|||
|
|
|||
|
Osoittautuu, että kun Ford–Fulkersonin algoritmi on saanut valmiiksi
|
|||
|
maksimivirtauksen, se on tuottanut samalla minimileikkauksen.
|
|||
|
Olkoon $A$ niiden solmujen joukko,
|
|||
|
joihin verkossa pääsee
|
|||
|
alkusolmusta positiivisia kaaria pitkin.
|
|||
|
Esimerkkiverkossa $A$ sisältää solmut 1, 2 ja 4:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
|||
|
\node[draw, circle,fill=lightgray] (1) at (1,1.3) {$1$};
|
|||
|
\node[draw, circle,fill=lightgray] (2) at (3,2.6) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,2.6) {$3$};
|
|||
|
\node[draw, circle] (4) at (7,1.3) {$6$};
|
|||
|
\node[draw, circle,fill=lightgray] (5) at (3,0) {$4$};
|
|||
|
\node[draw, circle] (6) at (5,0) {$5$};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=2] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:3] {} (1);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=0] {} (3);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:6] {} (2);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=0] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:5] {} (3);
|
|||
|
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=0] {} (5);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:4] {} (1);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=0] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:1] {} (5);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
|||
|
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
|||
|
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:0] {} (2);
|
|||
|
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:3] {} (5);
|
|||
|
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:7] {} (6);
|
|||
|
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:1] {} (3);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Nyt minimileikkauksen muodostavat ne alkuperäisen verkon kaaret,
|
|||
|
jotka kulkevat joukosta $A$ joukon $A$ ulkopuolelle
|
|||
|
ja joiden kapasiteetti on täysin käytetty
|
|||
|
maksimivirtauksessa.
|
|||
|
Tässä verkossa kyseiset kaaret ovat $2 \rightarrow 3$
|
|||
|
ja $4 \rightarrow 5$, jotka tuottavat minimileikkauksen $6+1=7$.
|
|||
|
|
|||
|
Miksi sitten algoritmin tuottama virtaus ja leikkaus ovat
|
|||
|
varmasti maksimivirtaus ja minimileikkaus?
|
|||
|
Syynä tähän on, että verkossa ei voi olla virtausta,
|
|||
|
jonka suuruus ylittäisi yhdenkään
|
|||
|
verkossa olevan leikkauksen painoa.
|
|||
|
Niinpä kun verkossa oleva
|
|||
|
virtaus ja leikkaus ovat yhtä suuret,
|
|||
|
ne ovat varmasti maksimivirtaus ja minimileikkaus.
|
|||
|
|
|||
|
Tarkastellaan mitä tahansa verkon leikkausta,
|
|||
|
jossa alkusolmu kuuluu osaan $A$,
|
|||
|
loppusolmu kuuluu osaan $B$ ja osien välillä kulkee kaaria:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\draw[dashed] (-2,0) circle (1.5);
|
|||
|
\draw[dashed] (2,0) circle (1.5);
|
|||
|
|
|||
|
\node at (-2,-1) {$A$};
|
|||
|
\node at (2,-1) {$B$};
|
|||
|
|
|||
|
\node[draw, circle] (1) at (-1,0.5) {};
|
|||
|
\node[draw, circle] (2) at (-1,0) {};
|
|||
|
\node[draw, circle] (3) at (-1,-0.5) {};
|
|||
|
\node[draw, circle] (4) at (1,0.5) {};
|
|||
|
\node[draw, circle] (5) at (1,0) {};
|
|||
|
\node[draw, circle] (6) at (1,-0.5) {};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) -- (4);
|
|||
|
\path[draw,thick,->] (5) -- (2);
|
|||
|
\path[draw,thick,->] (3) -- (6);
|
|||
|
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Leikkauksen paino on niiden kaarten painojen summa,
|
|||
|
jotka kulkevat osasta $A$ osaan $B$.
|
|||
|
Tämä on yläraja sille, kuinka suuri verkossa oleva virtaus voi olla,
|
|||
|
koska virtauksen täytyy edetä osasta $A$ osaan $B$.
|
|||
|
Niinpä maksimivirtaus on pienempi tai yhtä suuri kuin
|
|||
|
mikä tahansa verkon leikkaus.
|
|||
|
|
|||
|
Toisaalta Ford–Fulkersonin algoritmi tuottaa virtauksen,
|
|||
|
joka on \emph{tarkalleen} yhtä suuri kuin verkossa oleva leikkaus.
|
|||
|
Niinpä tämän virtauksen on oltava maksimivirtaus ja
|
|||
|
vastaavasti leikkauksen on oltava minimileikkaus.
|
|||
|
|
|||
|
\section{Rinnakkaiset polut}
|
|||
|
|
|||
|
Ensimmäisenä virtauslaskennan sovelluksena tarkastelemme
|
|||
|
tehtävää, jossa tavoitteena on muodostaa mahdollisimman
|
|||
|
monta rinnakkaista polkua verkon alkusolmusta loppusolmuun.
|
|||
|
Vaatimuksena on, että jokainen verkon kaari esiintyy
|
|||
|
enintään yhdellä polulla.
|
|||
|
|
|||
|
Esimerkiksi verkossa
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|||
|
\node[draw, circle] (4) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (5) at (5,1) {$5$};
|
|||
|
\node[draw, circle] (6) at (7,2) {$6$};
|
|||
|
\path[draw,thick,->] (1) -- (2);
|
|||
|
\path[draw,thick,->] (1) -- (4);
|
|||
|
\path[draw,thick,->] (2) -- (4);
|
|||
|
\path[draw,thick,->] (3) -- (2);
|
|||
|
\path[draw,thick,->] (3) -- (5);
|
|||
|
\path[draw,thick,->] (3) -- (6);
|
|||
|
\path[draw,thick,->] (4) -- (3);
|
|||
|
\path[draw,thick,->] (4) -- (5);
|
|||
|
\path[draw,thick,->] (5) -- (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
pystyy muodostamaan kaksi rinnakkaista polkua solmusta 1 solmuun 6.
|
|||
|
Tämä toteutuu valitsemalla polut
|
|||
|
$1 \rightarrow 2 \rightarrow 4 \rightarrow 3 \rightarrow 6$
|
|||
|
ja $1 \rightarrow 4 \rightarrow 5 \rightarrow 6$:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|||
|
\node[draw, circle] (4) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (5) at (5,1) {$5$};
|
|||
|
\node[draw, circle] (6) at (7,2) {$6$};
|
|||
|
\path[draw,thick,->] (1) -- (2);
|
|||
|
\path[draw,thick,->] (1) -- (4);
|
|||
|
\path[draw,thick,->] (2) -- (4);
|
|||
|
\path[draw,thick,->] (3) -- (2);
|
|||
|
\path[draw,thick,->] (3) -- (5);
|
|||
|
\path[draw,thick,->] (3) -- (6);
|
|||
|
\path[draw,thick,->] (4) -- (3);
|
|||
|
\path[draw,thick,->] (4) -- (5);
|
|||
|
\path[draw,thick,->] (5) -- (6);
|
|||
|
|
|||
|
\path[draw=green,thick,->,line width=2pt] (1) -- (2);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (2) -- (4);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (4) -- (3);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (3) -- (6);
|
|||
|
|
|||
|
\path[draw=blue,thick,->,line width=2pt] (1) -- (4);
|
|||
|
\path[draw=blue,thick,->,line width=2pt] (4) -- (5);
|
|||
|
\path[draw=blue,thick,->,line width=2pt] (5) -- (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Osoittautuu, että suurin rinnakkaisten polkujen määrä
|
|||
|
on yhtä suuri kuin maksimivirtaus verkossa,
|
|||
|
jossa jokaisen kaaren kapasiteetti on 1.
|
|||
|
Kun maksimivirtaus on muodostettu,
|
|||
|
rinnakkaiset polut voi löytää
|
|||
|
ahneesti etsimällä alkusolmusta loppusolmuun
|
|||
|
kulkevia polkuja.
|
|||
|
|
|||
|
Tarkastellaan sitten tehtävän muunnelmaa,
|
|||
|
jossa jokainen solmu (alku- ja loppusolmua lukuun ottamatta)
|
|||
|
saa esiintyä enintään yhdellä polulla.
|
|||
|
Tämän rajoituksen seurauksena äskeisessä verkossa
|
|||
|
voi muodostaa vain yhden polun,
|
|||
|
koska solmu 4 ei voi esiintyä monella polulla:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|||
|
\node[draw, circle] (4) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (5) at (5,1) {$5$};
|
|||
|
\node[draw, circle] (6) at (7,2) {$6$};
|
|||
|
\path[draw,thick,->] (1) -- (2);
|
|||
|
\path[draw,thick,->] (1) -- (4);
|
|||
|
\path[draw,thick,->] (2) -- (4);
|
|||
|
\path[draw,thick,->] (3) -- (2);
|
|||
|
\path[draw,thick,->] (3) -- (5);
|
|||
|
\path[draw,thick,->] (3) -- (6);
|
|||
|
\path[draw,thick,->] (4) -- (3);
|
|||
|
\path[draw,thick,->] (4) -- (5);
|
|||
|
\path[draw,thick,->] (5) -- (6);
|
|||
|
|
|||
|
\path[draw=green,thick,->,line width=2pt] (1) -- (2);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (2) -- (4);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (4) -- (3);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (3) -- (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tavallinen keino rajoittaa solmun kautta kulkevaa
|
|||
|
virtausta on jakaa solmu tulosolmuksi ja lähtösolmuksi.
|
|||
|
Kaikki solmuun tulevat kaaret saapuvat tulosolmuun
|
|||
|
ja kaikki solmusta lähtevät kaaret poistuvat lähtösolmusta.
|
|||
|
Lisäksi tulosolmusta lähtösolmuun on kaari,
|
|||
|
jossa on haluttu kapasiteetti.
|
|||
|
|
|||
|
Tässä tapauksessa verkosta tulee seuraava:
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
|
|||
|
\node[draw, circle] (2a) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3a) at (6,3) {$3$};
|
|||
|
\node[draw, circle] (4a) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (5a) at (6,1) {$5$};
|
|||
|
|
|||
|
\node[draw, circle] (2b) at (4,3) {$2$};
|
|||
|
\node[draw, circle] (3b) at (7,3) {$3$};
|
|||
|
\node[draw, circle] (4b) at (4,1) {$4$};
|
|||
|
\node[draw, circle] (5b) at (7,1) {$5$};
|
|||
|
|
|||
|
\node[draw, circle] (6) at (9,2) {$6$};
|
|||
|
|
|||
|
\path[draw,thick,->] (2a) -- (2b);
|
|||
|
\path[draw,thick,->] (3a) -- (3b);
|
|||
|
\path[draw,thick,->] (4a) -- (4b);
|
|||
|
\path[draw,thick,->] (5a) -- (5b);
|
|||
|
|
|||
|
\path[draw,thick,->] (1) -- (2a);
|
|||
|
\path[draw,thick,->] (1) -- (4a);
|
|||
|
\path[draw,thick,->] (2b) -- (4a);
|
|||
|
\path[draw,thick,->] (3b) edge [bend right=30] (2a);
|
|||
|
\path[draw,thick,->] (3b) -- (5a);
|
|||
|
\path[draw,thick,->] (3b) -- (6);
|
|||
|
\path[draw,thick,->] (4b) -- (3a);
|
|||
|
\path[draw,thick,->] (4b) -- (5a);
|
|||
|
\path[draw,thick,->] (5b) -- (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tämän verkon maksimivirtaus on:
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}
|
|||
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|||
|
|
|||
|
\node[draw, circle] (2a) at (3,3) {$2$};
|
|||
|
\node[draw, circle] (3a) at (6,3) {$3$};
|
|||
|
\node[draw, circle] (4a) at (3,1) {$4$};
|
|||
|
\node[draw, circle] (5a) at (6,1) {$5$};
|
|||
|
|
|||
|
\node[draw, circle] (2b) at (4,3) {$2$};
|
|||
|
\node[draw, circle] (3b) at (7,3) {$3$};
|
|||
|
\node[draw, circle] (4b) at (4,1) {$4$};
|
|||
|
\node[draw, circle] (5b) at (7,1) {$5$};
|
|||
|
|
|||
|
\node[draw, circle] (6) at (9,2) {$6$};
|
|||
|
|
|||
|
\path[draw,thick,->] (2a) -- (2b);
|
|||
|
\path[draw,thick,->] (3a) -- (3b);
|
|||
|
\path[draw,thick,->] (4a) -- (4b);
|
|||
|
\path[draw,thick,->] (5a) -- (5b);
|
|||
|
|
|||
|
\path[draw,thick,->] (1) -- (2a);
|
|||
|
\path[draw,thick,->] (1) -- (4a);
|
|||
|
\path[draw,thick,->] (2b) -- (4a);
|
|||
|
\path[draw,thick,->] (3b) edge [bend right=30] (2a);
|
|||
|
\path[draw,thick,->] (3b) -- (5a);
|
|||
|
\path[draw,thick,->] (3b) -- (6);
|
|||
|
\path[draw,thick,->] (4b) -- (3a);
|
|||
|
\path[draw,thick,->] (4b) -- (5a);
|
|||
|
\path[draw,thick,->] (5b) -- (6);
|
|||
|
|
|||
|
\path[draw=red,thick,->,line width=2pt] (1) -- (2a);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (2a) -- (2b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (2b) -- (4a);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (4a) -- (4b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (4b) -- (3a);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (3a) -- (3b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (3b) -- (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tämä tarkoittaa, että verkossa on mahdollista muodostaa
|
|||
|
vain yksi polku alkusolmusta lähtösolmuun,
|
|||
|
kun sama solmu ei saa esiintyä monessa polussa.
|
|||
|
|
|||
|
\section{Maksimiparitus}
|
|||
|
|
|||
|
\index{paritus@paritus}
|
|||
|
\index{maksimiparitus@maksimiparitus}
|
|||
|
|
|||
|
\key{Maksimiparitus} on suurin mahdollinen joukko
|
|||
|
verkon solmuista muodostettuja pareja,
|
|||
|
jolle pätee,
|
|||
|
että jokaisen parin välillä on kaari verkossa
|
|||
|
ja jokainen solmu kuuluu enintään yhteen pariin.
|
|||
|
|
|||
|
Maksimiparituksen etsimiseen yleisessä
|
|||
|
verkossa on olemassa polynominen algoritmi,
|
|||
|
mutta se on hyvin monimutkainen.
|
|||
|
Tässä luvussa keskitymmekin tilanteeseen,
|
|||
|
jossa verkko on kaksijakoinen.
|
|||
|
Tällöin maksimiparituksen pystyy etsimään
|
|||
|
helposti virtauslaskennan avulla.
|
|||
|
|
|||
|
\subsubsection{Maksimiparituksen etsiminen}
|
|||
|
|
|||
|
Kaksijakoinen verkko voidaan esittää niin,
|
|||
|
että se muodostuu vasemman ja oikean puolen
|
|||
|
solmuista ja kaikki verkon kaaret kulkevat puolten välillä.
|
|||
|
Tarkastellaan esimerkkinä seuraavaa verkkoa:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle] (2) at (2,3) {2};
|
|||
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle] (4) at (2,0) {4};
|
|||
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle] (6) at (8,3) {6};
|
|||
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle] (8) at (8,0) {8};
|
|||
|
|
|||
|
\path[draw,thick,-] (1) -- (5);
|
|||
|
\path[draw,thick,-] (2) -- (7);
|
|||
|
\path[draw,thick,-] (3) -- (5);
|
|||
|
\path[draw,thick,-] (3) -- (6);
|
|||
|
\path[draw,thick,-] (3) -- (8);
|
|||
|
\path[draw,thick,-] (4) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tässä verkossa maksimiparituksen koko on 3:
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle] (2) at (2,3) {2};
|
|||
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle] (4) at (2,0) {4};
|
|||
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle] (6) at (8,3) {6};
|
|||
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle] (8) at (8,0) {8};
|
|||
|
|
|||
|
\path[draw,thick,-] (1) -- (5);
|
|||
|
\path[draw,thick,-] (2) -- (7);
|
|||
|
\path[draw,thick,-] (3) -- (5);
|
|||
|
\path[draw,thick,-] (3) -- (6);
|
|||
|
\path[draw,thick,-] (3) -- (8);
|
|||
|
\path[draw,thick,-] (4) -- (7);
|
|||
|
|
|||
|
\path[draw=red,thick,-,line width=2pt] (1) -- (5);
|
|||
|
\path[draw=red,thick,-,line width=2pt] (2) -- (7);
|
|||
|
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Kaksijakoisen verkon maksimiparitus
|
|||
|
vastaa maksimivirtausta verkossa,
|
|||
|
johon on lisätty alkusolmu ja loppusolmu.
|
|||
|
Alkusolmusta on kaari jokaiseen vasemman
|
|||
|
puolen solmuun, ja vastaavasti loppusolmuun
|
|||
|
on kaari jokaisesta oikean puolen solmusta.
|
|||
|
Jokaisen kaaren kapasiteettina on 1.
|
|||
|
|
|||
|
Esimerkissä tuloksena on seuraava verkko:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle] (2) at (2,3) {2};
|
|||
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle] (4) at (2,0) {4};
|
|||
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle] (6) at (8,3) {6};
|
|||
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle] (8) at (8,0) {8};
|
|||
|
|
|||
|
\node[draw, circle] (a) at (-2,2.25) {\phantom{0}};
|
|||
|
\node[draw, circle] (b) at (12,2.25) {\phantom{0}};
|
|||
|
|
|||
|
\path[draw,thick,->] (1) -- (5);
|
|||
|
\path[draw,thick,->] (2) -- (7);
|
|||
|
\path[draw,thick,->] (3) -- (5);
|
|||
|
\path[draw,thick,->] (3) -- (6);
|
|||
|
\path[draw,thick,->] (3) -- (8);
|
|||
|
\path[draw,thick,->] (4) -- (7);
|
|||
|
|
|||
|
\path[draw,thick,->] (a) -- (1);
|
|||
|
\path[draw,thick,->] (a) -- (2);
|
|||
|
\path[draw,thick,->] (a) -- (3);
|
|||
|
\path[draw,thick,->] (a) -- (4);
|
|||
|
\path[draw,thick,->] (5) -- (b);
|
|||
|
\path[draw,thick,->] (6) -- (b);
|
|||
|
\path[draw,thick,->] (7) -- (b);
|
|||
|
\path[draw,thick,->] (8) -- (b);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tämän verkon maksimivirtaus on yhtä suuri kuin
|
|||
|
alkuperäisen verkon maksimiparitus,
|
|||
|
koska virtaus muodostuu joukosta polkuja
|
|||
|
alkusolmusta loppusolmuun ja jokainen
|
|||
|
polku ottaa mukaan uuden kaaren paritukseen.
|
|||
|
Tässä tapauksessa maksimivirtaus on 3,
|
|||
|
joten maksimiparitus on myös 3.
|
|||
|
|
|||
|
\subsubsection{Hallin lause}
|
|||
|
|
|||
|
\index{Hallin lause@Hallin lause}
|
|||
|
\index{txydellinen paritus@täydellinen paritus}
|
|||
|
|
|||
|
\key{Hallin lause} antaa ehdon, milloin kaksijakoiseen
|
|||
|
verkkoon voidaan muodostaa paritus,
|
|||
|
joka sisältää kaikki toisen puolen solmut.
|
|||
|
Jos kummallakin puolella on yhtä monta solmua,
|
|||
|
Hallin lause kertoo, voidaanko muodostaa
|
|||
|
\key{täydellinen paritus},
|
|||
|
jossa kaikki solmut paritetaan keskenään.
|
|||
|
|
|||
|
Oletetaan, että haluamme muodostaa parituksen,
|
|||
|
johon kuuluvat kaikki vasemman puolen solmut.
|
|||
|
Olkoon $X$ jokin joukko vasemman puolen solmuja
|
|||
|
ja $f(X)$ näiden solmujen naapurien joukko.
|
|||
|
Hallin lauseen mukaan paritus on mahdollinen,
|
|||
|
kun jokaiselle joukolle $X$
|
|||
|
pätee $|X| \le |f(X)|$.
|
|||
|
|
|||
|
Tarkastellaan Hallin lauseen merkitystä esimerkkiverkossa.
|
|||
|
Valitaan ensin $X=\{1,3\}$, jolloin $f(X)=\{5,6,8\}$:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle, fill=lightgray] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle] (2) at (2,3) {2};
|
|||
|
\node[draw, circle, fill=lightgray] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle] (4) at (2,0) {4};
|
|||
|
\node[draw, circle, fill=lightgray] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle, fill=lightgray] (6) at (8,3) {6};
|
|||
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle, fill=lightgray] (8) at (8,0) {8};
|
|||
|
|
|||
|
\path[draw,thick,-] (1) -- (5);
|
|||
|
\path[draw,thick,-] (2) -- (7);
|
|||
|
\path[draw,thick,-] (3) -- (5);
|
|||
|
\path[draw,thick,-] (3) -- (6);
|
|||
|
\path[draw,thick,-] (3) -- (8);
|
|||
|
\path[draw,thick,-] (4) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tämä täyttää Hallin lauseen ehdon, koska $|X|=2$ ja $|f(X)|=3$.
|
|||
|
Valitaan sitten $X=\{2,4\}$, jolloin $f(X)=\{7\}$:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle, fill=lightgray] (2) at (2,3) {2};
|
|||
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle, fill=lightgray] (4) at (2,0) {4};
|
|||
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle] (6) at (8,3) {6};
|
|||
|
\node[draw, circle, fill=lightgray] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle] (8) at (8,0) {8};
|
|||
|
|
|||
|
\path[draw,thick,-] (1) -- (5);
|
|||
|
\path[draw,thick,-] (2) -- (7);
|
|||
|
\path[draw,thick,-] (3) -- (5);
|
|||
|
\path[draw,thick,-] (3) -- (6);
|
|||
|
\path[draw,thick,-] (3) -- (8);
|
|||
|
\path[draw,thick,-] (4) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tässä tapauksessa $|X|=2$ ja $|f(X)|=1$, joten Hallin lauseen ehto
|
|||
|
ei ole voimassa.
|
|||
|
Tämä tarkoittaa, että verkossa
|
|||
|
ei ole mahdollista muodostaa täydellistä paritusta,
|
|||
|
johon kuuluvat kaikki vasemman puolen solmut.
|
|||
|
Tämä on myös odotettu tulos, koska verkon maksimiparitus on 3 eikä 4.
|
|||
|
|
|||
|
Jos Hallin lauseen ehto ei päde, osajoukko $X$
|
|||
|
kertoo syyn sille, miksi paritusta ei voi muodostaa.
|
|||
|
Koska $X$ sisältää enemmän solmuja kuin $f(X)$,
|
|||
|
kaikille $X$:n solmuille ei riitä paria oikealta.
|
|||
|
Esimerkiksi yllä molemmat solmut 2 ja 4 tulisi
|
|||
|
yhdistää solmuun 7, mutta tämä ei ole mahdollista.
|
|||
|
|
|||
|
\subsubsection{Kőnigin lause}
|
|||
|
|
|||
|
\index{Kőnigin lause}
|
|||
|
\index{solmupeite@solmupeite}
|
|||
|
\index{pienin solmupeite@pienin solmupeite}
|
|||
|
|
|||
|
\key{Kőnigin lause} tarjoaa tehokkaan
|
|||
|
tavan muodostaa kaksijakoiselle verkolle
|
|||
|
\key{pienin solmupeite} eli pienin sellainen
|
|||
|
solmujen joukko, että jokaisesta verkon kaaresta ainakin
|
|||
|
toinen päätesolmuista kuuluu joukkoon.
|
|||
|
|
|||
|
Yleisessä verkossa pienimmän solmupeitteen
|
|||
|
etsiminen on NP-vaikea ongelma.
|
|||
|
Sen sijaan kaksijakoisessa verkossa
|
|||
|
Kőnigin lauseen nojalla maksimiparitus ja
|
|||
|
pienin solmupeite ovat aina yhtä suuria,
|
|||
|
minkä ansiosta
|
|||
|
pienimmän solmupeitteen voi
|
|||
|
etsiä tehokkaasti virtauslaskennan avulla.
|
|||
|
|
|||
|
Tarkastellaan taas seuraavaa verkkoa,
|
|||
|
jonka maksimiparituksen koko on 3:
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle] (2) at (2,3) {2};
|
|||
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle] (4) at (2,0) {4};
|
|||
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle] (6) at (8,3) {6};
|
|||
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle] (8) at (8,0) {8};
|
|||
|
|
|||
|
\path[draw,thick,-] (1) -- (5);
|
|||
|
\path[draw,thick,-] (2) -- (7);
|
|||
|
\path[draw,thick,-] (3) -- (5);
|
|||
|
\path[draw,thick,-] (3) -- (6);
|
|||
|
\path[draw,thick,-] (3) -- (8);
|
|||
|
\path[draw,thick,-] (4) -- (7);
|
|||
|
|
|||
|
\path[draw=red,thick,-,line width=2pt] (1) -- (5);
|
|||
|
\path[draw=red,thick,-,line width=2pt] (2) -- (7);
|
|||
|
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
Kőnigin lauseen ansiosta tiedämme nyt,
|
|||
|
että myös pienimmän solmupeitteen koko on 3.
|
|||
|
Solmupeite voidaan muodostaa seuraavasti:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle, fill=lightgray] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle] (2) at (2,3) {2};
|
|||
|
\node[draw, circle, fill=lightgray] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle] (4) at (2,0) {4};
|
|||
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle] (6) at (8,3) {6};
|
|||
|
\node[draw, circle, fill=lightgray] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle] (8) at (8,0) {8};
|
|||
|
|
|||
|
\path[draw,thick,-] (1) -- (5);
|
|||
|
\path[draw,thick,-] (2) -- (7);
|
|||
|
\path[draw,thick,-] (3) -- (5);
|
|||
|
\path[draw,thick,-] (3) -- (6);
|
|||
|
\path[draw,thick,-] (3) -- (8);
|
|||
|
\path[draw,thick,-] (4) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
Pienin solmupeite muodostuu aina niin,
|
|||
|
että jokaisesta maksimiparituksen kaaresta
|
|||
|
toinen kaaren päätesolmuista kuuluu peitteeseen.
|
|||
|
|
|||
|
\index{riippumaton joukko@riippumaton joukko}
|
|||
|
\index{suurin riippumaton joukko@suurin riippumaton joukko}
|
|||
|
|
|||
|
Kun verkosta valitaan kaikki solmut,
|
|||
|
jotka \emph{eivät} kuulu pienimpään
|
|||
|
solmupeitteeseen, syntyy
|
|||
|
\key{suurin riippumaton joukko}.
|
|||
|
Tämä on suurin mahdollinen joukko solmuja,
|
|||
|
jossa minkään kahden solmun
|
|||
|
välillä ei ole kaarta.
|
|||
|
Pienimmän solmupeitteen tavoin
|
|||
|
riippumattoman joukon muodostaminen on
|
|||
|
NP-vaikea ongelma yleisessä verkossa,
|
|||
|
mutta Kőnigin lauseen avulla
|
|||
|
ongelma on mahdollista ratkaista
|
|||
|
tehokkaasti kaksijakoisessa verkossa.
|
|||
|
Esimerkkiverkossa suurin riippumaton joukko on seuraava:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.60]
|
|||
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|||
|
\node[draw, circle, fill=lightgray] (2) at (2,3) {2};
|
|||
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|||
|
\node[draw, circle, fill=lightgray] (4) at (2,0) {4};
|
|||
|
\node[draw, circle, fill=lightgray] (5) at (8,4.5) {5};
|
|||
|
\node[draw, circle, fill=lightgray] (6) at (8,3) {6};
|
|||
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|||
|
\node[draw, circle, fill=lightgray] (8) at (8,0) {8};
|
|||
|
|
|||
|
\path[draw,thick,-] (1) -- (5);
|
|||
|
\path[draw,thick,-] (2) -- (7);
|
|||
|
\path[draw,thick,-] (3) -- (5);
|
|||
|
\path[draw,thick,-] (3) -- (6);
|
|||
|
\path[draw,thick,-] (3) -- (8);
|
|||
|
\path[draw,thick,-] (4) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
\section{Polkupeitteet}
|
|||
|
|
|||
|
\index{polkupeite@polkupeite}
|
|||
|
|
|||
|
\key{Polkupeite} on joukko verkon polkuja,
|
|||
|
jotka on valittu niin, että jokainen verkon solmu kuuluu
|
|||
|
ainakin yhteen polkuun.
|
|||
|
Osoittautuu, että voimme muodostaa
|
|||
|
virtauslaskennan avulla
|
|||
|
pienimmän polkupeitteen suunnatussa,
|
|||
|
syklittömässä verkossa.
|
|||
|
|
|||
|
Polkupeitteestä on kaksi muunnelmaa:
|
|||
|
\key{Solmuerillinen peite} on polkupeite,
|
|||
|
jossa jokainen verkon solmu esiintyy tasan yhdessä polussa.
|
|||
|
\key{Yleinen peite} taas on polkupeite, jossa sama solmu voi
|
|||
|
esiintyä useammassa polussa.
|
|||
|
Kummassakin tapauksessa pienin polkupeite löytyy
|
|||
|
samanlaisella idealla.
|
|||
|
|
|||
|
\subsubsection{Solmuerillinen peite}
|
|||
|
|
|||
|
Tarkastellaan esimerkkinä seuraavaa verkkoa:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (0,0) {1};
|
|||
|
\node[draw, circle] (2) at (2,0) {2};
|
|||
|
\node[draw, circle] (3) at (4,0) {3};
|
|||
|
\node[draw, circle] (4) at (6,0) {4};
|
|||
|
\node[draw, circle] (5) at (0,-2) {5};
|
|||
|
\node[draw, circle] (6) at (2,-2) {6};
|
|||
|
\node[draw, circle] (7) at (4,-2) {7};
|
|||
|
|
|||
|
\path[draw,thick,->,>=latex] (1) -- (5);
|
|||
|
\path[draw,thick,->,>=latex] (2) -- (6);
|
|||
|
\path[draw,thick,->,>=latex] (3) -- (4);
|
|||
|
\path[draw,thick,->,>=latex] (5) -- (6);
|
|||
|
\path[draw,thick,->,>=latex] (6) -- (3);
|
|||
|
\path[draw,thick,->,>=latex] (6) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tässä tapauksessa pienin solmuerillinen polkupeite
|
|||
|
muodostuu kolmesta polusta.
|
|||
|
Voimme valita polut esimerkiksi seuraavasti:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (0,0) {1};
|
|||
|
\node[draw, circle] (2) at (2,0) {2};
|
|||
|
\node[draw, circle] (3) at (4,0) {3};
|
|||
|
\node[draw, circle] (4) at (6,0) {4};
|
|||
|
\node[draw, circle] (5) at (0,-2) {5};
|
|||
|
\node[draw, circle] (6) at (2,-2) {6};
|
|||
|
\node[draw, circle] (7) at (4,-2) {7};
|
|||
|
|
|||
|
\path[draw=red,thick,->,line width=2pt] (1) -- (5);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (5) -- (6);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (6) -- (7);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (3) -- (4);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Huomaa, että yksi poluista sisältää vain solmun 2,
|
|||
|
eli on sallittua, että polussa ei ole kaaria.
|
|||
|
|
|||
|
Polkupeitteen etsiminen voidaan tulkita paritusongelmana
|
|||
|
verkossa, jossa jokaista alkuperäisen verkon solmua
|
|||
|
vastaa kaksi solmua: vasen ja oikea solmu.
|
|||
|
Vasemmasta solmusta oikeaan solmuun on kaari,
|
|||
|
jos tällainen kaari esiintyy alkuperäisessä verkossa.
|
|||
|
Ideana on, että paritus määrittää, mitkä solmut
|
|||
|
ovat yhteydessä toisiinsa poluissa.
|
|||
|
|
|||
|
Esimerkkiverkossa tilanne on seuraava:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1a) at (0,6) {1};
|
|||
|
\node[draw, circle] (2a) at (0,5) {2};
|
|||
|
\node[draw, circle] (3a) at (0,4) {3};
|
|||
|
\node[draw, circle] (4a) at (0,3) {4};
|
|||
|
\node[draw, circle] (5a) at (0,2) {5};
|
|||
|
\node[draw, circle] (6a) at (0,1) {6};
|
|||
|
\node[draw, circle] (7a) at (0,0) {7};
|
|||
|
|
|||
|
\node[draw, circle] (1b) at (4,6) {1};
|
|||
|
\node[draw, circle] (2b) at (4,5) {2};
|
|||
|
\node[draw, circle] (3b) at (4,4) {3};
|
|||
|
\node[draw, circle] (4b) at (4,3) {4};
|
|||
|
\node[draw, circle] (5b) at (4,2) {5};
|
|||
|
\node[draw, circle] (6b) at (4,1) {6};
|
|||
|
\node[draw, circle] (7b) at (4,0) {7};
|
|||
|
|
|||
|
\node[draw, circle] (a) at (-3,3) {\phantom{0}};
|
|||
|
\node[draw, circle] (b) at (7,3) {\phantom{0}};
|
|||
|
|
|||
|
%\path[draw,thick,->,>=latex] (1a) -- (5b);
|
|||
|
\path[draw,thick,->,>=latex] (2a) -- (6b);
|
|||
|
%\path[draw,thick,->,>=latex] (3a) -- (4b);
|
|||
|
%\path[draw,thick,->,>=latex] (5a) -- (6b);
|
|||
|
\path[draw,thick,->,>=latex] (6a) -- (3b);
|
|||
|
%\path[draw,thick,->,>=latex] (6a) -- (7b);
|
|||
|
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (1a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (2a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (3a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (4a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (5a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (6a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (7a);
|
|||
|
|
|||
|
\path[draw,thick,->,>=latex] (1b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (2b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (3b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (4b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (5b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (6b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (7b) -- (b);
|
|||
|
|
|||
|
\path[draw=red,thick,->,line width=2pt] (1a) -- (5b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (5a) -- (6b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
|||
|
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tässä tapauksessa maksimiparitukseen kuuluu neljä kaarta,
|
|||
|
jotka vastaavat alkuperäisen verkon kaaria
|
|||
|
$1 \rightarrow 5$, $3 \rightarrow 4$,
|
|||
|
$5 \rightarrow 6$ ja $6 \rightarrow 7$.
|
|||
|
Niinpä pienin solmuerillinen polkupeite syntyy muodostamalla
|
|||
|
polut kyseisten kaarten avulla.
|
|||
|
|
|||
|
Pienimmän polkupeitteen koko on $n-c$, jossa $n$ on verkon
|
|||
|
solmujen määrä ja $c$ on maksimiparituksen kaarten määrä.
|
|||
|
Esimerkiksi yllä olevassa verkossa pienimmän
|
|||
|
polkupeitteen koko on $7-4=3$.
|
|||
|
|
|||
|
\subsubsection{Yleinen peite}
|
|||
|
|
|||
|
Yleisessä polkupeitteessä sama solmu voi kuulua moneen polkuun,
|
|||
|
minkä ansiosta tarvittava polkujen määrä saattaa olla pienempi.
|
|||
|
Esimerkkiverkossa pienin yleinen polkupeite muodostuu
|
|||
|
kahdesta polusta seuraavasti:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (0,0) {1};
|
|||
|
\node[draw, circle] (2) at (2,0) {2};
|
|||
|
\node[draw, circle] (3) at (4,0) {3};
|
|||
|
\node[draw, circle] (4) at (6,0) {4};
|
|||
|
\node[draw, circle] (5) at (0,-2) {5};
|
|||
|
\node[draw, circle] (6) at (2,-2) {6};
|
|||
|
\node[draw, circle] (7) at (4,-2) {7};
|
|||
|
|
|||
|
\path[draw=blue,thick,->,line width=2pt] (1) -- (5);
|
|||
|
\path[draw=blue,thick,->,line width=2pt] (5) -- (6);
|
|||
|
\path[draw=blue,thick,->,line width=2pt] (6) -- (3);
|
|||
|
\path[draw=blue,thick,->,line width=2pt] (3) -- (4);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (2) -- (6);
|
|||
|
\path[draw=green,thick,->,line width=2pt] (6) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Tässä verkossä yleisessä polkupeitteessä on 2 polkua,
|
|||
|
kun taas solmuerillisessä polkupeitteessä on 3 polkua.
|
|||
|
Erona on, että yleisessä polkupeitteessä solmua 6
|
|||
|
käytetään kahdessa polussa.
|
|||
|
|
|||
|
Yleisen polkupeitteen voi löytää lähes samalla
|
|||
|
tavalla kuin solmuerillisen polkupeitteen.
|
|||
|
Riittää täydentää maksimiparituksen verkkoa niin,
|
|||
|
että siinä on kaari $a \rightarrow b$ aina silloin,
|
|||
|
kun alkuperäisessä verkossa solmusta $a$ pääsee
|
|||
|
solmuun $b$ (mahdollisesti usean kaaren kautta).
|
|||
|
|
|||
|
Nyt esimerkkiverkossa on seuraava tilanne:
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1a) at (0,6) {1};
|
|||
|
\node[draw, circle] (2a) at (0,5) {2};
|
|||
|
\node[draw, circle] (3a) at (0,4) {3};
|
|||
|
\node[draw, circle] (4a) at (0,3) {4};
|
|||
|
\node[draw, circle] (5a) at (0,2) {5};
|
|||
|
\node[draw, circle] (6a) at (0,1) {6};
|
|||
|
\node[draw, circle] (7a) at (0,0) {7};
|
|||
|
|
|||
|
\node[draw, circle] (1b) at (4,6) {1};
|
|||
|
\node[draw, circle] (2b) at (4,5) {2};
|
|||
|
\node[draw, circle] (3b) at (4,4) {3};
|
|||
|
\node[draw, circle] (4b) at (4,3) {4};
|
|||
|
\node[draw, circle] (5b) at (4,2) {5};
|
|||
|
\node[draw, circle] (6b) at (4,1) {6};
|
|||
|
\node[draw, circle] (7b) at (4,0) {7};
|
|||
|
|
|||
|
\node[draw, circle] (a) at (-3,3) {\phantom{0}};
|
|||
|
\node[draw, circle] (b) at (7,3) {\phantom{0}};
|
|||
|
|
|||
|
|
|||
|
%\path[draw,thick,->,>=latex] (1a) -- (5b);
|
|||
|
\path[draw,thick,->,>=latex] (1a) -- (6b);
|
|||
|
\path[draw,thick,->,>=latex] (1a) -- (7b);
|
|||
|
\path[draw,thick,->,>=latex] (1a) -- (3b);
|
|||
|
\path[draw,thick,->,>=latex] (1a) -- (4b);
|
|||
|
\path[draw,thick,->,>=latex] (5a) -- (6b);
|
|||
|
\path[draw,thick,->,>=latex] (5a) -- (7b);
|
|||
|
%\path[draw,thick,->,>=latex] (5a) -- (3b);
|
|||
|
\path[draw,thick,->,>=latex] (5a) -- (4b);
|
|||
|
\path[draw,thick,->,>=latex] (6a) -- (7b);
|
|||
|
%\path[draw,thick,->,>=latex] (6a) -- (7b);
|
|||
|
\path[draw,thick,->,>=latex] (6a) -- (3b);
|
|||
|
%\path[draw,thick,->,>=latex] (3a) -- (4b);
|
|||
|
%\path[draw,thick,->,>=latex] (2a) -- (6b);
|
|||
|
\path[draw,thick,->,>=latex] (2a) -- (7b);
|
|||
|
\path[draw,thick,->,>=latex] (2a) -- (3b);
|
|||
|
\path[draw,thick,->,>=latex] (2a) -- (4b);
|
|||
|
|
|||
|
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (1a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (2a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (3a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (4a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (5a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (6a);
|
|||
|
\path[draw,thick,->,>=latex] (a) -- (7a);
|
|||
|
|
|||
|
\path[draw,thick,->,>=latex] (1b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (2b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (3b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (4b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (5b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (6b) -- (b);
|
|||
|
\path[draw,thick,->,>=latex] (7b) -- (b);
|
|||
|
|
|||
|
\path[draw=red,thick,->,line width=2pt] (1a) -- (5b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (5a) -- (3b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (2a) -- (6b);
|
|||
|
\path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|||
|
|
|||
|
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (6b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (7b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (3b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (4b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (6b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (7b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (3b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (4b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (6a) -- (3b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (6b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (7b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (3b);
|
|||
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (4b);
|
|||
|
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
|
|||
|
\subsubsection{Dilworthin lause}
|
|||
|
|
|||
|
\index{Dilworthin lause@Dilworthin lause}
|
|||
|
\index{antiketju@antiketju}
|
|||
|
|
|||
|
\key{Dilworthin lauseen} mukaan suunnatun, syklittömän
|
|||
|
verkon pienin yleinen polkupeite
|
|||
|
on yhtä suuri kuin suurin verkossa oleva \key{antiketju}
|
|||
|
eli kokoelma solmuja,
|
|||
|
jossa minkään kahden solmun välillä ei ole polkua.
|
|||
|
|
|||
|
Esimerkiksi äskeisessä verkossa pienin
|
|||
|
yleinen polkupeite sisältää kaksi polkua,
|
|||
|
joten verkon suurimmassa antiketjussa on kaksi solmua.
|
|||
|
Tällainen antiketju muodostuu esimerkiksi
|
|||
|
valitsemalla solmut 3 ja 7:
|
|||
|
|
|||
|
\begin{center}
|
|||
|
\begin{tikzpicture}[scale=0.9]
|
|||
|
\node[draw, circle] (1) at (0,0) {1};
|
|||
|
\node[draw, circle] (2) at (2,0) {2};
|
|||
|
\node[draw, circle, fill=lightgray] (3) at (4,0) {3};
|
|||
|
\node[draw, circle] (4) at (6,0) {4};
|
|||
|
\node[draw, circle] (5) at (0,-2) {5};
|
|||
|
\node[draw, circle] (6) at (2,-2) {6};
|
|||
|
\node[draw, circle, fill=lightgray] (7) at (4,-2) {7};
|
|||
|
|
|||
|
\path[draw,thick,->,>=latex] (1) -- (5);
|
|||
|
\path[draw,thick,->,>=latex] (2) -- (6);
|
|||
|
\path[draw,thick,->,>=latex] (3) -- (4);
|
|||
|
\path[draw,thick,->,>=latex] (5) -- (6);
|
|||
|
\path[draw,thick,->,>=latex] (6) -- (3);
|
|||
|
\path[draw,thick,->,>=latex] (6) -- (7);
|
|||
|
\end{tikzpicture}
|
|||
|
\end{center}
|
|||
|
|
|||
|
Verkossa ei ole polkua solmusta 3 solmuun 7
|
|||
|
eikä polkua solmusta 7 solmuun 3,
|
|||
|
joten valinta on kelvollinen.
|
|||
|
Toisaalta jos verkosta valitaan mitkä tahansa
|
|||
|
kolme solmua, jostain solmusta toiseen on polku.
|
|||
|
|