Flugtveje [1] A312 Jens Stokholm Høngaard Kristian Pilegaard Jensen Thomas Birch Mogensen Niels Asger Aunsborg Nicolai Vesterholt Søndergaard Daniel Agerskov Heidemann Jensen 24. maj 2010 I II Det Teknisk-Naturvidenskabelige Basis˚ ar Naturvidenskab Strandvejen 12-14 Telefon 96 35 97 31 Fax 98 13 63 93 http://tnb.aau.dk Synopsis: Rapporten omhandler hvordan man kan finde den optimale flugtvej ud af en bygning. For at finde den flugtvej har vi givet et overblik over grafteori, og kigget p˚ a nogle algoritmer om korteste vej problemet. De er blevet sammenlignet for at finde den algoritme vi har brug for. Vi har ogs˚ a interviewet en arkitekt om flugtveje er noget de tager højde for n˚ ar de designer bygninger. Til sidst har vi lavet et program der kan finde den optimale vej ud af en bygning. Titel: Flugtveje Tema: Algoritmer og netværk Projektperiode: P2, for˚ arssemesteret 2010 Projektgruppe: A312 Deltagere: Jens Stokholm Høngaard Vejledere: Kristian Pilegaard Jensen Hans H¨ uttel og Marion Berg Christiansen Thomas Birch Mogensen Oplagstal: 1 Niels Asger Aunsborg Sidetal: 50 Bilagsantal og –art: 1 tekst Nicolai Vesterholt Søndergaard Afsluttet den 25. Maj 2010 Daniel Agerskov Hejdemann Jensen Rapportens indhold er frit tilgængeligt, men offentliggørelse (med kildeangivelse) m˚ a kun ske efter aftale med forfatterne. III IV Indhold 1 Problemanalyse 1 1.1 Initierende problem . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Menneskelig adfærd ved brand . . . . . . . . . . . . . . . . . . . 1 1.3 Arkitektværktøjer . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.3.1 Samlet vurdering . . . . . . . . . . . . . . . . . . . . . . . 3 Interview med arkitekt . . . . . . . . . . . . . . . . . . . . . . . . 4 1.4.1 Selve interviewet . . . . . . . . . . . . . . . . . . . . . . . 4 Afgrænsning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4 1.5 2 Grafteori 2.1 2.2 6 Anvendelse af grafteori . . . . . . . . . . . . . . . . . . . . . . . . 6 2.1.1 Knuder . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.1.2 Kanter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Eksempel p˚ a repræsentation . . . . . . . . . . . . . . . . . . . . . 7 3 Flugtvejsproblemet 9 3.1 Definitioner af parametre . . . . . . . . . . . . . . . . . . . . . . 3.2 Gevinsten af en flugtplan . . . . . . . . . . . . . . . . . . . . . . 10 3.2.1 9 Det konkrete flugtvejsproblem . . . . . . . . . . . . . . . . 11 4 Korteste-vej algoritmer 12 4.1 Tidskompleksitet . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.2 Store O-notation . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.3 Justering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4.4 Dijkstras algoritme . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4.4.1 4.5 Tidskompleksitet . . . . . . . . . . . . . . . . . . . . . . . 15 Bellman-Ford . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.5.1 Tidskompleksitet . . . . . . . . . . . . . . . . . . . . . . . 16 4.6 APSP algoritmer generelt . . . . . . . . . . . . . . . . . . . . . . 16 4.7 Floyds algoritme . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 V 4.8 4.7.1 Eksempel p˚ a Floyds algoritme . . . . . . . . . . . . . . . 17 4.7.2 Tidskompleksitet . . . . . . . . . . . . . . . . . . . . . . . 19 Valg af algoritme . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 5 Største strømnings-problemet 20 5.1 Strømningsnetværk . . . . . . . . . . . . . . . . . . . . . . . . . . 20 5.2 Ford-Fulkersons metode . . . . . . . . . . . . . . . . . . . . . . . 21 5.2.1 Pseudokode . . . . . . . . . . . . . . . . . . . . . . . . . . 21 5.2.2 Kompleksiteten af Ford-Fulkersons algoritme . . . . . . . 22 6 Overvejelser ved egen kode 23 7 Implementationens struktur 24 7.1 OptimalPathFramework . . . . . . . . . . . . . . . . . . . . . . . 24 7.2 Edge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 7.3 Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 7.4 Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 7.5 Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7.6 PathFinder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7.6.1 Implementering af Dijkstras algoritme . . . . . . . . . . . 26 7.6.2 Implementering af Ford-Fulkersons algoritme . . . . . . . 28 8 Forsøg p˚ a algoritmer til at finde optimale flugtveje 8.1 Tanker om algortimen . . . . . . . . . . . . . . . . . . . . . . . . 30 8.1.1 8.2 30 Tidskompleksiteten af algoritmen . . . . . . . . . . . . . . 31 Vores algoritme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 8.2.1 Koden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 8.2.2 Kritik af algoritme . . . . . . . . . . . . . . . . . . . . . . 37 9 Modeldannelse 38 9.1 Opdeling af bygningen i knuder . . . . . . . . . . . . . . . . . . . 38 9.2 Tilføjelse af kanter . . . . . . . . . . . . . . . . . . . . . . . . . . 38 9.3 Længde og kapacitet . . . . . . . . . . . . . . . . . . . . . . . . . 39 9.4 Kilder og dræn . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 9.5 Eksekvering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 9.6 kopieret fra metode . . . . . . . . . . . . . . . . . . . . . . . . . . 39 10 Brugervenlighed 41 Litteratur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 A Spørgsm˚ al fra interview: 43 VI B Interviewet 44 C Vigtige ord og begreber 49 C.1 Grafteori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 C.2 tidskompleksitet . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 C.3 O-notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 VII Kapitel 1 Problemanalyse 1.1 Initierende problem Det sker med jævne mellemrum, at folk dør i brand. Ifølge sikkerhedsstyrelsen omkom 90 mennesker ved brande i 2008[?]. Dette er et problem og at mindske antallet af omkomne ville være en lettelse for samfundet. For at gøre dette m˚ a man overveje, hvor de mest effektive omr˚ ader ville være at sætte ind. En vigtigt problem er at mennesker tit vælger den forkerte udgang, n˚ ar brandalarmen lyder[2]. Et af problemerne er alts˚ a at den menneskelige psykologi ikke tillader mennesker at handle rationelt i forhold til den m˚ ade flugtplaner er opbygget p˚ a. En effektiv m˚ ade at mindske antallet af dødsbrande p˚ a, ville være at afhjælpe dette problem. Man skal derfor se p˚ a, hvorfor mennesker vælger de forkerte udgange og hvordan man kan hjælpe dem til at vælge den rigtige. 1.2 Menneskelig adfærd ved brand Det første man ville tro er, at folk ville g˚ a i panik og dermed ikke tænke rationelt. Men i følge Norman Groner PhD, er det dog ikke det, som sker, n˚ ar en brand opst˚ ar. Han siger, at det er en myte, for ved terrorangrebet p˚ a World Trade Center brugte de fleste lang tid p˚ a at finde ud af, hvad der skete og p˚ a at søge infomation om situationen. Ved faretruende situationer er mennesket skeptiske[3]. Enten kan historien om en brand eller lignende være for absurd eller s˚ a tager man det ikke seriøst. Nogen ville m˚ aske tro, det bare var en brandøvelse og fortsætte deres arbejde. S˚ a det vil alts˚ a sige, at mennesker forholder sig roligt under brand. Hvis folk generelt tager det roligt, n˚ ar de skal ud, hvorfor er det s˚ a væsenligt at designe bygningerne anderledes end, man har gjort tidligere? Det har ved et forsøg vist sig, at folk som regel tager den samme vej ud, som de kommer ind af selv under disse specielle omstændigheder. Det er et problem, fordi det øger presset p˚ a nogle flugtveje, og efterlader andre ubenyttede. Ved et forsøg[?] foretaget i en IKEA, imiterede man en brandøvelse. Testpersonerne skulle, n˚ ar alarmen gik igang, finde ud af bygningen. Her viste det sig at over halvdelen af forsøgspersonerne valgte at tage den vej, som de kom ind ad ogs˚ a selvom, 1 denne udgang var dobbelt s˚ a langt væk som den nærmeste branddør. Det lader dermed til at folk tager den kendte vej ud. Det vil ud fra denne antagelse ikke gøre en bygning mere sikker, hvis der er mange flugtveje, fordi folk alligevel tager den flugtvej, de kender. For at undg˚ a det flaskehalsproblem der opst˚ ar, vil en bedre løsning være at fokusere p˚ a f˚ a flugtudgange, men med en stor kapacitet. Den sidste ting man skal tage højde for er, hvordan folk bevæger sig i grupper som ”flokdyr”, for hvis en flugtvej siger, at 5 personer skal løbe den ene vej for at komme ud og en anden person skal løbe en anden vej for at komme ud, vil de s˚ a gøre det eller vil de alle sammen løbe den samme vej? I et forsøg[4] har man taget en gruppe personer og sagt til dem, at de ikke m˚ a snakke sammen og at de skulle g˚ a med en arms længde til hinanden, ellers skulle de bare g˚ a rundt i en hal. I den gruppe havde man givet nogle af personerne instruktioner p˚ a, at de skulle g˚ a en bestemt vej. Da forsøget startede blev der uden at de snakkede sammen, lavet en kæde af mennesker som fulgte de personer, der havde f˚ aet at vide, hvor de skulle g˚ a. Forsøget blev gentaget flere gange med flere og flere personer og færre og færre personer, der fik at vide, hvor de skulle g˚ a. Det viste sig at en flok p˚ a 200 personer eller flere, hvor 5 % af de personer fik at vide, hvor de skulle g˚ a hen, var de 5 % nok til at kunne bestemme, hvor flokken skulle g˚ a hen. Det vil være upraktisk at skulle forsøge at ændre menneskers adfærd, f.eks. ved kurser, vil en bedre løsning være at optimere bygninger, s˚ a der i højere grad tages højde for optimale flugtveje. Det er derfor oplagt at sætte ind der hvor bygninger bliver tegnet. Arkitekter vil derfor være den primære m˚ algruppe for projektet. Det vil derfor være en god id´e at se p˚ a hvad arkitekter gør for at sikre flugtplaner, og hvordan man vil kunne hjælpe dem til at sørge for at flugtplanerne benytter de optimale veje. 1.3 Arkitektværktøjer For at f˚ a en bedre ide om hvordan arkitekter designer bygninger, vil vi her se p˚ a nogle forskellige arkitektprogrammer lavet til plantegning og design af bygninger. Det vi vil se p˚ a er, hvilke features programmerne har og om de tager højde for flugtveje. Alle de programmer vi har undersøgt er CAD programmer. CAD st˚ ar for Computer-Aided Design og er betegnelsen for en bred række af design værktøjer, som arkitekter bruger. CAD programmerne har en fælles standard, der gør at arkitekter, der bruger forskellige programmer kan se hinandens tegninger. For at f˚ a et udvalg af forskellige CAD programmer har vi valgt at se p˚ a programmer, som koster vidt forskelligt, g˚ aende fra omkring 4000 $ til et gratis program. De tre programmer vi har undersøgt er ArchiCAD 13, SmartDraw 2010 og Google Sketchup. 2 ArchiCAD 13 er det dyreste program, vi har undersøgt. Programmet har rigtig mange funktioner, hvilket vi følte virkede meget uoverskueligt. N˚ ar man designer bygninger i programmet ses det i 3D, dog er det ikke muligt at se m˚ al p˚ a bygningen, man har tegnet. Selvom programmet indeholdte mange funktioner kunne vi ikke finde en m˚ ade at tegne flugtplaner eller p˚ a nogen m˚ ade finde optimale flugtveje. I programmet fandtes der ikke en funktion til at lave flugtplaner eller beregne optimale flugtveje. I modsætning til ArchiCAD 13 s˚ a er SmartDraw 2010 et simplere program og nemmere at sætte sig ind i. Det skal dog siges, at det s˚ a heller ikke har nær s˚ a mange funktioner som ArchiCAD 13. Derudover kan man heller ikke se sin bygning i 3D, det man ser er en plantegning, hvilken kan give problemer i følge Erik Falck Jørgensen Man opdager ting tidligere ved at lave det i 3D. Eksempelvis opdagede vi, at udgangsdøren for en af vores flugtveje sad lige bag ved rampen, s˚ a man ikke ville kunne komme ud den vej. S˚ a m˚ atte vi flytte den. Det ville have været svært at opdage i en 2D-tegning. [5]. I SmartDraw 2010 er der en masse eksempler p˚ a bygninger til r˚ adighed. Et par af disse eksempler er flugtplaner, hvor der sørges for at f˚ a alle ud fra bygningen og endda ud af flugtveje, som ser ud til at være de optimale. Der er alts˚ a i Smartdraw 2010 tænkt p˚ a flugtveje, dog kan man ikke lave optimale flugtveje i sin egen bygning. SmartDraw 2010 er billigere end ArchiCAD 13.[6] Google SketchUp er et gratis program, hvor der dog kan købes en PRO udgave. Vi har valgt at tage Google SketchUp med for at vise et gratis tilbud til arkitekter. Dette program er ligesom SmartDraw 2010 meget simpelt og lige til at g˚ a til. I Google SketchUp kan man b˚ ade lave plantegninger og tegne i 3D. I forhold til flugtveje, har vi ikke fundet nogen funktioner, der giver brugeren mulighed for at lave flugtveje.[7] 1.3.1 Samlet vurdering Disse tre programmer udgør et udvalg af, hvad der er p˚ a marked af CAD programmer. Selvom vi har et begrænset kendskab til CAD programmerne konkluderer vi, at der ikke bliver taget højde for flugtveje i disse programmer. Dette undrer vi os over da planlægningen af flugtveje m˚ a være en væsentlig del af bygningers design. Hvordan kan det være, at det ikke er muligt at planlægge flugtveje i de programmer vi har testet? Er det fordi det udvalg vi har valgt ikke normalt bliver brugt af arkitekter eller kan det være at arkitekter ikke mener der er brug for det? Udfra disse overvejelser har vi valgt at interviewe en arkitekt. 3 1.4 Interview med arkitekt M˚ alet med dette interview er at finde ud af om, arkitekter har behov for et program, der kan hjælpe med at finde optimale flugtveje ud af en bygning. I den sammenhæng vil det ogs˚ a være relevant at finde ud af, hvad de gør for at designe bygninger p˚ a en m˚ ade, s˚ a folk kan komme sikkert ud og om menneskelig adfærd bliver medregnet. Det vil ogs˚ a være relevant for os at høre hvilke love, der er vigtige, n˚ ar man skal designe bygninger, da der kunne ske at være nogle ting, vi m˚ atte tage højde for. Til sidst vil vi gerne finde ud af, hvilke krav en arkitekt har til et flugtvejsprogram. 1.4.1 Selve interviewet Arkitekten der blev interviewet var Jan Refsgaard Jepsen chef for produktionen ved Friis & Moltke. I interviewet fandt vi ud af, at arkitekter arbejder tæt sammen med brandingeniører og brandmyndighederne. Tidligere fungerede brandsikringen ved at arkitekterne tegnede en bygning og derefter henvendte sig til brandmyndighederne for godkendelse. Den arkitekt vi snakkede med har aldrig oplevet, at brandmyndigehederne har afvist en bygning. Dog mente han, at der ikke var behov for en strammere lovgivning, da lovgivningen hele tiden bliver ændret i forhold til de ulykker der sker. Dette kan hænge sammen med deres tætte samarbejde med brandmyndighederne. Man benytter stadig den gamle godkendelsesmetode ved mindre bygninger i dag, men ved større bygninger arbejder arkitekter sammen med brandingeniører ved desitagn af bygningen. Ved udarbejdelsen af en bygnings flugtveje, er der udlagt nogle specifikke krav til bygningen, eksempler p˚ a disse krav kan være afstanden mellem trapper og bredden p˚ a gangene. Kravene skifter alt efter hvilken slags bygning der er tale om. Jepsen lavede dog ikke nogen overordenet analyse af flugtveje, som f.eks. at køre tests p˚ a hvor mange personer der ville kunne komme ud af bygningen p˚ a en given tid. De har en brandteknisk analyse, de g˚ ar ud fra. Den brandtekniske analyse simulerer en brand, hvor den kigger p˚ a brandens og røgensudvikling, men den tager ikke højde for beregningen af den optimale vej. Som sagt beregner arkitekter ikke flugtveje, men de benytter programmer, der kan tegne bygninger med m˚ al, s˚ a beregning af flugtveje skulle være lige til og oplagt at implementere. Jepsen benyttede programmerne fra Autodesk og havde ikke prøvet at beregne flugtveje i programmerne, men han mente, at de godt kunne. Han kunne godt se, at det kunne være relevant at udregne flugtveje, da det kunne mindske den nødvendige kontakt med brandmyndighederne. I forhold til deres brandtekniske analyse, der kan tage flere dage om at beregne, hvordan branden udvikler sig og hvordan røgen bevæger sig, kunne et program forholdvis hurtig beregne optimale flugtveje, evt. køre samtidigt med en brandteknisk analyse. Alt i alt m˚ a man sige, at en program til udregning af optimale flugtveje kunne være ideelt til at hjælpe arkitekter med design af bygninger. Jan Refsgaard Jepsen mente at kravene for flugtveje var, at de havde en bredde p˚ a 1,5 meter og dette mente han ikke kunne være et problem i forhold til flaskehalse i en bygning. Dog kan dette nemt være et stort problem, som er vigtigt 4 at forholde sig til ved design af bygninger. Man kunne forestille sig at 500 mennesker skulle bevæge sig igennem en gang, der er 1,5 meter bred, dette vil uden tvivl skabe et flaskehals problem. Ved et spørgsm˚ al om lovgivningen p˚ a dette omr˚ ade var for stramt, svarede han, at det mente han ikke, men desuden nævnte han ændringer i lovgivningen ofte sker efter ulykker. Derfor kunne man tænke sig at der kom love ikke blot vedrørende m˚ al, men ogs˚ a vedrørende strømning. 1.5 Afgrænsning Nu da vi har analyseret os frem til et egenligt problem, kan vi se videre p˚ a, hvordan det evt. kan løses. En m˚ ade var, at man i selve designet af bygninger tog højde for optimale flugtveje. Da det er tilfældet, at arkitekter benytter sig af software til design af bygninger[5], kan det m˚ aske være muligt at implementere dette i softwaren. Vi vil derfor udvikle en optimal flugtvejs algoritme og undersøge om, der er en id´e i at implementere den i arkitekt software eller lave den til et selvstændigt stykke software. Dette leder os frem til følgende problemformulering. Problemformulering • Hvordan finder man optimale flugtveje? – Hvordan kan man finde optimale flugtveje vha. grafteori? – Hvordan kan vores optimale flugtvejs algoritme være til gavn for arkitekter? 5 Kapitel 2 Grafteori Inden vi kan gribe problemet om flugtveje an, m˚ a vi først se p˚ a grafteori. Da det bliver brugt til at finde og lave grafer i vores m˚ ade at finde flugtvejs problemet. Det første vi har valgt at definere er orienterede grafer. Definition 1. En orienteret graf G er et par G = (V, E), hvor V er en mængde af knuder, E er en mængde af kanter. En kant e ∈ E er et ordnet par e = v1 , v2 , hvor v1 ∈ V, v2 ∈ V . Vi siger, at e starter i v1 og slutter i v2 . En orienteret graf best˚ ar alts˚ a af en mængde kanter og knuder. N˚ ar man tegner en graf, tegner man som regel knuder som prikker og kanter som streger, der forbinder to knuder. Man angiver en kants orientering med en pil. Definition 2. En ikke-orienteret graf G er et par G = (V, E) hvor V er en mængde af knuder og E er en mængde af kanter. En kant er et uordnet par e = {v1 , v2 }, hvor v1 ∈ V, v2 ∈ V . Definition 3. Lad G = (V, E) være en orienteret graf. En vej er en følge af knuder v1 , ..., vk , hvor for alle vi , vi+1 ∈ E for alle i, hvor 1 ≤ i ≤ k − 1. 2.1 Anvendelse af grafteori Vi vil i dette afsnit forklare hvordan vi afbilder knuder og kanter i en model over en bygning. 2.1.1 Knuder Vi definerer knuder som steder, hvor man kan opholde sig. Den enkelte knude vil derfor repræsentere et rum eller en del af et rum. Den mængde plads en knude repræsenterer er varierende, men svarer cirka til et gennemsnitligt grupperum p˚ a 30 kvadratmeter. Alle grupperum kan alts˚ a vises som en enkelt knude og større arealer. Som gange bliver repræsenteret som en række knuder. Vi vælger at dele store rum og gange op i flere knuder. Havde vi valgt at hele gangene kun var en knude, skulle alle de flygtende mennesker hen til denne ene knude, det ville der for være svært at sige noget præcist om afstanden fra et bestemt gruppe rum til udgangen, da gangen ville repræsentere et stort omr˚ ade. Vi deler de store 6 lokaler op, for at gøre modellen mere præcis. Man kunne nemlig forestille sig, at alle ville vælge den samme flugtvej, hvis de befandt sig i et lokale, hvor der kun g˚ ar en kant ud fra. Da disse lokaler har flere døre, virker det ogs˚ a naturligt at udnytte dette, da flere knuder ville give de flygtende mulighed for at kunne tage forskellige veje. 2.1.2 Kanter I flugtplanen repræsenterer kanter mulige veje mellem knuderne. Hvis vi havde valgt kun at bruge enkelte knuder ved gange og større rum, ville vi f˚ a kanter som gik igennem væggene. Da vi har valgt at dele rummene op, f˚ ar vi ikke kanter der g˚ ar igennem væggene og derfor en model, der grafisk giver mere mening. 2.2 Eksempel p˚ a repræsentation Vi har taget udgangspunkt i Bygningen p˚ a Strandvejen 12-14, og har derfor dette eksempel p˚ a hvordan repræsenterer en bygning grafteoretisk. Længden p˚ a kanterne er ikke realistiske, men det skulle give en grafisk forst˚ aelse af hvordan grafteori afspejler virkeligheden. Figur 2.1: Strandvejen 12-14, 2. etage • I grafen repræsenterer Gx en del af en gang. • Ux er udgange. 7 • Tx er toiletter. • Depx er depoter. • Numrene som 312 er grupperum og kontorer. • Vx efter et rum angiver, at rummet er delt op i forskellige dele. • De firkantede knuder repræsenterer gange, men der er ikke nogen praktisk forskel p˚ a dem og de cirklede. 8 Kapitel 3 Flugtvejsproblemet I hele dette kapitel antager vi, at følgende er givet: • Givet en ikke-orienteret graf G = (V, E) • Kilder S ⊆ V afløb D ⊆ V • Passagefunktion t : E → R+ • Strømningsfunktion f : E → R+ • Befolkningsfunktion b : S → N En flugtplan P er en mængde af veje i G, der alle er p˚ a formen. (s, ..., d) hvor s ∈ S og d ∈ D. 3.1 Definitioner af parametre I dette afsnit vil vi definere de parametre vi benytter Definition 4. Vi antager dette givet. • G = (V, E), ikke-orienteret graf • Passagetidsfunktionen t : E → R+ • En vej θ i G. Vi vil nu definere passagetiden T (θ) • T (θ) er et tal. • T (θ) er defineret s˚ aledes det opfylder T (θ) = T (θ) angiver den tid en vej θ tager. 9 P e∈θ t(e) Definition 5. Vi antager dette givet. • G = (V, E), ikke-orienteret graf • Strømningsfunktion f : E → R+ • En vej θ i G. Vi vil nu definere strømningen F (θ) • F (θ) er et tal. • F (θ) er defineret s˚ aledes det opfylder F (θ) = min f (e) e∈θ I forhold til flugtvejsproblemet skal kilder forst˚ as som de knuder, hvor de flygtende starter deres flugt og nødudgangene er her afløbene. Vi finder den mindste kapacitet for en flugtrute, da en flugtrute er begrænset af sit smalleste sted. Den mindste kapacitet fortæller derfor, hvor mange personer en given flugtrute kan rumme. Definition 6. Vi antager dette givet. • G = (V, E), ikke-orienteret graf • Befolkningsfunktion b : S → N Vi vil nu definere befolkningen B(S) • B(S) er defineret s˚ aledes at B(S) = X b(s). s∈S Nu har vi de parametre, der gør, at vi kan finde gevinsten for en flugtplan. 3.2 Gevinsten af en flugtplan Definition 7. Vi antager dette givet. • G = (V, E), ikke-orienteret graf • En vej θ i G. • Strømningen F (θ) • Passagetiden T (θ) Vi vil nu definere gevinsten C(θ) 10 • C(θ) er et tal. • C(θ) er defineret s˚ aledes det opfylder C(θ) = F (θ) · T (θ) Gevinsten angiver, hvor mange mennesker der kan komme igennem en given vej. Den totale gevinst f˚ as ved at summere gevinsten af alle vejene i en flugtplan P: C(P ) = X C(θ) θ∈P Den totale gevinst skulle s˚ a angive, hvor mange mennesker en flugtplan kan rumme. Men dette er der et problem med, det kræver nemlig at alle kanterne i alle vejene i flugtplanen er kant disjunkt. De m˚ a alts˚ a ikke have nogle kanter til fælles. Hvis flugtplanerne har fælles kanter kan de ikke blot summeres. S˚ a hvis man ønsker at finde hvor mange mennesker der totalt kan komme igennem en given graf kan man kigge p˚ a største strømnings-problemet, som vi kommer ind p˚ a i et senere kapitel??. 3.2.1 Det konkrete flugtvejsproblem Det første vi vil gøre er at finde ud af, om en given flugtplan P kan f˚ a sin befolkning ud p˚ a en tid under m. Definition 8. Vi antager dette givet. • Givet en graf G = (V, E) • Passagetid T (θ) • Befolkning B(S) • En tidsgrænse m • Gevinsten C(P ) Vi vil nu definere kravet for en flugtplan P . P er tilstrækkelig hvis • T (θ) ≤ m. X • C(θ) ≥ B(S) θ∈P Da gevinsten af en optimal flugtvej er kompliceret at regne p˚ a vil vi prøve at forsimple problemet. Hvis man ser bort fra kapaciteten i første omgang, vil den korteste vej altid være den optimale. Derfor har vi valgt at starte med at kigge p˚ a flugtvejsproblemet som et korteste vej-problem. Alts˚ a har vi valgt at sætte kapaciteten af alle kanter i grafen til ∞. Vi vil nu kigge lidt p˚ a nogle algoritmer, som omhandler korteste vej-problemet. 11 Kapitel 4 Korteste-vej algoritmer I vores projekt har vi tænkt os at finde den optimale flugtvej. Som beskrevet i afsnittet før best˚ ar vores flugtvejsproblem af et maksimal strømningsproblem og et korteste-vej problem. I dette afsnit vil vi gennemg˚ a forskellige kortestevej algoritmer og derefter finde frem til hvilken algoritme, vi vil bruge. For at kunne vurdere hvilken algoritme vi vil bruge, vil vi ogs˚ a komme ind p˚ a tidskompleksiteten af algoritmerne. 4.1 Tidskompleksitet Tidskompleksiteten T (n) m˚ aler antallet af væsentlige operationer som en funktion af n, hvor n er størrelsen af input. For at beskrive tidskompleksiteten anvendes ordene worst-case,average-case eller best-case kompleksitet. • Worst-case kompleksitet beskriver det størst mulige antal væsentlige operationer ved et vilk˚ arligt input n. • Average-case kompleksitet beskriver det gennemsnitlige mulige antal væsentlige operationer ved et vilk˚ arligt input n. • Best-case kompleksitet beskriver det mindst mulige antal væsentlige operationer ved et vilk˚ arligt input n. Ved beskrivelsen af algoritmerne er vi dog kun interesseret i en worst-case analyse. Dette er der flere grunde til, best-case scenariet er ofte ikke interessant, dette kunne være at opgaven algoritmen skulle løse var løst p˚ a forh˚ and. Grunden til at vi ikke laver en average-case analyse er at gennemsnitlig input kan være svært at definere. 4.2 Store O-notation Store O-notation anvendes til at give en øvre grænse for vækstraten af en given funktion. Definition 9. Lad f : N → N og g : N → N være funktioner. Vi skriver at f = O(g) hvis der findes et tal C > 0 og et tal n0 ∈ N s˚ aledes at 12 f (n) ≤ c · g(n) for alle n ≥ n0 Store O resultater m˚ a overholde disse regler: 1. Hvis f = O(g) og k > 0, da har vi f = O(kg) 2. Hvis i ≤ j, da har vi ni = O(nj ) 3. Hvis f = O(g), da har vi f + g = O(g) Vi vil nu bevise at de tre p˚ astande er sande. I den første p˚ astand skal vi vise, at hvis f = O(g) og k > 0, s˚ a har vi at f = O(kg). Det vil sige, at vi skal vise, at der findes en konstant C1 og et tal n1 s˚ aledes at f (n) ≤ C1 · g(n) for alle n ≥ n1 . Hvis man sætter C1 = k og n1 = n0 . I den anden p˚ astand skal vi vise, at der findes en konstant C og et n0 s˚ a ni ≤ Cnj , n˚ ar n ≥ n0 . Hvis man vælger C = 1 og n0 = 1, f˚ ar man ni ≤ nj , hvor n ≥ 1. Da i ≤ j vil dette passe i henhold til overst˚ aende definition. I den tredje p˚ astand skal vi finde et C1 og et n1 s˚ aledes at f (n) + g(n) ≤ c1 · g(n) n˚ ar n ≥ n0 . Da f = O(g) har vi, at der findes en C0 og et n0 . S˚ a vi har f (n) + g(n) ≤ C0 · g(n) + g(n) = (C0 + 1)g(n) n˚ ar n ≥ n0 . S˚ a vi har f (n) + g(n) ≤ C0 · g(n) + g(n) = (C0 + 1)g(n) n˚ ar n ≥ n0 . S˚ a vælg C1 = C0 + 1 og n1 = n0 . Den sidste p˚ astand er især vigtig for vurderingen af korteste vej algoritmerne da den tillader at vi kan smide led af mindre orden væk. Vi vil bruge store O-notation til at bedømme hvilken af de følgende tre algoritmer vi vil bruge, ved at forsimple worst-case kompleksiteten s˚ aledes at vi nemt kan bedømme hvilke algoritme der er optimal. Dog skal det nævnes at dette kan være upræcist. Da det er tilladt at smide led af mindre orden væk kan to algoritmer der begge er O(n3 ) have forskellig tidskompleksitet, hvis der er tale om specifik tidskompleksitet. 4.3 Justering Fælles for alle korteste vej algoritmer er, at der er en del, som g˚ ar igen i alle algoritmerne. J u s t e r ( u , v , w) Hvis L(u, v) > L(u, w) + L(w, v) S˚ a L(u, v) := L(u, w) + L(w, v) Denne del af algoritmen tjekker om en vej fra u til v er større end en vej fra u til w plus vejen fra w til v. Hvis dette er tilfældet, skal den lave vægten p˚ a vejen/kanten fra u til v om 13 til længden fra u til v gennem w. Vi har valgt at kigge p˚ a tre algoritmer, som er Dijkstras, Bellman-Fords og Floyds algoritme, som alle bruger den her del i algoritmen. 4.4 Dijkstras algoritme Dijkstras algoritme blev udviklet af Edsger Wybe Dijkstra i 1959 og er en algoritme, der kan finde den korteste vej fra ´et punkt til samtlige andre punkter. Algoritmen kan anvendes p˚ a uorienterede grafer med positive vægte, men kan nemt laves om til brug ved orienterede grafer[8]. Har vi en orienteret vægtet graf med positive vægte, anvendes Dijkstras algoritme s˚ aledes. Man starter med at vælge en startknude v1 ∈ V . Vi betegner længden fra v1 til en vilk˚ arlig knude vk som L(v1 , vk ), desuden betegner vi vægten kanten mellem to knuder vi og vj som w(vi , vj ). En mængde af knuder S, beskriver hvilke knuder vi har gennemløbet. Algoritmen starter med at sætte længden mellem v1 og alle v ∈ V til uendelig, dog sættes længden v1 til nul, da længden til startpunktet er nul. S sættes til at være tom. Givet en vægtet i k k e −o r i e n t e r e t g r a f G(V, E) med p o s i t i v e vægte , hvor v1 ∈ V er startpunktet f o r i := 1 t o n L(vi ):= ∞ L(v1 ) := 0 S:=∅ Herefter kører en while-løkke, der først stopper, n˚ ar alle v ∈ V er v ∈ S. Ville man have en version af Dijkstras algoritme, som kunne finde korteste vej mellem to knuder, kunne man i stedet for stoppe loopet, n˚ ar en given knude var indeholdt i mængden S. Loopet startes ved at en given knude vk med L(vk ) mindst tilføjes til S. Her vil v1 altid blive tilføjet i første iteration, da L(v1 ) = 0. Derefter sker der en sammenligning af vægtene af alle kanterne g˚ aende fra u til naboknuderne. Findes der at L(u)+w(u, v) < L(v), s˚ a opdateres L(v) := L(u) + w(u, v). while a l l e v ∈ / S begin u := v − v e r en knude som i k k e l i g g e r i S med L( u ) mindst mulig . u tilføjes i S f o r a l l e knuder v ∈ / S J u s t e r L(u, v, v1 ) end ( A l l e mærkerne L(v)f orv ∈ V ) e r o p d a t e r e t s˚ a de e r k o r t e s t m u l i g e ) 14 4.4.1 Tidskompleksitet Givet input n knuder: While-løkke: Alle n knuder gennemløbes til de alle er indholdt i S Alle knudens højest n − 1 naboer gennemsøges T (n − 1) 2 Vi har at worst case er T (n) = n · (n − 1) = n − n Hvilket giver os at T (n) = O(n2 ) 4.5 Bellman-Ford Bellman-Ford algoritmen kan finde den korteste vej fra en knude til alle andre knuder i en graf[9]. Kravet for grafen er, at der ikke findes nogle negative kredse. En negativ kreds er en kreds, hvor summen af alle vægtene p˚ a kanterne i kredsen er negativ. Dette krav medfører ogs˚ a, at grafen skal være orienteret. Ellers har vi en negativ kreds for hver kant med negativ vægt. S˚ a Bellman-Ford skal tjekke for alle knuder til alle knuder, for at se om alle veje er positive fra alle kanter til alle kanter. Algoritmen starter som Dijkstras algoritme med at sætte længden fra startknuden til alle andre knuder til uendelig. Længden til startknuden sættes til 0. Givet en vægtet o r i e n t e r e t g r a f G(V, E) , hvor v1 ∈ V er startpunktet f o r i := 1 t o n L(vi ):= ∞ L( v 1 ) :=0 Det næste trin i algoritmen er, at alle længderne fra startpunktet til alle andre knuder opdateres s˚ aledes, at de er kortest mulig. En af forskellene mellem Bellman-Ford og Dijkstras algoritme er, at denne algoritme ikke gr˚ adigt vælger en knude, der i øjeblikket er kortest hen til, men opdaterer alle længderne. Dette er grunden til, at den kan h˚ andtere negative vægte. f o r i = 1 t o |V | − 1 f o r a l l e k a n t e r (u, v) ∈ E J u s t e r L(u, v) Det sidste trin tjekker om grafen indeholder nogen negative kredse. Ved dette trin bør alle de korteste veje fra startknuden til alle andre knuder være fundet. Hvis der ved, dette trin kan findes en kortere vej, betyder det, at der findes en negativ kreds i grafen. f o r a l l e k a n t e r (u, v) ∈ E i f L(u) + w(u, v) < L(v) 15 T (n) S˚ a f i n d e s d e r en n e g a t i v k r e d s . 4.5.1 Tidskompleksitet Givet input p˚ a n knuder og m kanter Alle n knuder gennemløbes Alle m kanter justeres m Vi har at worst case er T (n) = n · m n Da vi er interesseret i worst-case af algoritmen skal vi finde hvad m er i worst-case. For n knuder der hver har n − 1 naboer, vil m = n ∗ (n − 1). Vi f˚ ar derfor en worst-case beskrevet kun med n til T (n) = n3 − n2 . Dette giver T (n) = O(n3 ) 4.6 APSP algoritmer generelt ’All pairs shortest path’-problemet drejer sig om, at beregne afstande og korteste veje mellem samtlige par af knuder i en graf af formen G = (V, E). V er mængden af alle knuder i grafen og E er mængden af alle kanter i grafen.[10] Efter kørsel af en APSP-algoritme f˚ ar man to n × n − matricer, hvor n er antallet af knuder i grafen. Lader vi (u, v) beskrive et par af knuderne, s˚ a kan den ene matrix betegnes ved D(u, v) og er en vægtet nabo matrix, hvilket vil sige, at den indeholder alle afstande mellem samtlige par af knuder i grafen. Den anden matrix kaldes R(u, v). Mens den første matrix holder styr p˚ a afstande, s˚ a fortæller den anden matrix os i hvilken retning, alts˚ a til hvilken nabo, man skal g˚ a til, for at følge den korteste vej. 4.7 Floyds algoritme Et eksempel p˚ a en APSP-algoritme er Floyds algoritme. I det følgende er den beskrevet i pseudokode, hvor R betegner matrixen med naboer, som vi i det foreg˚ aende blev beskrevet med R(u, v) og N , som opdateres med korteste afstande mellem knudepar (u, v), som vi tidligere kaldte D(u, v)[11]. Denne udgave af Floyds algoritme tager højde for negative længder med if-sætningen ’if N(i,j) > N(i,k) + N(k,j) then’. p r o c e d u r e Floyd (G) ; begin N:= R; f o r k in 1 . . n loop f o r u in 1 . . n loop f o r v in 1 . . n loop J u s t e r L(k, u, v) end i f ; end l o o p ; end l o o p ; 16 end l o o p ; end Floyd ; Algoritmen starter med at kigge p˚ a løkken v, og tjekker alle andre knuder om, det er muligt at lave en kortere vej fra denne knude. Efter den har gjort det, vil den g˚ a videre med u for at tjekke om, der er kommet nogle nye steder, hvor det er blivet muligt at lave en kortere vej fra u til de andre knuder og det vil den blive ved med, indtil den er kommet igennem alle knuderne[12]. 4.7.1 Eksempel p˚ a Floyds algoritme Figur 4.1: Ikke-orienteret vægtet graf [8] ∞ 4 2 ∞ ∞ ∞ (a, a) 4 ∞ 1 5 ∞ ∞ (a, b) 2 1 ∞ 8 10 ∞ (a, c) ∞ 5 8 ∞ 2 6 = (a, d) ∞ ∞ 10 2 ∞ 3 (a, e) ∞ ∞ ∞ 6 3 ∞ (a, z) Grafen 4.1 i 1 2 1 2 1 2 1 2 1 2 1 2 (b, a) (b, b) (b, c) (b, d) (b, e) (b, z) (c, a) (c, b) (c, c) (c, d) (c, e) (c, z) (d, a) (d, b) (d, c) (d, d) (d, e) (d, z) (e, a) (e, b) (e, c) (e, d) (e, e) (e, z) (z, a) (z, b) (z, c) (z, d) (z, e) (z, z) matrixform. D(0) 3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 R(0) matrixen N˚ ar man kører Floyds algoritme første gang, kigger man p˚ a i = 1. Værdien af i bruges til at markere den korteste vej gennem en knude. Alle de steder i 17 R, hvor der st˚ ar 1, skal man g˚ a igennem knuden a for at finde den korteste vej. Havde i været 2, skulle vi g˚ a igennem 2. Floyds algoritme for i = 1 starter alts˚ a med at kigge p˚ a a, derfor kigger man p˚ a første række og kolonne. S˚ a løber man igennem for at finde alle de nye korteste vej gennem a. I første række og kolonne, alts˚ a (2, 1) og (1, 2), ser vi tallet 4, kigger man i (2, 2) er tallet ∞, da summen af (2, 1)+(1, 2) er 8 og da 8 < ∞ s˚ a sættes den nye korteste vej i (2, 2) til 8. S˚ a opdateres R(2, 2) til 1 da i = 1. Ligeledes opdateres D(3, 3) og R(3, 3)[13]. Hvordan R matricen bruges til at finde den korteste vej, kommer vi tilbage til i slutningen af dette afsnit. Til at starte med beskæftiger vi os med at f˚ a den til at indeholde de rigtige veje. ∞ 4 2 ∞ ∞ ∞ 4 8 1 5 ∞ ∞ 2 1 4 8 10 ∞ ∞ 5 8 ∞ 2 6 ∞ ∞ 10 2 ∞ 3 ∞ ∞ ∞ Figur 4.1 i 1 2 1 1 1 2 1 2 1 2 1 2 6 3 ∞ matrixform. D(1) 3 4 5 6 3 4 5 6 1 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 R(1) matricen S˚ adan forsætter man til i = 6 er løbet igennem, da har man de færdige matricer. Grunden til det er, at i = 6 er fordi, der er 6 knuder i grafen, s˚ a man gennem løber løkken en gang per knude til, at man ikke har flere knuder i grafen. De færdige matricer ser s˚ aledes ud: 4 3 2 8 10 13 3 2 1 5 7 10 2 1 2 6 8 11 8 5 6 4 2 5 10 7 8 2 4 3 13 10 11 5 3 6 Grafen figur 4.1 i matrixform. D(6) 18 3 3 1 2 4 5 3 3 2 2 4 5 3 3 2 2 4 5 3 4 2 2 4 5 4 4 4 5 4 5 5 5 5 5 6 5 R(6) matrixen Hvis man gerne vil finde den korteste vej fra a til z, starter man i R(6) med at kigge p˚ a (6, 1), svarende til z, hvor der st˚ ar 5, hvilket betyder, at man skal g˚ a til e alts˚ a (5, 1) bemærk, at v ikke ændrer sig, da vi stadig ønsker at finde vejen til a. Dette fortsættes ind til, at man f˚ ar det samme tal i u som i v. Vejen bliver alts˚ a a, c, b, d, e, z med en længde p˚ a 13. 4.7.2 Tidskompleksitet Har vi et input p˚ a n knuder, s˚ a har vi en tidskompleksitet p˚ a T (n) = n·n·n = n3 , fordi algoritmen gennemløber tre løkker n gange. Hvilket giver at T (n) = O(n3 ). 4.8 Valg af algoritme Den første algoritme vi kiggede p˚ a var Dijkstras algoritme. Den havde den ulempe, at den ikke kan regne p˚ a negative kanter. Men da vi ikke har negative vægtede kanter i grafer over bygninger, kan vi se bort fra dette. Tidskompleksiteten for Dijkstras algoritme er O(n2 ). En af forskellene ved Bellman-Ford algoritmen og Dijkstras algoritme er, at Bellman-Ford kan tage negative kanter, som tidligere nævnt har vi ikke brug for negative kanter. Dijkstras algoritme har tidskompleksiteten O(n2 ), mens Bellman-Ford har tidskompleksiteten p˚ a O(n3 ). En anden vigtig forskel p˚ a de to algoritmer er, at Dijkstras algoritme er en gr˚ adig algoritme. Den sidste algoritme vi har beskæftiget os med er Floyds algoritme. Den har en tidskompleksiteten O(n3 ). Den største forskel p˚ a Floyds algoritme i forhold til Dijkstras, er at mens Dijkstras kun finder korteste vej fra en knude til alle andre, s˚ a finder Floyds korteste vej mellem alle knuder. Det kommer derfor an p˚ a hvor mange kilder og dræn vi har i vores graf. Har vi mange knuder kan Floyds algoritme være en fordel. Vi vil her se p˚ a grafen, som vi har lavet over Strandvejen 12 i figur 2.1 for at se hvilken algoritme, der vil være optimal i forhold til kilder og dræn. Her kan vi se, at der kun er tre dræn, hvilket betyder at Dijkstras algoritme vil tage O(3 · n2 ). Hvis vi vælger Floyds algoritme til at finde alle korteste veje, vil det tage O(n3 ) tid. Da Dijkstras algoritme har en lavere kompleksitet end de to andre algoritmer, har vi valgt at bruge den algoritme. Nu da vi har kigget p˚ a kortestevej delen af vores problem, kan vi g˚ a videre til at se p˚ a strømningsproblemet. 19 Kapitel 5 Største strømnings-problemet Vi vil gerne finde ud af, hvor stor strøming en flugtplan tillader. Strømningen for en flugtplan kan fortælle os, om alle menneskerne i flugtplanen kan komme ud. Herunder vil vi ogs˚ a gennemg˚ a Ford-Fulkersons metode. 5.1 Strømningsnetværk Et strømningsnetværk er en vægtet orienteret graf G = (V, E), hvor alle e ∈ E har en positiv vægt, kaldet kapaciteten c(u, v), hvor u ∈ V og v ∈ V . To knuder s ⊆ V og d ⊆ V kaldes for kilder og dræn. For et strømningsnetværk skal der gælde: Strømingen for en given kant m˚ a ikke overstige dens kapacitet: For alle u, v ∈ V skal c(u, v) ≥ f (u, v) For alle knuder skal den strømning, der kommer ind være lig den strømning, der g˚ ar ud, undtagen for kilder og dræn: X For alle v ∈ V \{s, t} skal f (v) = 0 v∈V Bevæger vi os modsat orienteringen f˚ ar vi en strømning med negativt fortegn: For alle u, v ∈ V skal f (u, v) = −f (v, u) Definition 10. Givet er: • Et strømningsnetværk G = (V, E) • En strømningsfunktion f : E → R+ Her er den samlede strømning af et strømningsnetværk |f | defineret som: X |f | = f (e) e∈E Definition 11. Givet er: 20 • Et strømningsnetværk G = (V, E) • En strømningsfunktion f : E → R+ Her er den resterende kapacitet cr defineret som: cr (u, v) = c(u, v) − f (u, v) Finder vi for et strømningsnetværk G = (V, E), den resterende kapacitet for alle kanter, kan vi lave et nyt strømningsnetværk, hvor c(u, v) = cr (u, v) for alle (u, v) ∈ E. Dette netværk kalder vi et rest-netværk Gr = (V, E). En vej fra en kilde til et dræn i s˚ adan et strømningsnetværk kalder vi en rest-vej pr . 5.2 Ford-Fulkersons metode Vi vil her beskrive Ford-Fulkersons metode, som kan finde den største strømning for en given graf G = (V, E). Ideen bag metoden er at lave et rest-netværk for den givne graf og derefter forøge strømningen gennem grafen indtil der ikke kan findes flere rest-veje. Dette skulle give os den største strømning gennem grafen. Vi vil her vise at dette er sandt, her følger beviset: Givet er et strømningsnetværk G = (V, E) og en afledt rest-graf Gr = (V, E). Lad os antage, at vi har fundet den største strømning |f | for G, men at der stadig er en rest-vej tilbage i Gr . S˚ a vil |f | + fr , hvor fr er den strømning, der kan g˚ a igennem rest-vejen, være større end den antagede største strømning. Vi har derfor at den største strømning af G f˚ as, n˚ ar der ikke er flere rest-veje tilbage. 5.2.1 Pseudokode Her kommer en meget basal implementering af Ford-Fulkersons metode. Givet e t s t r ø m n i n g s n e t v æ r k G = (V, E) . En k i l d e og e t dræn . f o r a l l e k a n t e r (u, v) ∈ E f (u, v) = 0 f (v, u) = 0 w h i l e d e r e k s i s t e r e r en r e s t −v e j mellem k i l d e n og drænet i r e s t −g r a f e n Gr f o r a l l e r e s t −v e j e θ i Gr f o r a l l e k a n t e r (u, v) ∈ θ f (u, v)+ = F (θ) f (v, u) = −f (u, v) Som beskrevet her kan denne algoritme kun finde strømningen fra en kilde til et dræn. Da vi i vores projekt vil finde veje mellem flere kilder og dræn skal vi have rettet den. For flere dræn og kilder ændrer man ikke p˚ a koden, men til 21 gengæld p˚ a grafen. For at reducere et strømningsnetværk med flere kilder og dræn til et strømningsnetværk med ´en kilde og ´et dræn. Tilføjer vi en superkilde til mængden af kilder og et superdræn til mængden af dræn. S˚ a tilføjer vi en orienteret kant fra superkilden til alle kilder, hvor kapaciteten er uendelig. Det samme gør vi for superdrænet til alle dræn. Derved kan man finde strømningen mellem superkilden og superdrænet for at finde største strømning. 5.2.2 Kompleksiteten af Ford-Fulkersons algoritme I Ford-Fulkersons metode havde vi en while-løkke der fandt veje mellem kilden og drænet i rest-grafen. Alt efter hvordan der findes veje er kompleksiteten af Ford-Fulkersons algoritme forskellig. Til at finde veje anvender vi Dijkstras algoritme. Givet input n knuder og den maksimale strømning f ∗ : Hver gang vi finder rest-veje anvendes Dijkstras algoritme: n2 − n Hvis hver vejs mindste kapacitet er p˚ a 1 kører løkken s˚ a mange gange som der ∗ er strømning: f I alt har vi T (n) = n2 − n · f ∗ Derved f˚ ar vi at T (n) = O(n2 · f ∗ ) 22 Kapitel 6 Overvejelser ved egen kode Vi har nu kigget p˚ a flere forskellige problemstillinger s˚ a som strømning, kortestevej algoritmer og flugtvejproblemet. Dem vil vi bruge i vores program, vi har fundet ud af at det ikke matematisk muligt at gøre. En af de ting er, at folk bevæger sig i en flok, s˚ a hvis vi har to grupper af mennesker der skal ud af to forskellige udgange. De grupper møder s˚ a en fælles gang, s˚ a er der gode muligheder for at de vil sl˚ a sig sammen til en stor gruppe[?]. Det kan vi ikke tage højde for, da det er svært at programmere adfærd ind i et program. 23 Kapitel 7 Implementationens struktur I dette afsnit vil vi omtale vores stuktur i koden med det form˚ al at give en bedre forst˚ aelse af vores program. Pga. vores kursus om Java har vi valgt at programmere programmet i dette. Vores oprindelige ide om et program, var et program der, kunne kører p˚ a h˚ andholdte enheder. Her ville Java være optimal, da Java kan køre p˚ a mange forskellige enheder inklusiv de fleste mobiltelefoner. Vi vil her gennemg˚ a de forskellige klasser som definere datastrukturerne, OptimalPathFrameWork, Edge, Node, Graph, Path og PathFinder. 7.1 OptimalPathFramework Denne klasse er vores main, hvor vi kører alle de andre dele fra. Den indeholder ingen metoder eller constructors. 7.2 Edge Edge klassen bliver brugt til at lave nye kanter. Kantens propeties er target,length,flow og capacity. S˚ a vi er i stand til at bestemme, hvor kanten g˚ ar hen, hvad den er vægtet med og dens strømning. N˚ ar vi skal lave en ny kant, anvender vi disse to constructors: p u b l i c Edge ( S t r i n g fromNode , S t r i n g toNode , Graph graph , d o u b l e lengthOfEdge , d o u b l e c a p a ci t y O fE d g e ) { Node from = graph . getNode ( fromNode ) ; Node t o = graph . getNode ( toNode ) ; from . n e i g h b o u r s . add ( new Edge ( to , lengthOfEdge , c ap a c i t yO f E dg e ) ) ; t o . n e i g h b o u r s . add ( new Edge ( from , lengthOfEdge , c a p ac i t y Of E d g e ) ) ; } p u b l i c Edge ( Node toNode , d o u b l e lengthOfEdge , d o u b l e c a pa c i t y Of E d g e ) 24 { t a r g e t = toNode ; l e n g t h = lengthOfEdge ; c a p a c i t y = c a p ac i t y O fE d g e ; } N˚ ar man laver en kant anvender man den øverste constructor. Man fortæller om vægtningen og hvilken knude den g˚ ar fra og til og i hvilken graf. I denne constructor tilføjer vi de to knuder som naboer til hinanden ved at kalde den anden constructor, som s˚ a tilføjer en kant mellem knuderne for begge veje. 7.3 Node Denne klasse gør os i stand til at lave knuder. Klassens properties er disse: name, neighbours, previous, minDistance og flow. name er knudens navn som angives hver gang, man laver en ny knude. Knudens naboer lagres i form af en liste af kanter kaldet neighbours. Previous og minDistance anvendes, n˚ ar vi skal finde korteste veje og flow angiver vejens samlede strømning. Dens constructor kræver kun, at vi angiver et navn i form af en String. Den eneste metode klassen indeholder er printNeighbours(), den er som navnet antyder i stand til at fortælle os, hvilke naboer knuden har i form af kanter. 7.4 Graph Graph-klassen gør os i stand til at lave grafer. Denne klasse repræsenterer en graf G = (V, E) Grafens property nodes er en liste med knuder, som fortæller hvilke knuder, der er indeholdt. For at fjerne kanter anvendes deleteEdges, hvor input er to knuder, s˚ a fjernes kanterne imellem dem. For at tilføje nye kilder og dræn bruger vi addSourcesAndDrains input, til denne er to String arrays, et String array for hvilke knuder, som er dræn og det andet for hvilke, som er kilder. Hvis vi vil kopiere en graf, benytter vi copyGraph, inputtet er den graf, man vil kopiere. For at f˚ a fat i en given knude i en graf anvendes getNode(String name). Metoden virker ved at alle knuder gennemløbes indtil den knude med navnet givet som input findes. Denne knude returneres. p u b l i c Node getNode ( S t r i n g nodeName ) { f o r ( Node node : nodes ) { i f ( node . name == nodeName ) { r e t u r n node ; } } return null ; } 25 7.5 Path Path-klassen gør os i stand til at lave veje. Vejen bliver lagret i propertien nodes i form af en liste af knuder. Da vi ikke har lagret kanterne i form af en liste, anvender vi metoden getEdge til at finde en kant mellem to knuder i en vej. Klassens andre metoder gør os i stand til at udregne en vejs længde, den mindste resterende kapacitet og gevinsten. Her vil vi forklare, hvordan getEdge fungerer, da vi anvender den ret ofte. Metodens input er to knuder. Den første knudes naboer gennemløbes indtil der findes en kant, der g˚ ar mod den anden knude. p u b l i c Edge getEdge ( Node from , Node t o ) { f o r ( Edge edge : from . n e i g h b o u r s ) { i f ( edge . t a r g e t == t o ) { r e t u r n edge ; } } return null ; } 7.6 PathFinder Denne klasse indeholder de metoder, vi bruger til at finde veje med. De metoder vi har er shortestPaths, maxFlow og optimalPaths. shortestPath er en implementering af Dijkstras algoritme. MaxFlow er en implementering af FordFulkersons metode, som dog ikke finder veje, men som bliver brugt i optimalPaths, der kan finde optimale veje fra en mængde af kilder til en mængde dræn. 7.6.1 Implementering af Dijkstras algoritme Vi vil her forklare, hvordan vi har implementeret Dijkstras algoritme. Input for metoden er graph, startNode og targetNodes, som er henholdvis en given graf, en startknude og alle knuderne vi vil have veje til. Metoden returnerer en liste af veje. Det første trin for Dijkstras algoritme er initialisering. f o r ( Node node : graph . nodes ) { node . minDistance = Double . POSITIVE INFINITY ; } s t a r t N o d e . minDistance = 0 . ; Her beskriver minDistance længden fra startknuden til denne knude. I afsnittet om Dijkstras algoritme blev dette beskrevet med L(u), hvor u er en vilk˚ arlig knude. 26 Det næste trin er Dijkstras while-løkke. Denne løkke ender først, n˚ ar nodesSearched.containsAll(targetNodes). Den første del af løkken er at bestemme, hvilken knude vi skal gennemsøge. Denne knude bliver derefter lagret i nodesSearched. minDistance = Double . POSITIVE INFINITY ; f o r ( Node node : graph . nodes ) { i f ( n o d e s S e a r c h e d . c o n t a i n s ( node ) ) { continue ; } e l s e i f ( node . minDistance < minDistance ) { currentNode = node ; minDistance = node . minDistance ; } } n o d e s S e a r c h e d . add ( currentNode ) ; For at sikre os at der kan findes en vej, tjekker vi om den knude vi skal til at gennemsøge er den samme, som den knude, vi lige har gennemsøgt. Er dette sandt, er der ikke nogen veje ellers sætter vi den nyfundne knude til at være den forrige knude. i f ( currentNode == p r e v i o u s N o d e ) { return null ; } else { p r e v i o u s N o d e = currentNode ; } Herefter kommer justeringstrinet. Dog vil vi ikke justere, hvis naboen er indeholdt i mængden af allerede gennemsete knuder. f o r ( Edge n e i g h b o u r : currentNode . n e i g h b o u r s ) { i f ( nodesSearched . contains ( neighbour . t a r g e t ) ) { continue ; } i f ( ( currentNode . minDistance + n e i g h b o u r . l e n g t h ) < n e i g h b o u r . t a r g e t . minDistance ) { n e i g h b o u r . t a r g e t . minDistance = ( currentNode . minDistance + neighbour . length ) ; n e i g h b o u r . t a r g e t . p r e v i o u s = currentNode ; 27 } } Normalt for Dijkstras algoritme bliver vejen hen til knuderne ikke lagret. N˚ ar vi justerer minDistance, gemmer vi desuden hvorfra hvilken knude, man kom fra. Derved kan vi gennemløbe alle de forrige knuder, startende ved slutknuderne til vi har startknuden. For at have vejene i den rigtige rækkefølge anvender vi Collections.reverse(), som vender rækkefølgen i en liste. Til sidst returnerer vi alle de korteste veje. f o r ( Node t a r g e t : t a r g e t N o d e s ) { Path path = new Path ( ) ; f o r ( Node node = t a r g e t ; node != n u l l ; node = node . p r e v i o u s ) { i f ( node . name != ” s u p e r S o u r c e ” && node . name != ” s u p e r D r a i n ” ) { path . nodes . add ( node ) ; } } C o l l e c t i o n s . r e v e r s e ( path . nodes ) ; path . c a l c u l a t e L e n g t h ( ) ; s h o r t e s t P a t h s . add ( path ) ; } return shortestPaths ; 7.6.2 Implementering af Ford-Fulkersons algoritme I dette afsnit beskrives vores implementation af Ford-Fulkersons algoritme lavet som metoden maximumFlow. Der er givet en start knude, slut knude og en graf. Ford-Fulkersons algoritmens første trin er at tømme strømningen for alle kanter. f o r ( Node node : copyOfGraph . nodes ) { f o r ( Edge n e i g h b o u r : node . n e i g h b o u r s ) { neighbour . flow = 0 ; } } Derefter følger en while-løkke, det er det trin hvor vi finder rest-veje indtil der ikke kan findes flere og den største strømning er fundet. Vi anvender Dijkstras algoritme til at finde veje, da vores implementation af denne algoritme tager en liste af slutknuder som input laver vi en ny liste og tilføjer slutknuden givet som input til maximumFlow metoden. 28 Denne del finder korteste veje mellem start og slutknuden, hvis der ikke kan findes nogen returneres den fundne strømning. Findes der nogle veje vælges den første vej ud, da hvilken vej vi vælger ikke har nogen betydning for at finde største strømning. Den vejs mindste resterende kapacitet tilføjes til maximumFlow. pathsFromSourceToDrain = s h o r t e s t P a t h s ( copyOfGraph , startNode , endNode ) ; i f ( pathsFromSourceToDrain == n u l l ) { maximumFlowFound = t r u e ; graph . f l o w = maximumFlow ; r e t u r n maximumFlow ; } Path path = pathsFromSourceToDrain . g e t ( 0 ) ; path . calculateMinimumRemaingCapacity ( ) ; L i s t <Node> edgesToBeRemoved = new A r r a y L i s t <Node >() ; maximumFlow += path . getMinRemainingCapacity ( ) ; Da vi anvender Dijkstras algoritme til at finde veje med bliver vi nød til at fjerne kanter fra grafen, hvis strømningen er lig kapaciteten for en given kant. Dette gør vi s˚ aledes at Dijkstras algoritme ikke bruger disse veje igen. For at slette en kant tilføjer vi knuderne som kanten g˚ ar fra og til til en liste som vi bagefter sletter med metoden deleteEdges. f o r ( i n t i = 0 ; i < path . nodes . toArray ( ) . l e n g t h −1; i ++) { Edge e = path . getEdge ( path . nodes . g e t ( i ) , path . nodes . g e t ( i +1) ) ; e . f l o w += path . getMinRemainingCapacity ( ) ; i f ( ( e . c a p a c i t y −e . f l o w ) <= 0 ) { edgesToBeRemoved . add ( path . nodes . g e t ( i ) ) ; edgesToBeRemoved . add ( path . nodes . g e t ( i +1) ) ; } } f o r ( i n t i = 0 ; i <edgesToBeRemoved . toArray ( ) . l e n g t h −1; i +=2) { copyOfGraph . d e l e t e E d g e s ( edgesToBeRemoved . g e t ( i ) . name , edgesToBeRemoved . g e t ( i +1) . name ) ; } 29 Kapitel 8 Forsøg p˚ a algoritmer til at finde optimale flugtveje Vi har i forrige kapitel set p˚ a implementeringen af Dijkstras algoritme og FordFulkersons metode. Vi vil bruge disse algoritmer til at finde optimale flugtveje. Hvordan kan dette gøres og hvilke problemer kan der opst˚ a? Bruger vi kun Dijkstras algoritme f˚ ar vi veje som er de korteste, men som ikke tager hensyn til kapaciteten af flugtvejene. Ford-Fulkersons metode tager kun hensyn til strømningen, hvilket kan give en lang evakueringstid. Koger vi det ned er det store problem at finde forholdet mellem at vælge veje der er korte og veje som kan f˚ a folk ud. Vi har i dette afsnit givet et bud p˚ a hvordan dette kan gøres og derefter give noget kritik af det. 8.1 Tanker om algortimen Det kan hænde at kapaciteten for en bygning er mindre end antallet af flygtende. Det vil derfor nogle gange være nødvendig at skulle have mennesker ud i flere omgange. Praktisk set vil kapaciteten være ledig allerede efter en enkelt tidsenhed, da menneskerne vil have flyttet sig fra det stykke af gangen. N˚ ar menneskerne har løbet igennem en kant, og skal tage en ny kant, vil de optage denne gangs kapacitet. Det vil sige at man konstant skal holde styr p˚ a hvor menneskerne befinder sig, for ikke at bruge den samme kapacitet flere gange samtidig. Dette vil være utrolig svært, og vi vil derfor forsimple dette i vores algoritme ved først at sende den næste gruppe mennesker afsted n˚ ar hele den første menneskemængde er blevet evakueret, og der ikke er mere strømning i grafen. Vi har forsøgt at omskrive vores ideer til pseudokode over algoritmen. f u n k t i o n o p t i m a l V e j ( Graf , K i l d e r ) g r a f T i l B r u g = Graf ; batches = 0; vejeBrugt [ ] ; Vælg r æ k k e f ø l g e a f k i l d e r ; 30 while ( a l l e ikke er evakueret ) f o r a l l e ( knuder i g r a f ) gendan ; for alle ( kilde i graf ) tømer f l o w ; for alle ( kilder i graf ) FordFulkersons t i l kilden er tom ; // B e n y t t e r D i j k s t r a s t i l at f i n d e v ej e v e j e B r u g t [ Vejene gemmes ] ; i f ( Der i k k e e r f l e r e v e j e ) batch++; f o r a l l e ( veje i vejeBrugt ) beregn e v a k u e r i n g s t i d ; Retuner e v a k u e r i n g s t i d og b a t c h e s 8.1.1 Tidskompleksiteten af algoritmen Da det er en kompliceret algoritme, vil vi prøve finde store O til tidskompleksiteten. Givet input n knuder, m kanter, den maksimale strømning f ∗ og et antal omgange l der angiver hvor mange runder det tager at f˚ a menneskerne ud. Den først løkke er while løkken som er hovede løkken i algoritmen, den gennemløbes ind til alle er evakueret, hvilket kan være op til f ∗ . Her efter gendannes grafen dette kan ske op til f ∗ gange, da dette er antallet af gange while loopet gennem løbes. For hvergang vi gendanner skal vi løbe alle knuder igennem igen hvilket højest kan være n. Derfor skal n ganges p˚ a f ∗ . Efter gendannelse tømmes flowet for alle kanter dette sker m gange. S˚ a f˚ ar vi f ∗ · (m + n). Der efter køres Ford Fulkersons højest en gang for hver vej f ∗ . Men da vi benytter dijkstras algortime til at finde vej i Ford Fulkersons bliver den i stedet f ∗ gange n2 , grundet store O for dijkstras er n2 , som det kan ses i afsnit 4.4.1. S˚ a f˚ ar vi f ∗ · m + n · f ∗ · n2 hvilket giver (f ∗ )2 · n2 · (n + m), hvilket er det samme som (f ∗ )2 · n2 · (n + n · (n − 1)), s˚ a man kan alts˚ a skrive store O som (f ∗ )2 · n4 . ∗ 2 4 Vi f˚ ar derfor worst-case T (n) = O()f ) · n ). Vi kan nu begynde at skrive vores program i java, og kommer i det næste afsnit ind p˚ a hvordan den virker efter den blev implementeret. 31 8.2 Vores algoritme N˚ ar vi starter vores algoritme, er det første skridt at vælge, hvilken rækkefølge kilderne skal komme i. Grunden til at vi gør dette er at den kilde vi starter ved, kan f˚ a de bedste veje ud af grafen p˚ a daværende tidspunkt. N˚ ar vi n˚ ar til de sidste kilder vil det svært at finde rest-veje igennem da kapaciteten er opbrugt mange steder. Vi har diskuteret bredt hvordan dette skulle ske. Er det mest retfærdigt starte med dem vi kan f˚ a hurtigst ud, dem der tilfældigvis ligger først i en liste eller fra den kilde hvor det er muligt at f˚ a flest ud? Vi har valgt to m˚ ader at sortere kilderne p˚ a. Enten bliver de valgt efter hvilken kilde, der har den mindste strømning eller s˚ a bliver de valgt ud fra, hvor stor befolkningen er ved kilden. Grunden til dette er at vi ved kilder med mindste strømning gerne vil have dem ud først fordi de har den største ulempe for at komme ud. Vi vælger at sortere kilderne efter befolkning for at f˚ a flest ud hurtigst muligt. Desuden bliver der noteret hvor mange mennesker, der skal evakueres. S˚ a bruger vi en kombination af korteste vej og Ford-Fulkersons til at finde alle de optimale vej. Vi starter med den første kilde efter vi har sorteret dem og kører Dijkstras algoritme fra kilden til alle dræn. Derefter udvælges den optimale vej fra en kilde til et dræn. Vejen udvælges udfra enten højeste gevinst eller den der er kortest. Den første gang algoritmen kører finder den kun veje i forhold til hvor korte de er og anden gang vælger de veje i forhold til gevinsten. N˚ ar vi har to mængder af veje sammenlignes de til sidst udfra hvor mange omgange vi fik menneskerne ud p˚ a, hvor mange veje det krævede og den samlede evakuringstid. Her betyder evakuringstiden den længste tid af den mængde af optimale veje vi har. N˚ ar vejen er valgt ud finder vi den mindste resterende kapacitet p˚ a vejen og sender mest muligt strømning igennem. Hvis ikke alle er kommet ud g˚ ar vi videre og undersøger om, det er muligt at f˚ a flere ud fra denne kilde nye rest-veje. Kan dette ikke lade sig gøre, g˚ ar vi videre til at undersøge om, det er muligt at evakuere flere via andre kilder. N˚ ar dette er gjort og der ikke er mere kapacitet at tage af g˚ ar vi videre. Hvis det ikke er muligt at finde flere rest-veje starter vi forfra med en ny evakueringsrunde. Der regnes igen flugtveje og de sammenlignes igen som tidligere. Evakueringstiden som denne runde tager bliver s˚ a lagt sammen med den tid fra første runde. S˚ adan fortsættes der indtil, alle er evakueret fra alle kilder. N˚ ar alle mennesker er blevet evakueret, udskriver algoritmen hvor mange mennesker der er blevet evakueret, hvor lang tid det tog, og i hvor mange omgange der skulle til for at f˚ a alle ud. 8.2.1 Koden N˚ ar vi starter vores algoritme er det første skridt at vælge hvilken rækkefølge kilderne skal komme i.Der er to ting de kan blive valgt p˚ a baggrund af. Enten bliver de valgt efter hvilken kilde der har den største strømning, ellers bliver de valg ud fra hvor stor befolkningen er ved kilden. Desuden bliver der noteret hvor mange mennesker der skal evakueres. 32 // Noting t h e number o f p e o p l e we a r e e v a c u a t i n g i n t numberOfPeople = 0 ; graph . s o u r c e s = s e l e c t S o u r c e O r d e r ( 2 , graph . s o u r c e s , graph ) ; f o r ( i n t i = 0 ; i <f l o w L e f t I n S o u r c e s . l e n g t h ; i ++) { f l o w L e f t I n S o u r c e s [ i ] = graph . s o u r c e s . g e t ( i ) . f l o w ; numberOfPeople += graph . s o u r c e s . g e t ( i ) . f l o w ; } selectSourceOrder er funktionen der faktisk vælger rækkefølgen af kilder. Som tideligere nævnt er der to forskellige modes den kan vælge kilder efter. Mode 1 som ses her vælger ud fra hvilke kilder der har det højeste flow. L i s t <Node> s e l e c t S o u r c e O r d e r ( i n t mode , L i s t <Node> s o u r c e s , Graph graph ) { i f ( mode == 1 ) { Graph maximumFlowGraph = new Graph ( new Node [ ] { } ) ; for ( int i = 0; i <graph . s o u r c e s . toArray ( ) . l e n g t h ; i ++) { maximumFlowGraph . nodes . c l e a r ( ) ; maximumFlowGraph . s o u r c e s . c l e a r ( ) ; maximumFlowGraph . d r a i n s . c l e a r ( ) ; maximumFlowGraph . copyGraph ( graph ) ; f o r ( Node d r a i n : maximumFlowGraph . d r a i n s ) { maximumFlowGraph . nodes . add ( new Node ( ” s u p e r D r a i n ” ) ) ; d r a i n . n e i g h b o u r s . add ( new Edge ( maximumFlowGraph . getNode ( ” s u p e r D r a i n ” ) , 0 , Double . POSITIVE INFINITY ) ) ; } maximumFlowGraph . s o u r c e s . g e t ( i ) . f l o w = maximumFlow ( maximumFlowGraph , maximumFlowGraph . s o u r c e s . g e t ( i ) , maximumFlowGraph . getNode ( ” s u p e r D r a i n ” ) ) ; } f o r ( Node s o u r c e : maximumFlowGraph . s o u r c e s ) { f o r ( Node node : graph . s o u r c e s ) 33 { i f ( node . name == s o u r c e . name ) { s o u r c e . f l o w = node . f l o w ; } } } f o r ( i n t k = 0 ; k<maximumFlowGraph . s o u r c e s . toArray ( ) . l e n g t h −1;k++) { i f ( maximumFlowGraph . s o u r c e s . g e t ( k ) . f l o w >maximumFlowGraph . s o u r c e s . g e t ( k+1) . f l o w ) { Node temp = maximumFlowGraph . s o u r c e s . g e t ( k+1) ; maximumFlowGraph . s o u r c e s . s e t ( k+1, maximumFlowGraph . s o u r c e s . get (k) ) ; maximumFlowGraph . s o u r c e s . s e t ( k , temp ) ; } } r e t u r n maximumFlowGraph . s o u r c e s ; } Det andet mode er hvor de bliver valgt efter hvor stor befolkningen er ved de forskellige kilder. Der hvor der er flest mennesker der skal ud, bliver valgt som den første osv. e l s e i f ( mode == 2 ) { for ( int i = 0 ; i <graph . s o u r c e s . toArray ( ) . l e n g t h −1; i ++) { i f ( graph . s o u r c e s . g e t ( i ) . f l o w >graph . s o u r c e s . g e t ( i +1) . f l o w ) { Node temp = graph . s o u r c e s . g e t ( i +1) ; graph . s o u r c e s . s e t ( i +1, graph . s o u r c e s . g e t ( i ) ) ; graph . s o u r c e s . s e t ( i , temp ) ; } } } 34 r e t u r n graph . s o u r c e s ; Tredje skridt en vej udvælges efter største strømning som set her eller efter befolkningen ved hver kilde. i f ( p a t h s S t o r e d == t r u e ) { // A l l p a t h s have been found − r e t u r n i n g t h e p a t h s with t h e s m a l l e s t e v a c u t i o n t i m e i f ( profitPathsEvacutionTime · p r o f i t P a t h E v a c u t i o n T i m e P a t h s . toArray ( ) . l e n g t h < shortestPathsEvacutionTime · shortestPathEvacutionTimePaths . toArray ( ) . l e n g t h ) { graph . evacutionTime = profitPathsEvacutionTime ; f o r ( Path path : profitPathEvacutionTimePaths ) { path . p r i n t ( ) ; } return profitPathEvacutionTimePaths ; } } Efter befolkningen ved hver kilde er som set her. e l s e i f ( mode == 2 ) { f o r ( i n t i = 0 ; i <graph . s o u r c e s . toArray ( ) . l e n g t h −1; i ++) { i f ( graph . s o u r c e s . g e t ( i ) . f l o w >graph . s o u r c e s . g e t ( i +1) . f l o w ) { Node temp = graph . s o u r c e s . g e t ( i +1) ; graph . s o u r c e s . s e t ( i +1, graph . s o u r c e s . g e t ( i ) ) ; graph . s o u r c e s . s e t ( i , temp ) ; } } } S˚ a finder vi alle de korteste vej og alle de veje med størst gevinst. // Finds a path with e i t h e r minimum l e n g t h o r maximum profit 35 i f ( s e a r c h F o r P r o f i t P a t h s == t r u e ) { f o r ( Path path : s h o r t e s t P a t h s T o D r a i n s ) { path . c a l c u l a t e P r o f i t ( ) ; i f ( path . g e t P r o f i t ( ) > maximumProfit ) { s h o r t e s t P a t h = path ; maximumProfit = path . g e t P r o f i t ( ) ; } } } else { f o r ( Path path : s h o r t e s t P a t h s T o D r a i n s ) { path . c a l c u l a t e L e n g t h ( ) ; i f ( path . g et L e ng t h ( ) < minimumLength ) { s h o r t e s t P a t h = path ; minimumLength = path . ge t L en g t h ( ) ; } } } // Finds out how much f l o w we can g e t through t h i s path s h o r t e s t P a t h . calculateMinimumRemaingCapacity ( ) ; // Determing how mush f l o w t o add i f ( s h o r t e s t P a t h . getMinRemainingCapacity ( ) > s o u r c e . f l o w ) { flowToAdd = s o u r c e . f l o w ; } else { flowToAdd = s h o r t e s t P a t h . getMinRemainingCapacity ( ) ; } s o u r c e . f l o w −= flowToAdd ; //Adds t h e path t o t h e l i s t o f o p t i m a l p a t h s o p t i m a l P a t h s . add ( s h o r t e s t P a t h ) ; 36 8.2.2 Kritik af algoritme Algoritmen tager ikke højde for hvordan mennesker reagerer ved brand, som man kunne ønske, da den godt nok forsøger at f˚ a folk ud, flest mulige fra en kilde af gangen. Men der kan opst˚ a scenarier hvor et antal mennesker skal bevæge sig samlet i en retning, for s˚ a at dele sig op i to og g˚ a hver deres vej. Dette er imod den gruppe mentalitet vi tidligere har snakket om. Desuden mener vi ikke at algoritmen favoriserer et lille antal af veje godt nok. F.eks. vil den sige at 19 veje er bedre end 20 veje, dog kan dette godt være utrolig mange veje for en gruppe p˚ a 20. N˚ ar en flygtende mængde mennesker flygter tager vi heller ikke højde for at n˚ ar de bevæger sig igennem grafen bliver kapaciteten ledig bag dem. Som algoritmen fungerer nu skal de hele vejen ud for at kapacitet bliver ledig igen. 37 Kapitel 9 Modeldannelse Nu da vores algoritme virker og vi kan finde flugtveje ud af en bygning, kan vi begynde at kigge lidt p˚ a, hvordan implementationen i et arkitekt program kunne foreg˚ a. Det smarteste ville være, hvis der i programmet var en knap, som grafisk kunne vise, om det kunne lade sig gøre at f˚ a alle ud og hvor der kunne opst˚ a flaskehalsproblemer. For at det ville kunne lade sig gøre, skal programmet først generere en graf over bygningen med længde og kapacitet p˚ a alle kanter. 9.1 Opdeling af bygningen i knuder Knuder har vi tidligere defineret, som steder man kan opholde sig. N˚ ar arkitekten har tegnet en bygning, skal programmet kunne genkende rum og tildele dem en knude. Men dette er ikke helt nok som vi snakkede om i afsnit 2.1.1, skal større rum deles i flere knuder. Da de arkitekt programmer vi har kigget p˚ a, alle kan finde frem til arealet af et rum, kan vi indføre en standard for, hvor stort et areal en knude højest m˚ a repræsentere. Det samme gør sig gældende for gange, da disse ogs˚ a er steder, man kan opholde sig. 9.2 Tilføjelse af kanter N˚ ar grafen er delt op i knuder, kan man g˚ a videre til at forbinde dem med kanter. Kanter er beskrevet i afsnit 2.1.2 som veje mellem knuder. Det vil sige, at hvis to knuder ligger i samme rum eller er adskilt af en dør, skal der være en kant imellem. Arkitekt tegninger af bygninger indeholder allerede døre. Derfor skal man først finde de rum, hvor der er mere end en knude, er der mere end en, skal der være en kant imellem dem, hvis de er inden for en bestemt afstand af hinanden. Afstanden skal sikre at kun knuder, der ligger lige op af hinanden er naboer, s˚ a to knuder i hver ende af et meget stort rum f.eks. ikke er naboer. N˚ ar dette er gjort for alle knuder, kan man g˚ a videre til at forsøge at finde knuder, som kun er adskilt af en dør, igen skal der tjekkes om knuderne er inden for den forudbestemte afstand, men ikke i samme rum. Hvis dette er tilfældet skal, der tjekkes om en evt kant vil krydse en dør, er dette ogs˚ a opfyldt, skal der være en kant. 38 9.3 Længde og kapacitet N˚ ar vi skal tilføje længden af kanter, kan vi tage udgangspunkt i rummenes m˚ al, som vi kender fra arkitekt programmet. Derefter skulle det være muligt ud fra nogle matematiske beregninger at finde frem til længden. Som et eksempel kan man se p˚ a et rektangulært rum, der er delt op i to knuder. Afstanden fra knuderne, som begge er placeret i midten af hver deres lige store del af firkanten, hvor hver af de to dele er 5 · 5 meter, vil kanten være 2 · 12 · 5. N˚ ar der skal sættes kapacitet p˚ a kanterne var en mulig løsning, at de forskellige dør typer som allerede findes i arkitektprogrammerne allerede har en tilknyttet kapacitet. Derved er det blot at tjekke om en kant g˚ ar gennem en dør, hvis den gør skal kapaciteten sættes til dørens prædefinerede kapacitet. Hvis ikke skal kapaciteten sættes i forhold til en udregning, som kunne være rummets størrelse dividered med antallet af knuder ganget med hvor mange mennesker, der nomalt kan g˚ a gemmen et rum p˚ a den størrelse, alt efter loft højde og bredden p˚ a rummet. 9.4 Kilder og dræn Kilder er en af de f˚ a ting, vi ikke uden videre kan sætte programmet til at ordne automatisk, som vi ser p˚ a nu, m˚ a arkitekten selv sætte knuderne i de rum, som er kilder til at indeholde et antal personer. Vi kunne hjælpe arkitekten godt p˚ a vej ved, at antallet af personer bare skal sættes for et rum, s˚ a kan vi fordele antallet af personer p˚ a de forskellige knuder og hvis en knude indeholder personer, n˚ ar flugtvejsalgoritmen eksekveres er det en kilde. Dræn m˚ a arkitekten ogs˚ a selv sætte ind, ved at markere nogle knuder og sætte det til dræn. 9.5 Eksekvering N˚ ar programmet eksekveres er vores forestilling, at bygningen bliver markeret med hvor stor en del af kapaciteten der bliver brugt i de forskellige kanter. Som en følge deraf vil man kunne se hvor, der er flaskehalse, og derved hvor man skal sætte ind hvis man vil forbedre flugtplanen. Det er vores forestilling, at dette vil kunne hjælpe arkitekter med at forbedre deres bygning og gøre dem sikrer uden alt for meget ekstra arbejde. 9.6 kopieret fra metode Rapporten best˚ ar af en datalogisk og en matematisk vinkling. Da vi ønsker at finde en optimal vej ud af en bygning, er det oplagt at benytte grafteori. Grafteori gør os i stand til at modellere bygninger og der er lavet mange forskellige algoritmer til at beregne den korteste vej. Desuden findes algoritmer som kan 39 finde strømningen igennem en graf. Dog er dette vi ønsker at finde ikke de korteste veje, men de optimale veje. Hvad forst˚ ar man ved den optimale vej? Er den optimale vej, den man kender eller den som er kortest? Det er svært at sige og der er ogs˚ a flere ting at tage højde for. Hvis man har en flugtvej, der kun ligger fem meter væk, er det ikke nødvendigvis den optimale flugtvej. Denne flugtvej kan være s˚ a snæver, at folk ikke kan komme hen til udgangen. En optimal flugtvej afhænger derfor ikke kun af dens længde, men ogs˚ a af dens kapacitet. Den optimale flugtvejrute kan alts˚ a opdeles i to problemer, navnligt at finde veje i forhold til længde og veje i forhold til kapacitet. Igen m˚ a vi ind og definerer hvad det vi præcist skal forst˚ a ved en flugtvejs længde og kapacitet. En flugtvejs længde definerer vi som længden mellem start stedet og udgangen. Kapacitet er et vanskligere term at forklare. Bredden af en flugtvej definerer vi som kapacitet og m˚ ales i hvor mange mennesker, der kan komme igennem per sekund. Kapacitet kan være defineret p˚ a forskellige m˚ ader. Er det gangen hen til flugtdøren, man taler om eller er det selve dørens kapacitet? Man kan iagttage to forskellige flugtveje. • En flugtvej der har en gang med høj kapacitet og en dør med lille kapacitet. • En flugtvej der har en gang med lav kapacitet og en dør med høj kapacitet. Ved den første type vil gangen have en højere kapacitet end døren. Her vil mange mennesker kunne komme hen til en nødudgang, men pga. dørens lave kapacitet vil der opst˚ a en flaskehals-situation. Her kunne det ske, at de flygtende ville trampe hinanden ned. Med den anden type vil dørens kapacitet kunne rumme flere af de flygtende mennesker. Vi vil derfor ikke f˚ a flaskehals-problemet, som ved den forrige løsning. Er denne løsning s˚ a bedre? De flygtende vil m˚ aske ikke trampe hinanden ned i selve udgangen, men der er derimod en fare for, at det vil ske i gangen med den lave kapacitet. Alts˚ a er typen, hvor vi har en gang med lavere kapacitet være lige s˚ a d˚ arlig som den første type. Dog kan man sige, at s˚ adan et design aldrig vil forekomme, hvor døren har en højere kapacitet end den gang, der fører hen til den. Vi vil derfor kun koncentrere os om den første type og vil definere kapaciteten af flugtvejen som kapaciteten af de døre, man g˚ ar igennem. Det kan ikke udelukkes, at gangenes kapacitet har betydning for den optimale rute, men vi har valgt at se bort fra det. 40 Kapitel 10 Brugervenlighed Vi mener det er vigtigt, hvis programmet blev en realitet, at det er nemt at bruge. Med nemt at bruge mener vi at det skal være simpelt at starte, som i tryk p˚ a en knap, og det skal kunne bruges uden at have modtaget undervisning p˚ a forh˚ and. Grunden til vi mener dette er fordi arkitekterne skal have kunstnerisk frihed, det er i forvejen ikke den samme fri hed ved at skitsere p˚ a computer som man har i h˚ anden, derfor bør vores program ikke være med til at gøre det yderligere kompliseret. Vi mener det er en god ide at det kan bruges uden at have haft undervisning da arkitekterne derfor ikke skal bruge tid p˚ a at tage p˚ a kurser eller forlænge den nuværende uddanelse, og derved tage fokus fra det de reelt vil arbejde med. 41 Litteratur [1] A. Matthes. [Online]. Available: http://altermundus.com/downloads/ examples/graph/Complet-16.png [2] J. Wiley, “Fire and materials.” [Online]. Available: http://www3. interscience.wiley.com/journal/71000844/issue [3] L. Winerman, “Fightin fire with psycholology.” [Online]. Available: http://www.apa.org/monitor/sep04/fighting.aspx [4] R. H. PHD, “Herd mentality explained,” 2008. [Online]. Available: http:// psychcentral.com/news/2008/02/15/herd-mentality-explained/1922.html [5] U. Andersen, “H˚ an, r˚ ab og hurtigt arbejde.” [Online]. Available: http://ing.dk/artikel/81316-haan-raab-og-hurtigt-arbejde [6] Smartdraw, “Smartdraw smartdraw.com/ 2010.” [Online]. Available: http://www. [7] Google, “Google sketch-up.” [Online]. Available: http://sketchup.google. com/ [8] K. H. Rosen, Discrete Mathematics and Its Applications Sixth Edition. McGraw-Hill, 2007. [9] C. E. Leiserson, “Introduction to algorithms, lecture 18.” [Online]. Available: http://www.cs.arizona.edu/classes/cs445/spring05/ShortestPath2. prn.pdf [10] M.-Y. Kao, Encyclopedia of Algorithms. LLC, 2008. [11] J.-C. Fournier, Graph Theory and Applications. John Wiley and Sons Inc, 2009. [12] R. Sedgewick, Algorithms in Java Third Edition Part 5: Graph Algorithms. Addison Wesley, 2003. [13] P. Symonds, “floyds[1].” [Online]. Available: http: //www.excellencegateway.org.uk/media/ferl and aclearn/ferl/resources/ colleges/petersymonds/filedownload/dhand/floyds/floyds[1].ppt 42 Bilag A Spørgsm˚ al fra interview: 1. Hvilke faktorer tager I højde for n˚ ar I tegner en bygning? 2. Tager i højde for flugtveje? Hvordan tager I højde for det? 3. Hvilke love og retningslinjer overvejer i? Og hvorfor? Hvorfor netop dem? Er det alle retningslinjer omkring flugtveje, eller er der nogle I kan fravælge? 4. Er det nogensinde sket at I har tegnet en bygning og brandmyndighederne har afvist den? Og hvorfor? 5. Hvad gør I for at forhindre dette? 6. Laver i beregninger p˚ a flugtruter og evakueringstider? Og hvordan gør I det? 7. Føler i nogensinde at det er nødvendigt at g˚ a p˚ a kompromis for at sikre flugtruter? 8. Føler i at lovgivningen er for stram eller burde ændres? P˚ a hvilke omr˚ ader og hvorfor? 9. Hvor meget og hvordan arbejder I sammen med brandmyndighederne? 10. Der findes en del værktøjer til udregning af optimale flugtveje (her kan I godt nævne et par eksempler), er det nogle I benytter jer af? 11. Hvis ja, hvad hedder dette program, og hvorfor har I valgt at bruge det? 12. Hvilke forbedringer kunne I ønske jer af programmet? 13. Hvis nej, har I overvejet dette? Og hvorfor bruger I ikke et værktøj? 14. Hvad skulle et program minimum kunne afhjælpe for at I ville bruge det? 15. Overvejer I menneskelig psykologi og adfærd ved krisesituationer, n˚ ar I tegner bygninger? Og hvordan? 43 Bilag B Interviewet Her vedlægges transcriptionen af selve interviewet. Det har været svært at f˚ a alle ting med pga. d˚ arlig lydkvalitet. Intervieweren: Hvilke faktorer tager I højde for n˚ ar i tegner en bygning? Jan Refsgaard Jepsen: Hvilke faktorer? Intervieweren: Ja i forhold til flugtveje og s˚ adan noget? Jan Refsgaard Jepsen: Jamen der tager vi udgangspunkt i bygningsreglementets krav. Til hvor langt der skal være mellem rammerne hvor brede gangene skal være, det er afhængigt af om det er et sygehus eller et forsamlingslokale eller en bolig eller hvad det er. Intervieweren: Hvad for nogle faktorer kan der være n˚ ar man skal lave s˚ adan nogle flugtveje? Jan Refsgaard Jepsen: Som regel er det afstanden mellem trapperne hvis det er et sygehus og der er nogle specielle forhold der gør sig gældende som f.eks. trapper. Intervieweren: Er det tit s˚ adan i tager højde hvis nu det er s˚ adan der er et sted p˚ a en gang der er smallere, s˚ a der tit kunne være en flaskehals hvor der bliver proppet? Jan Refsgaard Jepsen: Næh... der er jo minimumskrav for bredder. 44 Intervieweren: Ja okay. Jan Refsgaard Jepsen: og n˚ ar den er opfyldt s˚ a er det okay. Intervieweren: Hvad er det for nogle minimumskrav? Jan Refsgaard Jepsen: ja jeg mener det er minimum 1 meter og 30. Intervieweren: Hvilke regler og retningslinjer overvejer I? Jan Refsgaard Jepsen: Alts˚ a i forbindelse med det? Intervieweren: Ja.. Jan Refsgaard Jepsen: I mange af vores projekter, som er større projekter, er der som regel en brandingeniør med, som tager hele den der forhandling med brandmyndighederne, og skal lægge s˚ adan en brandstrategi. Man kan handle lidt p˚ a de der emner; hvis man opfylder nogle ting bedre end andre s˚ a kan man m˚ aske slække lidt p˚ a nogle andre omr˚ ader. Intervieweren: Har I nogensinde tegnet en bygning hvor brandmyndighederne har afvist den eller s˚ adan noget? Jan Refsgaard Jepsen: Nej, det har vi ikke. Intervieweren: S˚ a der er egentlig rimelig store.. Jan Refsgaard Jepsen: Ja, det vil sige, tidligere kom man med en række forslag, til hvordan flugtvejene var og s˚ a gik vi ned til brandmyndighederne og handlede det af med dem. Intervieweren: Er det nogle meget ˚ abne krav der er? Jan Refsgaard Jepsen: Det er s˚ adan rimelig billigt og aflæse bygningsreglementet hvordan det skal være, alts˚ a de kan jo tolkes p˚ a mange m˚ ader og det kan ogs˚ a være at brandvæsnet har nogle andre forhold. Intervieweren: Du sagde at det var det i gjorde tidligere? 45 Jan Refsgaard Jepsen: Ja, i dag kræver de jo endnu mere at der er en brandstrategi, det er ikke nok at der er en flugvejsplan, s˚ a skal der være en brandstrategi, der skal være en strategi for hvor mange folk der er i huset. Man skal ogs˚ a nogle gange lave en CFD alts˚ a en flugtvejsanalyse. I kender godt de programmer hvor man sætter s˚ a og s˚ a mange mennesker ind i alle rummene og siger udgangen den er herovre. Hvor lang tid det tager det s˚ a at komme ud. Intervieweren: Det er faktisk lidt præcist det vi forsøger at lave Intervieweren: Nu er vi jo meget interesserede i at finde flugtveje, hvad gør I for s˚ adan noget alts˚ a i forhold til evakueringstid. Jan Refsgaard Jepsen: Det gør vi i samarbejde med ingeniørene, men hvis det er mindre sager kan vi gøre det p˚ a den gode gammeldags m˚ ade, køre ned til brandmyndighederne, men hvis det er en større sag vil brandmyndighederne ikke acceptere det. S˚ a skal der dokumentation p˚ a det. Intervieweren: Har I nogensinde følt i har været nødsaget til at g˚ a p˚ a komprimis med noget for at sikre flugtveje, det kunne f.eks. være design. Jan Refsgaard Jepsen: Nej det mener jeg ikke. Intervieweren: Det virker p˚ a os at lovgivningen ikke er s˚ a stram p˚ a dette omr˚ ade, men hvad mener du, er lovgivningen for stram, burde den ændres p˚ a nogle omr˚ ader. Jan Refsgaard Jepsen: Nej... Jeg kan ikke sige om den er for stram, det tror jeg sgu ikk den er. Intervieweren: Den er meget godt tilpasset eller hvad? Jan Refsgaard Jepsen: Ja, den bliver jo justeret hele tiden. N˚ ar tingene sker rundt omkring, ulykker osv. s˚ a bliver den jo tilpasset. Det er selvfølgelig tragisk at der skal ske ulykker før lovgivningen bliver strammet op. Intervieweren: Hvor meget arbejder i egentlig sammen med brandmyndighederne? 46 Jan Refsgaard Jepsen: Dem arbejder vi tit sammen med, og for eksempel musikens hus vi lige har sendt ud her, der holder vi løbende møder hver m˚ aned, hvor brandvæsnet ogs˚ a er inviteret med. Ogs˚ a under skitseringsforløbet. Intervieweren: Der findes en del værktøjer til at udregne optimale flugtveje som f.eks. ArchiCAD 13 og SmartDraw 2010 og Google SketchUp. Hvilke benytter I, og hvorfor? Jan Refsgaard Jepsen: Google SketchUp.. Det er almindelige CAD programmer du tænker p˚ a, ik’ ? Intervieweren: Jo, jeg har ikke kigget p˚ a dem. Jan Refsgaard Jepsen: Jamen der bruger vi Revit fra autodesk og autodesk ACA fra men ogs˚ a lidt google, men det er mest i skitseringsfasen. Intervieweren: Ok. Jan Refsgaard Jepsen: Til Revit der ved jeg der kan f˚ as et overbygningsprogram til at lave evakueringsløsninger. Intervieweren: Kan de udregne optimale flugtveje? Jan Refsgaard Jepsen: Jeg har ikke set det i brug, jeg har bare hørt det er kommet. Intervieweren: Er det noget i gør, alts˚ a udregner optimale flugtveje? Jan Refsgaard Jepsen: Nej alts˚ a vi har ikk nogle programmer der g˚ ar ind og finder ud af det. Vi tegner ud fra de krav der er til flugtveje. Intervieweren: Er det relevant med s˚ adan et program der kan finde optimale flugtveje? Tror du det er noget i kunne bruge? Jan Refsgaard Jepsen: Alts˚ a hvis det kan lave de der CFD analyser hvor man kan se evakueringstider, s˚ a kunne vi selv lave de der brandstrategier. 47 Intervieweren: Hvilke ting skulle der være i det, udover den skal kunne regne hvor lang tid det skulle tage. For eksempel kunne den beregne hvor mange mennesker der kunne kunne komme ud p˚ a et vist antal tid. Jan Refsgaard Jepsen: Ja, det ville stort set ville være det den skal. Intervieweren: Overvejer i n˚ ar I tegner s˚ adan nogle bygninger, menneskelig psykologi og adfærd og s˚ adan noget ved krisesituationer. Jan Refsgaard Jepsen: Jamen det gør vi da, specielt p˚ a sygehuse, der er man jo nødt til at tage hensyn til sengeliggende patienter, finde ud af hvordan og hvorledes de kommer op og ned af trapper. Det skal der selvfølgelig ogs˚ a tages højde for i det program hvis det skal bruges til det. 48 Bilag C Vigtige ord og begreber C.1 Grafteori • Dræn - En kant som symboliserer udgange, n˚ ar en eller flere personer har n˚ aet denne knude er de ude af bygningen. • Ikke-orienteret graf - En graf hvor kanterne ikke er retningsbestemte. • Kapacitet - Hvor mange mennesker der kan bevæge sig langs en kant. • Kanter E - Forbinder en eller flere knuder. Kaldes p˚ a engelsk Edges. Se punkt 2.1.2. • Kilder - En knude hvor folk opholder sig ved starten af branden. • Knuder V - Et sted folk kan opholde sig. Kaldes p˚ a engelsk Vertices. se punkt 2.1.1. • Længde - Hvor lang en kant er. • Orienteret graf - En graf hvor kanterne er retningsbestemte. • Vægt - En værdi der kan tilknyttes en kant. Kan bruges til at beskrive tider, længder osv. • Vægtet graf - En graf hvor alle kanterne har en eller flere vægte. • Vej - En sekvens af kanter. C.2 tidskompleksitet • operationer C.3 O-notation • Algoritme - En følge af operationer som kan løse et specifikt problem [8]. 49 • Hukommelsesforbrug - I denne sammenhæng er det, hvor meget plads i hukommelsen der er brugt efter en algoritme at kørt. • Udførelsestid - I denne sammenhæng er det, hvor lang tid det tager for algoritmen at køre. • Øvre grænse - Maksimumsværdien af algoritmens vækstrate. • Underestimering - Minimumsværdien af algoritmens vækstate. 50
© Copyright 2024