DEGREE PROJECT, IN COMPUTER SCIENCE , SECOND LEVEL
STOCKHOLM, SWEDEN 2015
Maxflödesalgoritmer i Java
EN STUDIE AV VIKTEN ATT VÄLJA RÄTT
ALGORITM OCH DATASTRUKTUR FÖR ATT
MINIMERA KÖRTIDEN FÖR EXAKTA
MAXFLÖDESALGORITMER
ERIK BORGSTRÖM, FELIX GRAPE
KTH ROYAL INSTITUTE OF TECHNOLOGY
CSC SCHOOL
Maxflödesalgoritmer i Java
En studie av vikten att välja rätt algoritm och datastruktur för att minimera körtiden
för exakta maxflödesalgoritmer
ERIK BORGSTRÖM, FELIX GRAPE
DD143X Examensarbete inom datalogi, grundnivå
Handledare: Per Austrin
Examinator: Örjan Ekeberg
CSC, KTH 2015-05-08
Referat
Maxflödesproblemet har många praktiska tillämpningar och probleminstanserna kan bli mycket stora. Effektiva implementationer är därför
nödvändigt för att körtiden inte ska bli alltför hög. I den här studien
har två maxflödesalgoritmer, Edmonds-Karps algoritm och GoldbergTarjans push-relabel-algoritm, implementerats i Java med två olika datastrukturer och jämförts med varandra. Det framkommer att det är
fördelaktigt att implementera en mer komplex, objektbaserad, grafrepresentation för grafinstanser som ligger under en kritisk gräns i antal
kanter. När antalet kanter överstiger den kritiska gränsen blir en enklare, men mer minneskrävande, implementation med grannlista av heltal
tillsammans med matriser effektivare. Tyvärr saknas tillräcklig data för
att kunna dra slutsatser om huruvida Edmonds-Karps algoritm eller
Goldberg-Tarjans push-relabel-algoritm är att föredra vid implementation i Java.
Abstract
The maximum flow problem has many real world applications and the
problem instances can get very large. Efficient implementations are
therefore important to limit execution time. In this report, two maximum flow algorithms, Edmonds-Karps algorithm and Goldberg-Tarjans
push-relabel algoritm, has been implemented in Java, each with two
different data structures. The efficiancy of the datastructures and algorithms was evaluated. It was found that a more complex, object based,
graph representation is preferable for graph instances that have fewer
than a critical number of edges. When the number of edges exceeds the
critical limit the simpler, but more memory intensive, graph representation is faster. Due to insufficient data, we were unable to analyze which
of push-relabel and Edmonds-Karp that is preferable to implement in
Java.
Innehåll
1 Inledning
1.1 Syfte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Frågeställning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
2
2
2 Bakgrund
2.1 Ett urval av teoretiska framsteg . . . . . . . . . . . . . . . . . . . . .
2.1.1 Starten - T. E. Harris och F. S. Ross -55 . . . . . . . . . . . .
2.1.2 Den första metoden - L. R. Ford och D. R. Fulkerson -56 . .
2.1.3 De första algoritmerna - E. A. Dinic -70 och J. Edmonds och
R. M. Karp -72 . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.4 Förflöde - A. V. Karzanov -74 . . . . . . . . . . . . . . . . . .
2.1.5 Push-relabel - A. V. Goldberg och R. E. Tarjan -86 . . . . .
2.2 Praktiska jämförelser av algoritmers körtid . . . . . . . . . . . . . .
2.2.1 Utökande stigar vs push-relabel - R. K. Ahuja et al. -97 . . .
2.2.2 Maxflödesalgoritmer vid datorseende - Y. Boykov och V. Kolmogorov -04 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Grundligare genomgång av algoritmerna i rapporten . . . . . . . . .
2.3.1 Edmonds-Karps algoritm . . . . . . . . . . . . . . . . . . . .
2.3.2 Push-relabel med relabel-to-front-regeln . . . . . . . . . . . .
3
3
3
3
3 Metod
3.1 Testdata . . . . . . . . . . . . . . . . . . .
3.2 Hårdvara, operativsystem och JVM . . . .
3.3 Algoritmer, datastrukturer och korrekthet
3.3.1 Val av algoritmer . . . . . . . . . .
3.3.2 Val av datastrukturer . . . . . . .
3.3.3 Korrekthet . . . . . . . . . . . . .
3.3.4 Edmonds-Karp . . . . . . . . . . .
3.3.5 Push-relabel . . . . . . . . . . . . .
3.4 Testmetodik . . . . . . . . . . . . . . . . .
4 Resultat
4.1 Utfall för Edmonds-Karp
3
4
4
5
5
5
5
5
6
.
.
.
.
.
.
.
.
.
7
7
9
9
9
9
9
10
10
10
. . . . . . . . . . . . . . . . . . . . . . . .
13
14
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4.2
4.3
4.4
Utfall för Push-relabel . . . . . . . . . . . . . .
Jämförelser av Edmonds-Karp mot push-relabel
typ . . . . . . . . . . . . . . . . . . . . . . . . .
Vidare undersökning av push-relabel . . . . . .
5 Diskussion och slutsats
5.1 Diskussion . . . . . . . . . . . . . . . . .
5.1.1 Metodkritik . . . . . . . . . . . .
5.1.2 Edmonds-Karp . . . . . . . . . .
5.1.3 Push-relabel . . . . . . . . . . . .
5.1.4 Edmonds-Karp mot Push-relabel
5.2 Slutsats . . . . . . . . . . . . . . . . . .
5.2.1 Edmonds-Karp . . . . . . . . . .
5.2.2 Push-relabel . . . . . . . . . . . .
5.2.3 Edmonds-Karp mot push-relabel
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . .
på grafer av
. . . . . . .
. . . . . . .
. . . . .
samma
. . . . .
. . . . .
19
22
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
25
25
25
25
26
26
26
26
26
27
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
Bilagor
27
A Edmonds-Karp
29
B Push-relabel
31
C Hårdvara
35
D Kompilering
D.1 LLVM och Clang . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
D.2 Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
D.3 Referenslösare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
39
39
39
Litteraturförteckning
41
Kapitel 1
Inledning
Flödesproblem är en viktig klass optimeringsproblem inom bland annat datalogi
och operationsanalys. Maxflödesproblemet är ett flödesproblem som ursprungligen
formulerades av T. Harris 1956:
“Consider a rail network connecting two cities by way of a number of
intermediate cities, where each link of the network has a number assigned
to it representing its capacity. Assuming a steady state condition, find
a maximal flow from one given city to the other.” [1]
Ett annat sätt att se på maxflödesproblemet är att betrakta en graf G, med en
mängd kanter E och en mängd hörn V. Varje kant motsvarar en vattenledning och
varje hörn motsvarar att vattenledningar möts, förgrenas eller slutar. I grafen finns
två speciella hörn, en källa, s (kort för eng: source), och en sänka, t (kort för eng:
tap), som producerar respektive konsumerar vatten i samma takt. Flödet i en punkt
i grafen motsvaras av hastigheten med vilken vattnet färdas. Maxflödesproblemet
går ut på att maximera flödet mellan s och t. [2]
Maxflödesproblemet är väl undersökt på grund av dess tillämpbarhet inom bland
annat transport, telekommunikation, schemaläggning och för olika former av eloch vattennät. Samtidigt finns det inte något uppenbart sätt att enkelt och snabbt
beräkna det maximala flödet exakt. En följd av detta är att många små teoretiska
framsteg har gjorts, där långt ifrån alla har inneburit empiriskt snabbare algoritmer.
[2]
De vanligaste metoderna för att lösa maxflödesproblemet bygger antingen på
användande av utökande stigar, som i Edmonds-Karp, eller förflöde (eng: preflow),
som i push-relabel. Tidskomplexiteten för implementationer av dessa algoritmer
beror på hur den utökande stigen väljs respektive vilket hörn som väljs för att
skjuta förflödet genom. Tidskomplexiteten kan även påverkas av den datastruktur
som används. [2]
1
KAPITEL 1. INLEDNING
1.1
Syfte
Den här avhandlingen ämnar att undersöka hur valet av datastruktur och algoritm
påverkar körtiden för maxflödesalgoritmer i Java. Eftersom bättre teoretisk värstafallstidskomplexitet inte nödvändigtvis leder till empiriskt snabbare algoritmer är
det av intresse att empiriskt undersöka körtiden för olika implementationer. Empiriska studier är än mer relevanta för implementationer av maxflödesalgoritmer i
Java. Detta eftersom Java körs på en virtuell maskin som utför realtidsoptimeringar
av programkoden och har automatisk skräpsamling, vilket kan påverka körtiden.
Studien skiljer sig från tidigare undersökningar på flera sätt. Dels implementeras
algoritmerna i Java och dessutom ligger fokus främst på hur val av datastruktur
påverkar körtiden. Studien har avgränsats och undersöker endast Edmonds-Karps
algoritm och Goldberg-Tarjans push-relabel-algoritm med relabel-to-front-regeln,
båda med två datastrukturer vardera.
1.2
Frågeställning
Hur påverkar valet av datastruktur körtiden för implementationer av maxflödesalgoritmer i Java för olika typer av grafer? Hur står sig Edmonds-Karps algoritm mot
en, teoretiskt, asymptotiskt snabbare push-relabel algoritm när de implementeras i
Java?
2
Kapitel 2
Bakgrund
2.1
2.1.1
Ett urval av teoretiska framsteg
Starten - T. E. Harris och F. S. Ross -55
I en artikel från 1955 undersökte och presenterade Harris och Ross grunderna för
en metod för att hitta ett minimalt snitt i ett flödesnätverk. Genom att hitta ett
minsta snitt är det möjligt att maximera effekterna av att till exempel göra en eller
flera av fiendens järnvägssträckor obrukbara. På så vis kan fiendens transporter av
personal och materiel mellan två städer minimeras. [3]
2.1.2
Den första metoden - L. R. Ford och D. R. Fulkerson -56
1956 bevisade Ford och Fulkerson satsen om maximalt flöde och minsta snitt. Satsen
säger att för en graf, där varje kant har en flödeskapacitet, är det största flödet
mellan två hörn lika med det minsta möjliga snitt som separerar dessa hörn. De
fastställde på så vis även att det alltid finns ett maximalt flöde i en sådan graf. I
artikeln presenteras även den första kända metoden för att lösa maxflödesproblemet.
[1] [4]
Ford-Fulkerson är en iterativ metod som vid varje iteration hittar en utökande
stig som höjer flödet i nätverket. Hur den utökande stigen väljs är kritiskt avgörande för tidskomplexiteten för algoritmer som implementerar Ford-Fulkersons metod.
För nätverk med heltalskapaciteter terminerar Ford-Fulkersons metod alltid, men
metoden löser inte problemet i polynomisk tid, tidskomplexiteten är O(E|f|), där f
är det maximala flödet i grafen. [2]
2.1.3
De första algoritmerna - E. A. Dinic -70 och J. Edmonds och R.
M. Karp -72
Den algoritm som brukar kallas Edmonds-Karps algoritm är en implementation av
Ford-Fulkersons metod där ytterligare ett krav ställs på den utökande stigen. Utöver
3
KAPITEL 2. BAKGRUND
att ha tillgänglig kapacitet måste den även innehålla ett minimalt antal kanter. En
stig med ett minimalt antal kanter kan hittas med bredden-först-sökning. [5]
Algoritmen publicerades först av Dinic 1970 och sedan oberoende av Edmonds
och Karp 1972 och är första kända algoritm som löser maxflödesproblemet i polynomisk tid, O(V E 2 ). Dinics algoritm använder bland annat blockerande flöde, vilket
minskar tidskomplexiteten till O(V 2 E). [5] [6]
2.1.4
Förflöde - A. V. Karzanov -74
Karzanovs algoritm introducerade ett koncept som kallas förflöde. Förflöde fungerar
som ett vanligt flöde med skillnaden att överflöd in i hörnet är tillåtet. Förflöde
blir till flöde i grafen när ett hörn balanseras så att flödet in i hörnet är lika med
flödet ut ur hörnet. Till skillnad från Dinic och Edmonds-Karps algoritmer beräknas
maxflödet med operationer på hörn istället för på stigar eller kanter. [2] [7]
Algoritmen består av många faser där målet i varje fas är att hitta det maximala
flödet i en skiktad graf (eng: layered graph). I varje fas beräknas det maximala flödet
med två operationer, framflyttning och balansering av förflöde, som itereras tills
varje hörn är balanserat. Först skjuts så mycket förflöde som möjligt ut från källan,
lager 0, till dess grannar, lager 1. Därefter skjuts förflöde framåt i grafen, lager för
lager, tills det inte längre är möjligt. När det inte är möjligt att flytta fram mer
förflöde i något hörn balanseras grafens hörn, varpå nästa fas startar. För alla hörn
ligger dess utgående kanter i en kö där förflödet skjuts till hörnets grannar enligt
den ordning kanterna ligger i kön. För att kunna sänka flödet in i ett hörn läggs
kanterna på en stack i den ordning de behandlades. Vid säkning och balansering
av flöde är det därför den senast behandlade kantens flöde som sänks. Det ger en
algoritm som löser maxflödesproblemet i O(V 3 ). [2] [7] [8]
2.1.5
Push-relabel - A. V. Goldberg och R. E. Tarjan -86
Goldberg och Tarjan introducerade en push-relabel algoritm som bygger vidare
på Karzanovs förflödeskoncept. Push-relabel-algoritmen använder en märkning av
hörn som är tänkt att approximera längden av kortaste stigen till sänkan. Genom
att titta på märkningen avgörs till vilket hörn förflödet skall skjutas. Beroende på
vilken hörnväljningsregel som används kan tidskomplexiteten variera, om relabel-tofront eller högsta-märknings-regeln, där hörnet√
med högsta märkning väljs, används
blir tidskomplexiteten O(V 3 ) respektive O(V 2 E). [7] [9]
Se avsnitt 2.3.2 för en utförligare genomgång av Goldberg-Tarjas push-relabelalgoritm med relabel-to-front-regeln.
4
2.2. PRAKTISKA JÄMFÖRELSER AV ALGORITMERS KÖRTID
2.2
2.2.1
Praktiska jämförelser av algoritmers körtid
Utökande stigar vs push-relabel - R. K. Ahuja et al. -97
Ahuja et al. fann i en empirisk studie av maxflödesalgoritmer implementerade i
Fortran att förflödes-algoritmer är väsentligt snabbare än algoritmer som bygger på
utökande stigar. Förflödes-algoritmerna som undersöktes var Karzanovs algoritm
och tre implementationer av Goldberg och Tarjans push-relabel-algoritm. Goldberg
och Tarjans algoritm där hörnet med högsta märkning väljs för att skjuta flödet
genom är empiriskt snabbast. På fyra av fem klasser av maxflödesproblemet ligger
körtiden i O(V 1.5 ). [9]
2.2.2
Maxflödesalgoritmer vid datorseende - Y. Boykov och V.
Kolmogorov -04
I en studie av maxflödesalgoritmers körtid från 2004 finner Boykov och Kolmogorov att deras egenutvecklade algoritm är snabbast av algoritmerna som undersöks.
Boykov och Kolmogorovs algoritm, som bygger på utökande stigar, är snabbare än
både Dinics algoritm och Goldberg-Tarjans push-relabel algoritm när de används
för datorseende. För att uppnå hög prestanda i sin algoritm använder Boykov och
Kolmogorov bland annat en specialiserad FIFO-kö (eng: First In First Out) för
bredden-först-sökningen och märkningar av hörnen så att sökningen i stigar som
inte kan nå sluthörnet termineras. Push-relabel är implementerad i två versioner:
en med köbaserad regel och en med högsta-märknings regel för att välja hörn att
skjuta förflöde genom. Dessutom används heurestik för att minska antalet onödiga
relabel-operationer. Samtliga algoritmer implementerades i C++. [10]
2.3
Grundligare genomgång av algoritmerna i rapporten
Givet en graf G = (V, E), där alla (v, w) ∈ E har givna kapaciteter c(v, w), använder
sig algoritmerna av flödesgrafen Gf = (V, E2 ), där E2 = E∪Er och där Er innehåller
(w, v) för alla (v, w) ∈ E. Varje kant (v, w) ∈ Gf har en kapacitet, c(v, w), och ett
flöde, f (v, w). För alla (v, w) ∈ E2 där (v, w) ∈ Er är c(v, w) = 0. Initialt är
f (v, w) = 0 för alla (v, w) ∈ E2 .
2.3.1
Edmonds-Karps algoritm
Algoritmen använder sig av upprepade bredden-först-sökningar från källan, s, till
sänkan, t, i restkapacitetsgrafen Gr för att hitta utökande stigar. Gr innehåller de
kanter (v, w) ∈ Gf för vilka c(v, w) − f (v, w) > 0. När en utökande stig p, från s till
t, hittats i Gr uppdateras flödet längs stigen med stigens kapacitet, min(c(v, w))
för alla (v, w) ∈ p. Om stigens kapacitet är m uppdateras Gf enligt följande: för
alla (v, w) ∈ p, f (v, w) = f (v, w) + m och f (w, v) = f (v, w) − m. När det inte finns
5
KAPITEL 2. BAKGRUND
en stig mellan s och t i Gr har ett maximalt flöde mellan s och t uppnåtts. Det
P
maximala flödet för G är då f (s, w) då (s, w) ∈ E2 .
I appendix A finns pseudokod för Edmonds-Karps algoritm för en graf representerad som en grannlista tillsammans med en kapacitets- och flödesmatris. Implementationer som använder en utvidgad grannlista följer samma struktur men skiljer
sig när det gäller åtkomst av en kants flöde, kapacitet och omvänd kant.
2.3.2
Push-relabel med relabel-to-front-regeln
Varje hörn v i Gf har ett överflöd, e(v) och en höjd, h(v). Överflödet i ett hörn
är flödet in i hörnet minus flödet ut ur hörnet. Höjden för ett hörn är tänkt att
representera kortaste avståndet till sänkan räknat i antalet kanter. Överflödet i
källan initieras till oändligheten och dess höjd sätts till |V | ty längsta stigen från
källa till sänka är kortare än |V |. Algoritmen använder två operationer: push och
relabel.
• Push är applicerbar på en kant (v, w) ∈ E2 om c(v, w)−f (v, w) > 0 och h(v) >
h(w). Push ökar då flödet från v till w med x, där x = min(e(v), c(v, w) −
f (v, w)). e(v) och f (w, v) minskas med x samtidigt som e(w) och f (v, w) ökas
med x.
• Relabel kan utföras på alla hörn. Om relabel utförs på hörnet v sätts h(v) till
1 + min(h(wi )) för alla wi då (v, wi ) ∈ E2 .
För alla hörn v utförs en lämplig push- eller relabel-operation så länge e(v) > 0.
En kö används för att ange ordningen i vilken hörnen bearbetas. Om h(v) ökar för
ett hörn v efter att en relabel-operation utförts på hörnet läggs detta hörn först i kön
och algoritmen börjar om från början på kön. När det inte går att utföra varken en
push- eller relabel-operation har ett maximalt flöde uppnåtts. Det maximala flödet
P
för G är då f (s, w) då (s, w) ∈ E2 .
I appendix B finns pseudokod för en push-relabel-algoritm med relabel-to-frontregeln implementerad med grannlista tillsammans med en kapacitets- och flödesmatris. Implementationer som använder en utökad grannlista följer samma struktur
men skilljer sig när det gäller åtkomst av en kants flöde, kapacitet och omvänd kant.
6
Kapitel 3
Metod
3.1
Testdata
För testerna genereras grafer med generatorerna washington.c1 och ac.c från DIMACS första implementationstävling. Med washington.c genereras grafer av meshtyp med parametrar r, c och cap som specificerar antal rader, kolumner respektive
maxkapacitet för kanterna. Parametervärden väljs så att antal hörn ökar med ungefär 1000 upp till 5000 hörn. Generatorn ac.c genererar fullständigt täta acykliska
grafer med parametrar v och s som specificerar antal hörn respektive seed till slumptalsgeneratorn. Parametervärden väljs så att mängden hörn ökar med 150 upp till
750 hörn. I tabell 3.1 presenteras parametrar och storlek för samtliga genererade
grafinstanser. [11] [12] [13]
En uppsättning av tre typer av meshgrafer genereras, breda, långa och kvadratiska. Tre typer genereras eftersom kanterna från källan och till sänkan har fix
kapacitet. Därför påverkar grafernas relativa bredd det högsta möjliga flödet ut
från källan respektive in till sänkan, vilket i sin tur kan påverka det totala flödet i
grafen. Dessa grafer blir relativt glesa varför även fullständigt täta acykliska grafer
genereras för att undersöka ytterligare en graftyp.
• WB - Washington-Bred. Genereras med washington.c. Bred ty c ≈ r2 .
• WL - Washington-Lång. Genereras med washington.c. Lång ty r ≈ c2 .
• WK - Washington-Kvadrat. Genereras med washington.c. Kvadrat ty r ≈ c.
• AC - Fullständigt täta acykliska grafer. Genereras med ac.c.
1
För att washington.c ska kompilera med Apple LLVM version 6.1.0 (clang-602.0.49) se appendix D
7
KAPITEL 3. METOD
Graf
Parametrar
Hörn
Kanter
WB1
WB2
WB3
WB4
WB5
WL1
WL2
WL3
WL4
WL5
WK1
WK2
WK3
WK4
WK5
AC1
AC2
AC3
AC4
AC5
r: 10,c: 100,cap: 10000
r: 12,c: 167,cap: 10000
r: 15,c: 200,cap: 10000
r: 16,c: 256,cap: 10000
r: 17,c: 294,cap: 10000
r: 100,c: 10,cap: 10000
r: 167,c: 12,cap: 10000
r: 200,c: 15,cap: 10000
r: 256,c: 16,cap: 10000
r: 294,c: 17,cap: 10000
r: 31,c: 32,cap: 10000
r: 44,c: 45,cap: 10000
r: 55,c: 55,cap: 10000
r: 63,c: 64,cap: 10000
r: 70,c: 71,cap: 10000
v: 150,s: 0
v: 300,s: 0
v: 450,s: 0
v: 600,s: 0
v: 750,s: 0
1002
2006
3002
4098
5000
1002
2006
3002
4098
5000
994
1982
3027
4034
4972
150
300
450
600
750
2990
6000
8985
12272
14977
2900
5845
8800
12032
14700
2945
5896
9020
12033
14840
11175
44850
101025
179700
280875
Tabell 3.1. Valda parametrar och antal genererade hörn och kanter för vardera graf.
Figur 3.1 illustrerar strukturen för meshgrafer genererade washington.c. Grafen
har 3 rader och 3 kolumner, av estetiska skäl har grafen roterats 90° åt vänster,
hörn 2, 3 och 4 utgör således en rad, inte en kolumn. Varje hörn har kanter, med
pseudoslumptalsgenererad kapacitet i intervallet [1, 10000], till alla hörn i nästa rad.
För kanterna från källa och till sänka är kapaciteten tre gånger maxkapaciteten, för
alla grafer oavsett antal rader eller kolumner.
Figur 3.1. En graf med tre kolumner och 3 rader genererad med washington.c med
kapaciteter utelämnade.
8
3.2. HÅRDVARA, OPERATIVSYSTEM OCH JVM
3.2
Hårdvara, operativsystem och JVM
För att minska yttre omständigheters verkan på körtiden körs ett minimalt antal
bakgrundsprocesser. Processorns klockfrekvens låses och alla dess strömsparsfunktioner stängs av. Detta för att minimera klockfrekvensvarians och bakgrundsprocessers påverkan på testresultaten. I tabell 3.2 presenteras testsystemets hårdvara,
operativsystem, Javaversion och JVM.
Typ
Namn
Specifikation
Operativsystem
JVM
Java
Processor
Moderkort
Minne
Lagringsenhet
Microsoft Windows 7 SP1
HotSpot 64-Bit Server VM
1.8.0_45
Intel 2600K
MSI P67A-GD65
G.Skill 4x4 GB DDR3
OCZ Vertex 3 Max IOPS
64-bit
Build 25.45-b02
Build 1.8.0_45-b14
4.5 GHz
N/A
1600 MHz / 9-9-9-24
120 GB
Tabell 3.2. Specifikationer för testsystemet
3.3
3.3.1
Algoritmer, datastrukturer och korrekthet
Val av algoritmer
De två algoritmerna valdes bland annat för att de bygger på två fundamentalt
olika tekniker, utökande stigar respekive förflöde, och har olika tidskomplexitet.
Algoritmerna är dessutom lätta att implementera, vilket gör korrekthet lättare att
uppnå.
3.3.2
Val av datastrukturer
De två datastrukturena valdes så att den teoretiska tidskomplexiteten för båda
implementationerna av respektive algoritm blir samma. Samtliga datastrukturer
har konstant tidskomplexitet för operationerna i algoritmerna.
3.3.3
Korrekthet
Algoritmernas korrekthet kontrollerades med referenslösaren dinic.c2 från DIMACS
första implementationstävling. [14] Samtliga testade grafers maximala flödes beräknades med referenslösaren och med de undersökta algoritmerna och jämfördes
därefter. För samtliga genererade grafer beräknade de undersökta algoritmerna och
referenslösaren samma värde. Detta i kombination med grafernas regelbundna struktur gör att korrekthet kan antas.
2
För att dinic.c ska kompilera med Apple LLVM version 6.1.0 (clang-602.0.49) se appendix D
9
KAPITEL 3. METOD
Figur 3.2. En enkel graf och dess representation som grannlista av kantobjekt med
referenser till omvända kanten.
3.3.4
Edmonds-Karp
Den första implementationenen använder en grannlista med heltal. Grannlistan används för att indexera in i flödes- och en kapacitetsmatriser. Flöde respektive kapacitet för en kant (v, w) återfinns på plats (v, w) i flödes- respektive kapacitetsmatriserna. Den utökande stigen sparas i en förälderlista.
Den andra implementationen använder en grannlista av kantobjekt. Figur 3.2
illustrerar en förenklad version av grannlistan. Kantobjekten innehåller start- och
destinationshörn för kanten, flöde, kapacitet och en referens till den omvända kanten. Den utökande stigen sparas i en förälderlista.
3.3.5
Push-relabel
Den första implementation använder en grannlista med heltal. Grannlistan används
för att indexera in i flödes- och kapacitetsmatriser. Värde på flöde respektive kapacitet för en kant (v, w) återfinns på plats (v, w) i flödes- respektive kapacitetsmatriserna. Överflöd och höjd sparas i arrayer av längd |V |.
Den andra imlementationen använder en grannlista med kantobjekt. Kantobjekten innehåller destinationshörn, flöde, kapacitet och en referens till den omvända
kanten. Figur 3.2 illustrerar en förenklad version av grannlistan. Överflöd och höjd
sparas i arrayer av längd |V |.
3.4
Testmetodik
Ett testramverk utformat av Boyer används för att undvika kända problem med
tidsmätning i Java. Testramverkat minimerar en rad felfaktorer som den virtuella
maskinen introducerar. Genom att värma upp och försöka försätta den virtuella
maskinen i ett stabilt tillstånd undviks så kallad JIT-kompilering (eng: Just-in-time
compilation) och ytterligare optimeringar av stacken. Restramverket utför varje
test ett tillräckligt antal gånger och därefter beräknas ett observerat väntevärde
10
3.4. TESTMETODIK
och standardavikelse. Bootstrap används för att bestämma konfidensintervall med
konfidensgraden 95% för väntevärde och standardavvikelse. [15] [16]
Algoritmerna testas en i taget av Boyers testramverk och för varje grafinstans
skapas en ny virtuell Java-maskin. Detta undviker att optimeringar som den virtuella maskinen har utfört för ett tidigare test ger negativ inverkan på ett senare. [17]
Inläsning av data och skapandet av datastrukturerna räknas inte med i körtiden.
Datastrukturerna återanvänds under ett helt test för att undvika skräpsamling. För
att detta inte ska påverka beräkningen av det maximala flödet återställs datastrukturerna till ett initialläge inför varje beräkning. Återställning av datastrukturerna
sker på O(|E|) tid för samtliga algoritmer.
11
Kapitel 4
Resultat
Testresultaten presenteras både i tabell- och diagramform. Tabellerna innehåller
observerat väntevärde för körtiden, dess variationskoefficient och konfidensintervall
med konfidensgrad 95% för samtliga grafinstanser och implementationer.
Testresultaten presenteras även på diagramform för snabba översiktsjämförelser.
I varje diagram har varje graftyp fått en unik datapunktsmarkör och varje algoritm
en unik färg och linjestil. Alla diagram har en teckenförklaring som specificerar vilken linjetyp, färg och datapunktsmarkör som motsvarar vilken algoritm och graftyp.
Namnen i teckenförklaringen hämtas från tabellerna. Linje EK1-WL i figur 4.1
motsvarar således utfallet av Edmonds-Karps algoritm, implementerad med grannlista av heltal med matriser, för de långa meshgraferna WL. För push-relabelalgoritmerna genererades dessutom en andra uppsättning grafinstanser och antalet
karaktäristiska operationer räknades för att möjliggöra djupare analys. Dessa resultat betecknas på samma vis och utöver detta med suffixet b. Linje PR2-ACb i
figur 4.2 motsvarar således utfallet av push-relabel implementerad med grannlista
av kantobjekt för andra uppsättningen AC-grafer.
13
KAPITEL 4. RESULTAT
4.1
Utfall för Edmonds-Karp
EK2 är en faktor två snabbare än EK1 för de glesa meshgraferna men för hög graftäthet uppvisas motsatt beteende. För AC-graferna är EK1 snabbare när grafstorleken
når upp i över 600 hörn. Variationskoefficienten är låg, < 1%, för samtliga grafinstanser utom en för både EK1 och EK2.
Graf
Edmonds-Karp
Grannlista med matriser (EK1)
E(X) (s)
cv (%)
95% CI (ms)
WB1
WB2
WB3
WB4
WB5
0,07
0,43
0,92
1,75
2,82
0,42
0,24
0,22
0,08
0,13
[-0,02,
[-0,10,
[-0,34,
[-0,35,
[-0,90,
WL1
WL2
WL3
WL4
WL5
0,08
0,38
0,94
1,77
2,66
0,79
0,32
0,16
0,27
0,15
WK1
WK2
WK3
WK4
WK5
0,10
0,41
1,14
1,87
2,96
AC1
AC2
AC3
AC4
AC5
0,00
0,10
0,30
0,70
1,33
Grannlista av kantobjekt (EK2)
E(X) (s)
cv (%)
0,04
0,21
0,44
0,80
1,36
0,36
0,06
0,31
0,46
0,52
[-0,0058, +0,0069]
[-0,012, +0,010]
[-0,19, +0,15]
[-0,49, +0,96]
[-0,0013, +0,0025]
[-0,041, +0,036]
[-0,14, +0,16]
[-0,25, +0,28]
[-1,12, +1,30]
[-0,96, +1,04]
0,04
0,19
0,43
0,85
1,20
0,26
0,12
0,15
0,34
0,21
[-0,0048, +0,0051]
[-0,022, +0,018]
[-0,078, +0,088]
[-0,49, +0,54]
[-0,67, +0,60]
0,46
0,19
0,15
0,13
0,15
[-0,030, +0,028]
[-0,10, +0,097]
[-0,43, +0,437]
[-0,67, +0,59]
[-1,14, +1,07]
0,05
0,20
0,53
0,90
1,38
0,16
0,10
0,10
0,08
0,12
[-0,0038, +0,0038]
[-0,018, +0,017]
[-0,091, +0,092]
[-0,12, +0,13]
[-0,33, +0,49]
6,27
0,42
0,22
0,16
0,10
[-0,0021, +0,0021]
[-0,027, +0,024]
[-0,08, +0,091]
[-0,18, +0,21]
[-0,30, +0,34]
0,01
0,08
0,26
1,14
2,66
3,29
0,85
0,52
0,24
0,22
[-0,0064, +0,0062]
[-0,045, +0,041]
[-0,18, +0,17]
[-0,70, +0,71]
[-1,15, +1,95]
+0,02]
+0,18]
+0,38]
+0,33]
+0,90]
95% CI (ms)
Tabell 4.1. Väntevärde, standardavvikelse och konfidensintervall för körtiden.
14
4.2. UTFALL FÖR PUSH-RELABEL
3
2.5
EK1-WB
EK1-WL
EK1-WK
EK1-AC
EK2-WB
EK2-WL
EK2-WK
EK2-AC
Sekunder
2
1.5
1
0.5
0
10
4
10
5
Antal kanter (log)
Figur 4.1. Edmonds-Karp för samtliga testgrafer.
4.2
Utfall för Push-relabel
Testresultaten för push-relabel-algoritmerna är delvis inkonsekventa. Körtiden sjunker för vissa grafinstanser när instansstorleken ökar. För PR1 är variationskoefficienten låg, < 1%, för alla utom två grafinstanser och konfidensintervallen är smala. För
PR2 är variationskoefficienten hög, > 1%, för nästan alla grafinstanser och mycket
hög, > 10%, för fyra grafinstanser.
15
KAPITEL 4. RESULTAT
Push-relabel
Graf
Grannlista med matriser (PR1)
E(X) (s)
cv (%)
WB1
WB2
WB3
WB4
WB5
0,41
0,11
0,33
18,47
1,71
0,11
0,23
0,15
0,02
0,10
WL1
WL2
WL3
WL4
WL5
0,03
0,09
0,38
0,84
22,61
WK1
WK2
WK3
WK4
WK5
AC1
AC2
AC3
AC4
AC5
Grannlista av kantobjekt (PR2)
95% CI (ms)
E(X) (s)
cv (%)
95% CI (ms)
[-0,057, +0,060]
[-0,015, +0,016]
[-0,061, +0,066]
[-0,47, +1,64]
[-0,30, +0,29]
0,27
0,08
0,19
16,13
1,05
9,68
4,21
4,52
4,64
4,32
[-3,52, +3,10]
[-0,19, +0,21]
[-0,78, +0,75]
[-165,18, +219,60]
[-10,51, +12,81]
0,33
0,23
0,11
0,07
0,01
[-0,015, +0,03]
[-0,01, +0,013]
[-0,05, +0,054]
[-0,10, +0,11]
[-0,63, +0,69]
0,02
0,05
0,19
0,52
13,21
5,30
1,70
1,45
3,76
9,91
[-0,033, +0,034]
[-0,037, +0,039]
[-0,23, +0,27]
[-3,34, +3,67]
[-308,1, +358,4]
0,02
1,72
21,01
5,49
1,65
0,44
0,07
0,01
0,04
0,08
[-0,0033, +0,0032]
[-0,28, +0,28]
[-0,71, +0,72]
[-0,49, +0,54]
[-0,33, +0,35]
0,01
1,12
12,85
3,03
0,80
10,86
11,88
6,71
6,98
6,25
[-0,034, +0,034]
[-22,98, +24,38]
[-165,1, +308,8]
[-50,61, +57,23]
[-8,14, +9,89]
0,00
0,03
0,02
0,68
1,00
4,48
0,64
1,07
0,04
0,03
[-0,00012, +0,00039]
[-0,0090, +0,01061]
[-0,0035, +0,0036]
[-0,047, +0,049]
[-0,060, +0,062]
0,00
0,07
0,00
1,85
4,69
115,38
2,93
31,08
0,80
0,51
[-0,0000004, +0,0000004]
[-0,13, +0,13]
[-0,0000011, +0,0000012]
[-3,82, +3,62]
[-6,64, +5,61]
Tabell 4.2. Väntevärde, standardavvikelse och konfidensintervall för körtiden.
För att undersöka push-relabel-algoritmernas inkonsekventa testresultat genomfördes ytterligare tester. För att verifiera testresultaten utfördes tester på samma
grafer igen. De nya testresultaten föll inom konfidensintervallen för de resultat som
presenterades i tabell 4.2. Därför genererades nya grafer med samma parametrar,
undantaget seed till slumptalsgenereringen för kanternas kapaciteter. Därefter testades algoritmerna på de nya graferna. Testresultaten presenteras i tabell 4.3 och
är fortsatt inkonsekventa. För PR1 är testresultatens variationskoefficient fortsatt
låg. För PR2 är variationskoefficienten låg, < 1%, för fem grafinstanser, och mycket
hög, > 10%, för två grafinstanser, något lägre än i första omgången tester.
16
4.2. UTFALL FÖR PUSH-RELABEL
Graf
Push-relabel
Grannlista med matriser (PR1)
E(X) (s)
cv (%)
WBb1
WBb2
WBb3
WBb4
WBb5
0,14
1,46
6,86
0,29
6,02
0,34
0,11
0,04
0,22
0,04
WLb1
WLb2
WLb3
WLb4
WLb5
0,03
0,17
0,35
0,99
0,87
WKb1
WKb2
WKb3
WKb4
WKb5
ACb1
ACb2
ACb3
ACb4
ACb5
95% CI (ms)
Grannlista av kantobjekt (PR2)
E(X) (s)
cv (%)
95% CI (ms)
[-0,043, +0,041]
[-0,42, +0,39]
[-0,73, +0,74]
[-0,078, +0,082]
[-0,59, +0,56]
0,11
1,09
3,75
0,13
3,38
6,85
1,16
0,01
0,72
6,51
[-0,47, +0,49]
[-3,143, +3,231]
[-54,43, +59,08]
[-0,09, +0,08]
[-57,52, +53,76]
0,48
0,24
0,15
0,10
0,13
[-0,0048, +0,0048]
[-0,035, +0,038]
[-0,067, +0,067]
[-0,18, +0,18]
[-0,20, +0,20]
0,02
0,09
0,19
0,66
0,50
4,55
2,96
1,40
7,39
2,36
[-0,03,
[-0,18,
[-0,23,
[-8,72,
[-2,12,
0,06
1,94
1,78
0,66
47,56
0,00
0,04
0,09
0,12
0,01
[-0,096, +0,011]
[-0,29, +0,29]
[-0,36, +0,41]
[-0,14, +0,14]
[-0,63, +2,316]
0,04
1,13
1,12
0,28
28,63
2,10
6,10
14,98
6,56
12,31
[-0,04, +0,04]
[-15,69, +19,30]
[-36,12, +51,09]
[-2,42, +2,23]
[-770,25, +1067]
0,03
0,11
0,40
1,05
1,09
1,17
0,52
0,33
0,20
0,15
[-0,010, +0,011]
[-0,036, +0,033]
[-0,17, +0,16]
[-0,54, +0,54]
[-0,39, +0,44]
0,03
0,18
0,75
2,87
3,40
1,32
2,04
0,81
0,44
0,89
[-0,019, +0,019]
[-0,22, +0,57]
[-1,08, +1,10]
[-3,11, +3,20]
[-8,13, +7,16]
+0,03]
+0,17]
+0,25]
+8,70]
+2,01]
Tabell 4.3. Resultat för nya grafinstanser med samma parametrar och ändrat seed.
17
KAPITEL 4. RESULTAT
10 1
10 0
Sekunder (log)
10 -1
10 -2
10
-3
10 -4
10 -5
PR1-AC
PR2-AC
PR1-ACb
PR2-ACb
10 -6
0
0.5
1
1.5
Antal kanter
2
2.5
3
×10 5
Sekunder (log)
Figur 4.2. Push-Relabel på AC-graferna.
10
2
10
1
10 0
PR1-WB
PR1-WL
PR1-WK
PR2-WB
PR2-WL
PR2-WK
PR1-WBb
PR1-WLb
PR1-WKb
PR2-WBb
PR2-WLb
PR2-WKb
10 -1
10 -2
4000
6000
8000
Antal kanter
10000
Figur 4.3. Push-relabel på W-graferna.
18
12000
14000
4.3. JÄMFÖRELSER AV EDMONDS-KARP MOT PUSH-RELABEL PÅ GRAFER AV
SAMMA TYP
4.3
Jämförelser av Edmonds-Karp mot push-relabel på
grafer av samma typ
10 1
10 0
Sekunder (log)
10 -1
10
-2
10
-3
10 -4
10 -5
10 -6
EK1-AC
EK2-AC
PR1-AC
PR2-AC
PR1-ACb
PR2-ACb
0
0.5
1
1.5
Antal kanter
2
Figur 4.4. Edmonds-Karp mot push-relabel på AC-graferna.
19
2.5
3
×10 5
KAPITEL 4. RESULTAT
10 2
Sekunder (log)
10 1
10 0
10
-1
EK1-WK
EK2-WK
PR1-WK
PR2-WK
PR1-WKb
PR2-WKb
10 -2
4000
6000
8000
Antal kanter
10000
12000
14000
Sekunder (log)
Figur 4.5. Edmonds-Karp mot push-relabel på WK-graferna.
10
2
10
1
10 0
10 -1
EK1-WL
EK2-WL
PR1-WL
PR2-WL
PR1-WLb
PR2-WLb
10 -2
4000
6000
8000
Antal kanter
10000
12000
Figur 4.6. Edmonds-Karp mot Push-Relabel på WL-graferna.
20
14000
Sekunder (log)
4.3. JÄMFÖRELSER AV EDMONDS-KARP MOT PUSH-RELABEL PÅ GRAFER AV
SAMMA TYP
10
2
10
1
10 0
10
-1
EK1-WB
EK2-WB
PR1-WB
PR2-WB
PR1-WBb
PR2-WBb
10 -2
4000
6000
8000
Antal kanter
10000
12000
Figur 4.7. Edmonds-Karp mot Push-Relabel på WB-graferna
21
14000
KAPITEL 4. RESULTAT
4.4
Vidare undersökning av push-relabel
För att möjliggöra än djupare analys av de inkonsekventa utfallen för PR1 och PR2
räknades antalet metodanrop till push och relabel samt antalet förflyttningsoperationer i moveToFront för samtliga grafinstanser. PR1 och PR2 utförde exakt lika
många operationer för samtliga grafinstanser. I tabell 4.4 presenteras resultatet av
dessa tester tillsammans med körtiderna från tabell 4.2 och 4.3.
22
4.4. VIDARE UNDERSÖKNING AV PUSH-RELABEL
Graf
Push-relabel
PR1 (s)
# push
# relabel
# move
PR2 (s)
WB1
WB2
WB3
WB4
WB5
0,41
0,11
0,33
18,47
1,71
7,27e5
7,06e5
2,82e6
1,72e7
9,77e6
3,59e5
4,02e5
1,81e6
8,44e6
5,95e6
7,53e7
2,75e7
4,71e7
5,64e9
3,16e8
0,27
0,08
0,19
16,13
1,05
WL1
WL2
WL3
WL4
WL5
0,03
0,09
0,38
0,84
22,61
3,47e5
9,35e5
1,16e6
6,63e6
1,93e7
2,19e5
6,50e5
6,36e5
3,98e6
9,44e6
4,19e6
1,17e7
6,51e7
1,29e8
4,19e9
0,02
0,05
0,19
0,52
13,21
WK1
WK2
WK3
WK4
WK5
0,02
1,72
21,01
5,49
1,65
1,79e5
2,75e6
8,21e6
8,09e6
4,84e6
1,29e5
1,62e6
4,57e6
4,47e6
2,65e6
4,35e6
3,16e8
3,98e9
9,68e8
2,69e8
0,01
1,12
12,90
3,03
0,80
AC1
AC2
AC3
AC4
AC5
0,00
0,03
0,02
0,68
1,00
3,75e3
5,01e4
3,69e4
3,63e5
4,29e5
6,36e2
2,27e4
4,59e3
2,03e5
2,28e5
3,44e4
4,96e5
8,85e5
1,94e7
3,97e7
0,00
0,07
0,00
1,85
4,69
WBb1
WBb2
WBb3
WBb4
WBb5
0,14
1,46
6,86
0,29
6,02
4,95e5
3,69e6
8,78e6
1,14e6
6,45e6
2,64e5
1,80e6
4,25e6
5,95e5
3,44e6
3,79e7
4,20e8
1,27e9
4,91e7
1,13e9
0,11
1,09
3,75
0,13
3,38
WLb1
WLb2
WLb3
WLb4
WLb5
0,03
0,17
0,35
0,99
0,87
3,65e5
1,48e6
3,14e6
5,63e6
5,68e6
2,46e5
9,39e5
1,98e6
3,51e6
3,47e6
3,75e6
2,46e7
4,58e7
1,80e8
1,53e8
0,02
0,09
0,19
0,66
0,50
WKb1
WKb2
WKb3
WKb4
WKb5
0,06
1,94
1,78
0,66
47,56
3,67e5
2,91e6
2,34e6
2,21e6
2,28e7
2,23e5
1,58e6
1,19e6
1,45e6
1,23e7
1,29e7
3,57e8
3,31e8
1,09e8
8,55e9
0,04
1,13
1,12
0,28
28,63
ACb1
ACb2
ACb3
ACb4
ACb5
0,03
0,11
0,40
1,05
1,09
3,06e4
1,18e5
2,73e5
5,42e5
5,17e5
1,93e4
6,48e4
1,53e5
2,99e5
2,78e5
1,85e6
1,67e6
1,18e7
3,37e7
1,95e7
0,03
0,18
0,75
2,87
3,40
Tabell 4.4. Antal push- och relabel-operationer.
23
Kapitel 5
Diskussion och slutsats
5.1
Diskussion
5.1.1
Metodkritik
De bitvis inkonsekventa testresultaten för PR1 och PR2 har sin grund i de genererade grafinstanserna. Det är slumptalsgenereringen av kanternas kapaciteter som
leder till att vissa grafinstanser blir mycket lätta eller svåra, en teori som styrks
av den andra omgången tester av push-relabel-algoritmerna. Problemet med utfall
som beror på grafinstanser skulle kunna avhjälpas genom att testa ett stort antal
instanser av samma graftyp och storlek. Det skulle då bli möjligt att beräkna väntevärde och standardavvikelse för varje implementation och graftyp av varje storlek
snarare än för enskilda grafinstanser, vilket torde anses vara mer intressant. Att utföra rigorösa tester i Java med metodiken som beskrivs i kapitel tre visade sig dock
vara mycket tidskrävande. Därför hade vi inte möjlighet att testa en stor mängd
grafinstanser av varje typ och storlek. En föjd av detta är att vi inte har tillräckligt
med data för att kunna besvara frågeställningen till fullo.
De resultat som erhållits får dock anses vara korrekta, ty kontrollkörningar resulterade i körtider som föll inom konfidensintervallen för den första omgångens tester.
Att två olika omgångar testresultat är såpass lika varandra tyder på att testmetodiken i övrigt varit god och att yttre omständigheters verkan på testresultaten
framgångsrikt minimerats. Detta styrks ytterligare av att variationskoefficienten är
genomgående låg. För de testfall då variationskoefficienten är hög har det berott på
att de grafinstanserna varit mycket svåra eller lätta på grund av de pseudoslumptalsgenererade kapaciteterna.
5.1.2
Edmonds-Karp
EK2 är snabbare än EK1 för samtliga instanser av W-graferna. För AC-graferna är
EK2 ungefär lika snabb eller snabbare än EK1 när antalet kanter är lägre än ungefär
100 000, därefter blir EK1 avsevärt snabbare. En möjlig förklaring till detta kan
vara att antalet objekt är tillräckligt få när antalet kanter är mindre än 100 000
25
KAPITEL 5. DISKUSSION OCH SLUTSATS
och att skräpsamlarens inverkan på körtiden då blir försumbar. När antalet objekt
stiger körs sannolikt skräpsamlaren oftare för att frigöra mer minne samtidigt som
varje sökning med skräpsamlaren tar längre tid.
Ovanstående teori stämmer överens med utfallen för EK1 och EK2. För grafinstanser med få kanter är EK2 snabbare, men när antalet kanter går över en kritisk
gräns ser det ut som att EK2 blir asymptotiskt långsammare än EK1.
5.1.3
Push-relabel
Trots testernas inkonsekventa utfall för enskilda grafinstanser är det möjligt att jämföra PR1 med PR2, ty båda implementationerna presterar på liknande sätt för varje
grafinstans. Genom att räkna och studera antalet utförda push-, relabel- och förflyttningsoperationer för algoritmerna under exekvering går det att se att körtiden
bestäms av hur många av dessa operationer som utförs. Betraktas testerna på ACgraferna i 4.4 syns det tydligt att det är antalet relabel- och förflyttningsoperationer
som ger upphov till grafinstanserna AC1 och AC3:s mycket låga beräkningstid. För
AC1 och AC3 utförs två respektive en storleksordning färre relabel- och förflyttningsoperationer jämfört med AC2. Liknande minskning av antal operationer går
att observera för de flesta grafinstanser där körtiden sjunker.
PR1 och PR2 presterar på liknande sätt som implementationerna av EdmondsKarp. PR2 är snabbare för samtliga instanser av W-graferna. För AC-graferna är
PR1 generellt sett snabbare än PR2, med undantag för de AC1 och AC3, då antalet
relabel- och förflyttningsoperationer är extremt få.
5.1.4
Edmonds-Karp mot Push-relabel
På grund av metodens brister finns inte tillräcklig data för att diskutera huruvida
Edmonds-Karp eller Goldberg-Tarjans push-relabel-algoritm är empiriskt snabbare
i Java.
5.2
5.2.1
Slutsats
Edmonds-Karp
EK2 är snabbare än EK1 för glesa grafer och graferinstanser med få kanter men när
mängden kantobjekt ökar är EK1 att föredra. Vilken datastruktur som ska väljas
vid implementation beror alltså på grafinstansernas storlek och då framförallt sett
till antal kanter.
5.2.2
Push-relabel
Implementationerna av push-relabel uppvisar liknande beteende som EK1 och EK2.
För små grafinstanser, när antalet kanter är lågt, är PR2 snabbare. För de fullständigt täta acykliska graferna är PR1 snabbare med undantaget för de extremt lätta
grafinstanserna AC1 och AC3.
26
5.2. SLUTSATS
Valet av datastruktur kan därför följa samma resnonemang som för val av datastruktur för Edmonds-Karp, när grafinstanserna är små är PR2 att föredra.
5.2.3
Edmonds-Karp mot push-relabel
Det finns inte tillräckligt med data för att kunna dra några slutsatser kring om
huruvida Goldberg-Tarjans push-relabel-algoritm eller Edmonds-Karps algoritm är
empiriskt snabbare vid implementation i Java. En studie av en stor mängd grafinstanser av varje graftyp är nödvändigt för att kunna besvara den här frågeställningen
på ett tillfredsställande sätt.
27
Bilaga A
Edmonds-Karp
Nedan presenteras pseudokod för Edmonds-Karps algoritm implementerad med
grannlista av heltal som används för att indexera in i flödes- och kapacitetsmatriserna. Algoritmen tar fyra parametrar, E - grannlista, C - kapacitetsmatris, s källa, t - sänka.
29
BILAGA A. EDMONDS-KARP
Algorithm A.0.1: EdmondsKarp(E, C, s, t)
f ←0
F
P
M
Q
while true
do

