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