Simulace leteckých dopravců

Tato stránka slouží jako výzkumná zpráva simulace "Simulace leteckých dopravců" k semestrálnímu projektu pro předmět 4IT495 Simulace systémů (LS 2014/2015) na VŠE v Praze.


 * Název simulace: Simulace leteckých dopravců


 * Předmět: 4IT495 Simulace systémů (LS 2014/2015)


 * Autor: Bc. Alois Sečkár, xseca00


 * Typ modelu: Multiagentní


 * Modelovací nástroj: Netlogo 5.2

=Definice problému=

Simulace znázorňuje několik evropských měst (vybráno 20 měst, většinou hlavních s výjimkou Zürichu a Istanbulu, které byly upřednostněny kvůli velikosti) a imaginární letecké dopravce v pěti z nich (Londýn, Paříž, Řím, Berlín a Istanbul). Ve městech se generují cestující a úkolem dopravců je tyto cestující přepravovat a generovat tak zisk. Omezeni jsou počtem možných cestujících se zájmem o přepravu a náklady na pořízení a provoz stroje.

Model má sledovat letecké dopravce a jimi generovaný zisk.

=Vstupní data=

Vstupem byla tabulka měst s GPS souřadnicemi, počtem obyvatel a vypočteným indexem atraktivity.

Reálné GPS souřadnice byly zaokrouhleny na celé stupně. Poté normalizovány, aby mohla být města jednoduše rozmístěna do plochy simulace (k délce bylo přičteno 10, od šířky odečteno 35). Pro propočty kilometrových vzdálenosti byl následně stanoven koeficient "1 čtverec plochy = 80 km", na základě porovnání reálných vzdáleností (http://www.mapcrow.info/) s výsledky dle umístění v simulaci. Vzorek 10 náhodných srovnání ukázal na průměrnou odchylku od reality kolem 13% (s výrazným extrémem 42% u vzdálenosti Praha - Berlín). Většinou dochází k podhodnocení vzdálenosti.

Počet obyvatel byl čerpán z mezinárodní internetové encyklopedie Wikipedia, která dále referuje na poslední provedená sčítání lidu. Do úvahy byl vždy brán údaj vztahující se k rozšířené ("metropolitan") oblasti, protože u všech obyvatel spádové oblasti je pravděpodobné, že pokud kdy budou cestovat letecky, tak přes letiště v daném městě. Údaj byl vždy zaokrouhlen na tisíce.

"Index atraktivity" byl stanoven jako umělá hodnota z údajů o počtu obyvatel, počtů turistů za rok v dané zemi (zdroj: http://data.worldbank.org/indicator/ST.INT.ARVL, data o počtech cestujících na konkrétních letiších bohužel nejsou k dispozici zdarma) a cenového indexu ve městech (zdroj: http://www.expatistan.com/cost-of-living/index). Počet obyvatel a turistů atraktivitu zvyšuje (přičemž počet turistů je brán jako lehce významnější než počet obyvatel, protože sice to jsou turisté za celou zemi a nejen za dané město, ale místní obyvatelé města jsou zase více usedlí a letiště často vůbec nevyužijí), vyšší hodnota cenového indexu naopak snižuje (není zájem do drahého města cestovat). Konstanta 10000 normalizuje číslo do rozumných hodnot v intervalu zhruba 0-30. Některé hodnoty tohoto indexu jsou diskutabilní (např. 22.74 u Istanbulu, který je poměrně levný, zároveň velmi lidnatý a v zemi s velkým počtem turistů), nicméně představuje způsob porovnání založený na reálných číslech. Hodnoty by šly upravit například pomocí přidání jakési "subjektivní" složky, která by například Paříž či Lodnýn před Istanbulem zvýhodnila, ale už by nešlo o fakta, ale dojmy.

Jako referenční stroj byl zvolen Airbus A320 jakožto jeden z nejrojzříšenějších typů letadel v Evropě, díky menší velikosti a cenové dostupnosti.

=Model=

Předpoklady a omezení

 * Jedno letadlo představuje jednu linku (let) mezi dvěma městy. Letadla kontinuálně létají sem a tam.
 * Existuje jen 20 měst.
 * Vzálenosti mezi městy nejsou vždy zcela přesné (odchylka od reality v průměru 10-15%).
 * Jsou zanedbány atmosférické, váhové a jiné vlivy na spotřebu paliva a náklady.
 * Všechna letadla jsou stejného typu a mají stejné vlastnosti.
 * Index atraktivity dle zvolené metodiky plně nekoresponduje s realitou.
 * Cestující nerozlišují destinaci, letadlo jich vždy může nabrat tolik, kolik jich na letišti je až do své maximální kapacity.

Nastavení

 * plane-capacity - kapacita stroje (Airbus A320)
 * plane-fix-costs - fixní náklady na let (hrubý odhad, v $)
 * plane-var-costs - variabilní náklady na 1 km v $ (http://planes.axlegeeks.com/l/230/Airbus-A320)
 * plane-duration - výdrž letadla do odepsání pro stáří (v km)
 * plane-price - nákupní cena letadla (dle cen A320)

Monitoring

 * total-flights - počet letů celkem
 * total-loss-flights - počet letů, které skončily ztrátou (náklady převýšily zisk z letenek)
 * total-unloaded-flights - počet letů zaplněných méně než z 90%
 * generated-planes - počet koupených letadel
 * scrapped-planes - počet odepsaných letadel (ztrátové nebo málo naplněné)
 * retired-planes - počet odepsaných letadel (vysloužilé)

Ostatní slouží pouze k předávání dat mezi procedurami (city-x city-y city-name city-color travel-demand)modelů

Entity modelu

 * Cities - jednotlivá města (grafický tvar "dům")
 * Planes - jednotlivá letadla (grafický tvar "letadlo")

Vlastnosti entit

 * Cities
 * name - jméno
 * xcoord ycoord - souřadnice na mapě (viz vstupní data)
 * population - počet obyvatel (viz vstupní data)
 * atractivity - index atraktivity (viz vstupní data)
 * city-passangers - cestující ve městě
 * city-revenues - zisk místní letecké společnosti v $ (smysl má pouze u 5 vybraných měst)
 * Planes - jednotlivá letadla
 * init - pouze technická proměnná, aby se založení stroje ihned nezapočítalo jako dokončení letu
 * home-x home-y home-name - údaje o domovském městě
 * target-x target-y target-name - údaje o cílovém městě linky
 * flight-length - délka trasy v KM
 * passangers - počet cestujících
 * profit - celkový zisk (ztráta)
 * loss-count - počet letů ve ztrátě (5 -> odepsání stroje)

Procedury
to setup __clear-all-and-reset-ticks ;; set global variable settings set plane-capacity 150 ;; airbus A320 set plane-fix-costs 100000 ;; maintenance etc. (rough estimation) set plane-var-costs 11.64 * 0.54 ;; fuel consumption cost per nautical mile = http://planes.axlegeeks.com/l/230/Airbus-A320 ;; 1 km = 0.54 nautical mile set plane-duration 500000 ;; kilometers before being scrapped set plane-price 50000000 ;; in $ ;; paint world ask patches [ set pcolor white; ] ;; paint cities set-default-shape turtles "house" setup-cities ;; prepare for painting planes set-default-shape turtles "airplane" end
 * setup

Nastavení simulace. Nastavení globálních proměnný, přebarvení polí, v proceduře "setup-cities" nastavení vlastností jednotlivých měst.

to setup-cities ;; create 20 cities create-cities 20 [set color one-of base-colors] ;; setup values for every city ask city 0 [ set name "London" set xcoord 10 set ycoord 16 setxy 10 16 set population 13614000 set atractivity 8.27 ] { ... }
 * setup-cities
 * prepare cities

;; generate initial number of passangers to cities ask cities [ set city-passangers (round(random-normal (atractivity * 50) (200 / atractivity))) ] end

Nastavení hodnot atributů pro jednotlivá města, následně vygenerování náhodného výchozího počtu cestujících.


 * add-plane

to add-plane create-planes 1 [ ;; set origin into according to set-up globals set home-x city-x set home-y city-y set home-name city-name set color city-color ;; place plane to origin city setxy home-x home-y ;; set initial marker - so it doesn't count flight costs for the first time set init true ;; set how long the plane will last (kilometers) set duration plane-duration ;; set random destination - must be different from origin while [flight-length < 1] [ select-target-city ;; set target info set target-x city-x set target-y city-y set target-name city-name ;; elaborate distance of the flight set flight-length round(sqrt(((home-x - target-x)*(home-x - target-x)+((home-y - target-y)*(home-y - target-y))))) * 80 ;; 80 is squares-to-kilometers factor ]   ;;set plane heading to destination facexy target-x target-y ] ;; upgrade global marker set generated-planes (generated-planes + 1) end
 * add new plane into simulation

Vyvtoření nového letadla. Nastavení a umístění do výchozího města, poté náhodný výběr cílového města a nastavení trasy.

to select-target-city ask one-of cities [ ;; set global variables set city-x xcoord set city-y ycoord set city-name name set city-color color ] end
 * select-target-city
 * pick one random citiy

Náhodně vybere jedno město a nastaví jeho vlastnosti do pomocných globálních proměnných pro předání nově se vytvářející entitě typu "plane".

to step ;; handle planes movement fly ;; handle possible plane generation generate-planes ;; handle passanger generation generate-passangers ;; tick if ticks >= 100000 [ stop ] ;; stop simm after 100k ticks end
 * step
 * one simulation step

Jeden krok simulace. Procedura "fly" pohybuje letadly, "generate-planes" zvažuje vytvoření nových letadel a "generate-passangers" vyvtváří ve městech čekající cestující.


 * fly

to fly ask planes [ ;; move planes +0.1 towards current direction jump 0.1 ;; check if plane didn't reach its destination ;; it needs to be APPROX at the cooridnates, not exactly on them let finish 0 ;; check for target city if ((abs (xcor - target-x) < 0.1) AND (abs (ycor - target-y) < 0.1) ) [ ;; the initial phase is over set init false ;; plane reached target destination set finish 2 ]   ;; check for home city if ((abs (xcor - home-x) < 0.1) AND (abs (ycor - home-y) < 0.1)) [ ;; plane reached home destination set finish 1 ]   ;; if some action should be taken if ((finish > 0) AND (init = false)) [ ;; set variables for searching for specific city let match-home home-name let match-target target-name ;; increase total flights made set total-flights (total-flights + 1) ;; count profit/loss from flight let income (passangers * 2.5 * flight-length) let costs (plane-fix-costs + plane-var-costs * flight-length) let outcome (income - costs) ;; check if plane isn't unprofitable and unloaded ;; plane is allowed to be unprofitable/unloaded for couple of times... ifelse (outcome < 0) [ set loss-count (loss-count + 1) set total-loss-flights (total-loss-flights + 1) ] [ set loss-count 0 ] ifelse (passangers < (plane-capacity * 9 / 10)) [ set unloaded-count (unloaded-count + 1) set total-unloaded-flights (total-unloaded-flights + 1) ] [ set unloaded-count 0 ] ;; kill plane if needed if ((loss-count >= 5) OR (unloaded-count >= 10)) [ set scrapped-planes (scrapped-planes + 1) ask cities [ if (name = match-home) [ set city-planes (city-planes - 1) ]         ]        die ]     ;; adjust plane duration set duration (duration - flight-length) if (duration <= 0) [ set retired-planes (retired-planes + 1) ask cities [ if (name = match-home) [ set city-planes (city-planes - 1) ]         ]        die ]     ;; elaborate passangers let seats plane-capacity ask cities [ ;; find home city and add profits if (name = match-home) [ set city-revenues (city-revenues + outcome) ]       ;; find current city and get travel demand if (((finish = 1) AND (name = match-target)) OR ((finish = 2) AND (name = match-home)))[ ifelse (city-passangers >= seats) [ set city-passangers (city-passangers - seats) ] [ set seats city-passangers set city-passangers 0 ] ]     ]      set passangers seats ;; set off to other city ifelse (finish = 2) [ facexy home-x home-y ] [ facexy target-x target-y] ] ] end
 * plane movement

Pohne všemi existujícími letadly. Pokud se objeví v jednom z cílových měst, ukončí a vyhodnotí let a zahájí let zpět.


 * generate-passangers

to generate-passangers ask cities [ ;; protect from division by zero let pass city-passangers if (pass = 0) [ set pass 1 ] ;; count index from population and atractivity let passanger-index ((population * atractivity) / 2000000) ;; generate random amount of new passangers let new-passangers round((random-normal 1 0.7) * passanger-index) ;; some of waiting passagers dont want to wait let left-passangers round(random-normal (city-passangers / 15) 10) ;; adjust amount set city-passangers (city-passangers + new-passangers - left-passangers) if (city-passangers < 0) [ set city-passangers 0 ] ] end
 * passanger generation

Pro všechna města vypočte index cestujících založený na populaci města a indexu atraktivity a poté náhodně vygeneruje počet nových cestujících a přidá je do města.


 * generate-planes

to generate-planes ;; initially - DON'T add anything let addplane false ;; select one of possible cities (London, Paris, Rome, Berlin, Istanbul) let rand random(5) ask city rand [ ;; decide whether to buy or don't buy new plane ;; are there enough ppl waiting? ;; do we have enough money? ;; ain't we have enough planes already? ;; random factor... if (city-passangers >= passangers-level) [ set rand ((city-revenues / 1000000) + random(city-risk-desire) - random(city-planes * 2) - random(75)) if (rand > 0) [ ;; set initial variables for plane set city-x xcoord set city-y ycoord set city-name name set city-color color ;; "buy" new plane set city-revenues (city-revenues - plane-price) set city-planes (city-planes + 1) ;; add-plane marker set addplane true ]   ]  ]  ;; if decision was made - add new plane if (addplane = true) [ add-plane ] end
 * plane generation

Sledovaná města vyhodnocují situaci a mohou se rozhodnout nakoupit nové letadlo na novou linku.

Grafické prvky

 * Tlačítka pro nastavení simulace a zahájení provozu.
 * Monitory zisku sledovaných města a počtu čekajících pasažérů v nich.
 * Monitory počtu letadel (vyrobených/odepsaných/vyřazených) a počtu letů (celkem/ztrátových/neobsazených).
 * Posuvníky k nastavení parametrů sloužících při rozhodování o pořízení nového letadla (počet čekajících cestujících, při kterém stojí za to uvažovat o dalším stroji + sklon k zadlužování se (půjčky na nákup nového letadla)

=Výsledky= Bylo provedeno několik průběhů simulací s 100k kroky (ticks) s odlišným nastavením parametrů passangers-level (kdy začne město uvažovat o novém letadlu) a risk-desire (kolik jsou města ochotná se zadlužit).


 * passangers-level = 1000; risk-desire = 100;
 * Zakoupeno 124 letadel, 101 v provozu, 1 zrušeno, 22 odepsáno
 * Celkem 29238 letů, 5608 ztrátových, 8775 neobsazených
 * Čekající pasažéři: Londýn 433, Paříž 1735, Řím 680, Berlín 381, Istanbul 2480
 * Řím a Berlín nezakoupily ani jedno letadlo


 * passangers-level = 1000; risk-desire = 25;
 * Zakoupeno 74 letadel, 66 v provozu, 0 zrušeno, 8 odepsáno
 * Celkem 13514 letů, 1709 ztrátových, 3298 neobsazených
 * Čekající pasažéři: Londýn 810, Paříž 1653, Řím 460, Berlín 430, Istanbul 1952
 * Řím a Berlín nezakoupily ani jedno letadlo


 * passangers-level = 1000; risk-desire = 500;
 * Zakoupeno 383 letadel, 305 v provozu, 1 zrušeno, 77 odepsáno
 * Celkem 94131 letů, 18639 ztrátových, 29287 neobsazených
 * Čekající pasažéři: Londýn 562, Paříž 1303, Řím 523, Berlín 379, Istanbul 1395
 * Řím a Berlín nezakoupily ani jedno letadlo


 * passangers-level = 300; risk-desire = 100;
 * Zakoupeno 197 letadel, 156 v provozu, 4 zrušeno, 37 odepsáno
 * Celkem 46044 letů, 7820 ztrátových, 13262 neobsazených
 * Čekající pasažéři: Londýn 679, Paříž 1881, Řím 214, Berlín 67, Istanbul 1436


 * passangers-level = 300; risk-desire = 500;
 * Zakoupeno 537 letadel, 362 v provozu, 62 zrušeno, 113 odepsáno
 * Celkem 126658 letů, 25971 ztrátových, 47213 neobsazených
 * Čekající pasažéři: Londýn 633, Paříž 2165, Řím 364, Berlín 157, Istanbul 907


 * passangers-level = 2000; risk-desire = 500;
 * Zakoupeno 323 letadel, 255 v provozu, 7 zrušeno, 61 odepsáno
 * Celkem 69485 letů, 10632 ztrátových, 21025 neobsazených
 * Čekající pasažéři: Londýn 842, Paříž 1183, Řím 446, Berlín 166, Istanbul 1367
 * Londýn, Řím a Berlín nezakoupily ani jedno letadlo. Istanbul výrazně v zisku (583 mil. $)


 * passangers-level = 2000; risk-desire = 25;
 * Zakoupeno 33 letadel, 28 v provozu, 0 zrušeno, 5 odepsáno
 * Celkem 4804 letů, 735 ztrátových, 1543 neobsazených
 * Čekající pasažéři: Londýn 868, Paříž 2053, Řím 502, Berlín 359, Istanbul 1785
 * Londýn, Řím a Berlín nezakoupily ani jedno letadlo.

=Zhodnocení= Bohužel musím na rovinu přiznat, že jsem se v simulování ztratil a utopil. Nepodařilo se mi sestavit model takový, aby působil reálně. Hlavní problém byl v mechanismu pořizování nových letadel (města jich často koupí nesmyslně mnoho) a vztahu nákladů a výnosů z letů (i poloprázdné letadlo vydělává). Model také již sám o sobě příliš abstrahuje od reality (tvorba cestujících, náklady na let, apod.)

Výsledkem je tak spíše hříčka demonstrující program NetLogo než cokoliv jiného. Nicméně doufám, že úplně k ničemu práce nebyla a že půjde alespoň nějak ohodnotit, byť nečekám mnoho bodů :(

=Kód=
 * [[File:Airlines.nlogo]]

= Reference =