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.
|
||
|