fill(P, −1)




P [s] ← −2





fill(M, 0)




M
[s] ← inf






Q.clear()



Q.offer(s)



m←0





while Q.size() > 0




do








u ← Q.poll()







for each v ∈ E[u]









do







if (C[u, v] − F [u, v] > 0) and P [v] == −1













then
















P [v] ← u










M [v] ← min(M [u], C[u, v] − F [u, v])











if
v! = t


 











n then


















 Q.add(v)




















n else











 m ← M [t]








if m == 0




n then




break






f ← f + m



v←t




while v! = s






do




u ← P [v]





F [u, v] ← F [u, v] + m








F [v, u] ← F [v, u] − m




v←u
return (f )
30
Bilaga B
Push-relabel
Nedan presenteras pseudokod för en push-relabel implementation med grannlista av
heltal som används för att indexera in i flödes- och kapacitetsmatriserna. Algoritmen
tar fyra parametrar, E - grannlista, C - kapacitetsmatris, s - källa, t - sänka.
31
BILAGA B. PUSH-RELABEL
Algorithm B.0.2: pushRelabel(E, C, s, t)
n ← E.length()
F
height
excess
next
nodelist
j←0
for i ← 0 to n
do


if i! = s and i! = t
height[s] ← n
n then

 nodelist[j + +] ← i
excess[s] ← ∞
for v ∈ E[s]
n do
push(s, v) p ← 0
while p < nodelist.length()
do

u ← nodelist[p]





oldHeight ← height[u]




discharge(u)





if height[u] > oldHeight


( then



 moveToFront(p, nodeList)



p=0






n else


 p+ = 1
return (sum(F [s]))
32
Algorithm B.0.3: discharge(u)
while excess[u] > 0
do

if next[u] < E[u].length()






then





v ← next[u]






if C[u][v] − F [u][v] > 0 and height[u] > height[v]









 then


 n

 push(u, v)









n else





 seen[u] ← seen[u] + 1








( else



relabel(u)



 seen[u] ← 0
Algorithm B.0.4: push(u, v)
send ← min(excess[u], C[u][v] − F [u][v])
F [u][v] ← F [u][v] + send
F [v][u] ← F [v][u] − send
excess[u] ← excess[u] − send
excess[v] ← excess[v] + send
Algorithm B.0.5: relabel(u)
minh eight ← ∞
for each v ∈ E[u]
do

if C[u][v] − F [u][v] > 0



 then
(

minh eight ← min(minh eight, height[v])



height[u] ← minh eight + 1
33
Bilaga C
Hårdvara
35
BILAGA C. HÅRDVARA
36
37
Bilaga D
Kompilering
D.1
LLVM och Clang
Clang är en kompilator-front-end för bland annat C som använder LLVM som backend. Clang är open source, utvecklas av Apple tillsammans med bland andra Google,
ARM, Intel och Sony och utvecklas för vara kompatibel med GCC. [18] [19]
D.2
Generator
För att få washington.c att kompilera måste returvärden specificeras för två funktioner. Att returnera 0 ändrar inte funktionaliteten ty funktionenernas returvärde
ignoreras.
Funktionen AddEdge saknar returvärde på rad 722.
Funktionen PutInt saknar returvärde på rad 935.
D.3
Referenslösare
För att få dinic.c att kompilera med kommandot “make dinic” måste returvärden
specificeras för två funktioner i två olika filer. Att returnera 0 ändrar inte funktionaliteten ty funktionenernas returvärde ignoreras.
Funktionen PutInt i utility.c saknar returvärde på rad 130.
Funktionen AddEdge i manip.c saknar returvärde på rad 68.
39
Litteraturförteckning
[1]
Ford LR, DR Fulkerson. Maximal Flow through a Network. Canadian Journal
of Mathematics. 1956;8(0):399-404.
[2]
Cormen TH, Leiserson CE, Rivest RL, et al. Introduction to Algorithms. 2nd
ed. MIT Press och McGraw–Hill;2001.
[3]
Harris TE, Ross FS, Rand Corp Santa Monica Ca. Fundamentals of a Method
for Evaluating Rail Net Capacities. 1955.
[4]
Schrijver A. On the history of the transportation and maximum flow problems.
Mathematical Programming. 2002; 91(3):437-445.
[5]
Edmonds J, Karp RM. Theoretical Improvements in Algorithmic Efficiency for
Network Flow Problems. Journal of the ACM. 1972 april;19(2):248-264.
[6]
Dinic EA. Algorithm for Solution of a Problem of Maximum Flow in a Network
With Power Estimation. Soviet Math Doklady. 1970;11(5):1277-1280.
[7]
Goldberg AV, Tarjan RE. A new approach to the maximum-flow problem.
Journal of the Association for Computing Machinery. 1988 oktober;35(4);921940.
[8]
Hu TC, Shing MT. Combinatorial Algorithms. 2nd ed. Toronto: General
Publishing Company;2002.
[9]
Ahuja RK, Kodialam M, Mishra AK, Orlin JB. Computational investigation of maximum flow algorithms. European Journal of Operational Research.
1997;97(3);509-542.
[10] Boykov Y, Kolmogorov V. An experimental comparison of min-cut/max-flow
algorithms for energy minimization in vision. Ieee Transactions On Pattern
Analysis And Machine Intelligence. 2004; 26(9):1124-1137.
[11] DIMACS Implementation Challenges [hemsida på internet]. Center for Discrete
Mathematics Theoretical Computer Science; [uppdaterad 16 maj 2012; hämtad
16 mars 2015]. Tillgänglig på: http://dimacs.rutgers.edu/Challenges.
41
LITTERATURFÖRTECKNING
[12] Anderson R. Program: washington.c. Hämtad 10 april 2015. Tillgänglig på:
ftp://dimacs.rutgers.edu/pub/netflow/generators/network/washington.
[13] Setubal J. Program: ac.c. Hämtad 15 april 2015.
ftp://dimacs.rutgers.edu/pub/netflow/generators/network.
Tillgänglig
på:
[14] Anderson R, Setubal J. Program: dinic.c. Hämtad 10 april 2015. Tillgänglig
på: ftp://dimacs.rutgers.edu/pub/netflow/maxflow/solver-3.
[15] ibm.com
[hemsida
på
internet].
Robust
Java
benchmarking, Part 1: Issues [hämtad 17 mars 2015]. Tillgänglig på:
http://www.ibm.com/developerworks/library/j-benchmark1/.
[16] ibm.com [hemsida på internet]. Robust Java benchmarking, Part
2: Statistics and solutions [hämtad 17 mars 2015]. Tillgänglig på:
https://www.ibm.com/developerworks/java/library/j-benchmark2/.
[17] ellipticgroup.com
[hemsida
på
internet].
Java
benchmarking
article
[hämtad
15
april
2015].
Tillgänglig
på:
http://www.ellipticgroup.com/html/benchmarkingArticle.html.
[18] LLVM.org [hemsida på internet]. clang: a C language family frontend for LLVM
[hämtad 15 april 2015]. Tillgänglig på: http://clang.llvm.org/index.html.
[19] LLVM.org [hemsida på internet]. The LLVM Compiler Infrastructure [hämtad
15 april 2015]. Tillgänglig på: http://www.llvm.org/.
42
www.kth.se