„MATSim” változatai közötti eltérés
Mate (vitalap | szerkesztései) (→A MATSim elindítása) |
|||
(6 közbenső módosítás, amit egy másik szerkesztő végzett, nincs mutatva) | |||
49. sor: | 49. sor: | ||
A szoftver automatikusan felismeri a gépünkön futó Java verzióját és könyvtárát. Amennyiben ez nem történt meg, tallózzuk be a könyvtárat, ahol a JRE könyvtárunkat. A MATSim futtatásához legalább 7-es verziójú Java szükséges. | A szoftver automatikusan felismeri a gépünkön futó Java verzióját és könyvtárát. Amennyiben ez nem történt meg, tallózzuk be a könyvtárat, ahol a JRE könyvtárunkat. A MATSim futtatásához legalább 7-es verziójú Java szükséges. | ||
− | A MATSim futtatásához be kell tallózzunk egy konfigurációs filet, minden beállítható paraméterünket ez fogja tartalmazni. A letöltött csomag több példakonfigurációt is tartalmaz, ezeket megtaláljuk az ''example'' mappában. Amennyiben a programunk elindítás után hibát dob, abban az esetben nyissuk meg a konfigurációs fájlt és az abban megadott ''network'' és ''plans'' modulok elérhetőségi útját módosítanunk kell, a megadott elérési út | + | A MATSim futtatásához be kell tallózzunk egy konfigurációs filet, minden beállítható paraméterünket ez fogja tartalmazni. A letöltött csomag több példakonfigurációt is tartalmaz, ezeket megtaláljuk az ''example'' mappában. Amennyiben a programunk elindítás után hibát dob, abban az esetben nyissuk meg a konfigurációs fájlt és az abban megadott ''network'' és ''plans'' modulok elérhetőségi útját módosítanunk kell, a megadott elérési út helyett teljes, abszolút elérési utat adjunk meg. Ennek az az oka, hogy a szotfver alapértelmezetten a Java könyvtárunkhoz képest relatívan értelmezi a konfigurációs file-ban hivatkozott egyéb elérési útvonalakat, nem pedig a konfigurációs filehoz képest. |
A program paramétereit a konfigurációs fájlokban állíthatjuk be. | A program paramétereit a konfigurációs fájlokban állíthatjuk be. | ||
156. sor: | 156. sor: | ||
</population> | </population> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | == Vizualizáció == | ||
+ | A MATSim outputjának vizualizációjához mindenképpen third-party könyvtárakat kell használjunk. A fejlesztők az OTFVIS-t javasolják, így itt is azt mutatjuk be röviden. | ||
+ | |||
+ | Az OTFVIS elvileg letölthető [http://matsim.org/files/builds/ a MATSim nightly (nem stabil) buildeket tartalmazó könyvtárából], mi itt azonban hosszas keresgélés után sem találtuk. Amennyiben a későbbiekben sem található itt meg, úgy alternatívának javasoljuk [https://github.com/matsim-org/matsim/releases a matsim projekt github oldalát]. | ||
+ | |||
+ | Felhívjúk rá a figyelmet, hogy az OTFVIS futtatása sok memóriát vehet igénybe, így célszerű a megfelelő Java beállításokkal elindítani, például legalább 500MB-tal. A parancs struktúrája Windowson a következő: | ||
+ | <syntaxhighlight> | ||
+ | java -Xmx500m -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis arguments | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Amennyiben Linux-on szeretnénk futtatni, úgy a pontosvesszőt cseréljük le kettőspontra. | ||
+ | |||
+ | === Snapshotok készítése és megjelenítése === | ||
+ | Snapshotok készítését a következő példaparancshoz hasonló utasításokkal tudjuk elvégezni: | ||
+ | <syntaxhighlight> | ||
+ | java -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis -convert output/50.events.txt.gz input/network.xml.gz output/50.visualization.mvi 300 | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A <code>-convert</code> utasítás után megadhatjuk a MATSim output file-ját, az input hálózatot, majd a file-t amibe szeretnénk elmenteni a snapshotot (ezt .mvi kiterjesztéssel tehetjük meg), valamint a snapshotok időtartamát másodpercekben. Tehát a fenti példaparancs ötpercenként fog egy snapshotot készíteni a hálózatunkról, és ezt elmenti egy .mvi fájlba, amit aztán megjeleníthetünk, a következő módon: | ||
+ | <syntaxhighlight> | ||
+ | java -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis output/50.visualization.mvi | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Interaktív szimuláció === | ||
+ | Az OFTVIS-t lehet használni interkatív szimulációra. Megjegyezzük, hogy a program képességei korlátozottak. | ||
+ | |||
+ | Fontos tudni, hogy ebben az esetben az összes adatot (hálózat, populáció, stb) be kell tölteni a memóriába. Bár hardveres gyorsítást (OpenGL) használ, az igazán nagy fájlokkal így is akadhatnak gondok. | ||
+ | |||
+ | Ahhoz, hogy interaktív szimulációt indítsunk, nincs más dolgunk mint átadni az OTFVis-nek a konfigurációs fájlt amit egyébként a MATSimnek adnánk inputként. A következő egy lehetséges példahívás az interkatív vizualizálóra: | ||
+ | <syntaxhighlight> | ||
+ | java -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis input/config.xml | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Az implementációról szóló részben mutatunk példát arra, hogy hogyan futtathatjuk a saját programunkból az OFTVis-t, és hogyan fog kinézni a végeredmény. | ||
+ | |||
+ | == Fejlesztői használat == | ||
+ | Ebben azokat az információkat mutatjuk be, amiket szükséges tudnunk ha szeretnénk a saját programunkban használni a MATSim-et. A MATSim könyvtárat letölthetjük a [http://matsim.org/downloads projekt honlapjáról] vagy akár a [https://github.com/matsim-org/matsim/releases projekt github oldaláról is]. Azért javasoljuk az utóbbit, mert itt számos egyéb kiterjesztése is megtalálható, vagy hasznos third party libraryk, mint például a vizualizációhoz használható OFTVis. | ||
+ | |||
+ | A MATSim moduláris felépítésű, de a fejlesztői által a modul nem egy precízen definiált fogalom: felhasználók által készített kiegészítések (úgynevezett contrib-ek, contribution-ök), opcionális elemek és a MATSim fontos, belső egységei (például a pontozás) is egy-egy modulnak számít. A MATSim teljes architektúráját az összes modullal a következő ábra foglalja össze: | ||
+ | |||
+ | [[Fájl:Matsim_Teljes_Architekt%C3%BAra.jpg]] | ||
+ | |||
+ | A fenti ábra elég szerteágazó és sajnos a legtöbb eleméhez nem tartozik semmilyen dokumentáció. Ellenben nem minden itt felsorolt modult kötelező konfigurálni: némelyik opcionális (mint például az előző részben bemutatott OTFVis), mások pedig rendelkeznek alapértelmezett értékkel (mint például a pontozás, vagyis scoring). | ||
+ | |||
+ | === A MATSim használatának általános váza === | ||
+ | A fenti ábra komplikáltságához képest a MATSim saját programból való próbafuttatása kevésbé bonyolult. Amennyiben a MATSim-et csak használni szeretnénk, úgy a következő általános váza legyen a programunknak: | ||
+ | * Példányosítsuk a Config osztályt a konfigurációs xml segítségével | ||
+ | ** Létrehozhatunk default, "üres" Config-ot is | ||
+ | ** Az xml-t érdemes lehet parancssori paraméterben beadni | ||
+ | ** Megadhatjuk a Config további beállításait | ||
+ | * Példányosítsuk a Scenariot a Config példányunk segítségével | ||
+ | ** A Scenario egy super-konténer ami minden adatot tartalmazni fog a konfigurációs fájlból (utak, populáció, household-ok, facility-k, stb.) | ||
+ | ** Megadhatjuk a Scenario további beállításait | ||
+ | * Hozzuk létre a Controller-t a Scenario-t felhasználva | ||
+ | ** A Controller felelős a szimuláció futtatásáért | ||
+ | ** A Controller-t később bővebben ismertetjük | ||
+ | ** Megadhatjuk a Controller további beállításait | ||
+ | |||
+ | === Egy egyszerű példafuttatás === | ||
+ | Az alábbi kódot az egyik legegyszerűbb módszer, ahogyan futtathatjuk a MATSim-et. Nem használ valódi konfigurációt, csak az alapértelmezett "üreset", de ennek ellenére érdemes lefuttatnunk, hogy ellenőrizzük, hogy mindent könyvtárat megfelelően húztunk e be. Helyes futás esetén a program logolja a konzolra a futás lépéseit, majd logol egy hibát amikor az üres outputot nem tudja kiírni, végül pedig jelzi, hogy sikeresen leállt. | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | public static void main(String[] args) { | ||
+ | |||
+ | Config config; | ||
+ | |||
+ | // Használjuk a ConfigUtils osztályt default konfigurációhoz vagy konfigurációs xml beolvasásához | ||
+ | config = ConfigUtils.createConfig(); // "üres" konfiguráció létrehozása | ||
+ | |||
+ | // Egyéb, konfigurációval kapcsolatos beállítások | ||
+ | config.controler().setLastIteration(1); // iterációk számának beállítása | ||
+ | config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); //a kimeneti fájlok/mappa felülírása, ha már léteznek | ||
+ | |||
+ | // A Scenario szuperkonténer létrehozása | ||
+ | Scenario scenario = ScenarioUtils.createScenario(config) ; | ||
+ | |||
+ | // A Controler létrehozása | ||
+ | Controler controler = new Controler(scenario); | ||
+ | |||
+ | // A szimuláció futtatása | ||
+ | controler.run(); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Egy interaktív példa === | ||
+ | Amennyiben a MATSimhez az OTFVis vizualizálót használjuk, úgy lehetőségünk van interaktív példát megjeleníteni.Emlékeztetünk, hogy ebben az esetben minden adat a memóriába töltődik! | ||
+ | |||
+ | Az OFTVis a MATSimnek egy külső modulja, és a következő irányelveket érdemes követni a használata során: | ||
+ | * A Config osztályunk konstruktorparaméterében meg kell adni a modult (OTFVisConfigGroup) | ||
+ | * A ConfigUtils osztályból a Config példányunk megadásával lekérdezhetjük a OTFVisConfigGroup példányt | ||
+ | ** Ezután módosíthatjuk az OTFVis konfigurációját | ||
+ | ** Ezek a megjelenítéssel kapcsolatos beállítások | ||
+ | * A Controler-nek meg kell adnunk az OTFVis-t mint felülíró modul (az <code>addOverridingModule()</code> metódus segítségével) | ||
+ | * A megjelenítés konfigurálásával készen is vagyunk: amennyiben a szimulációt nem kívánjuk módosítani, úgy futtathatjuk a Controlert | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | public static void main(final String[] args) { | ||
+ | // Betöltjük a Configot a konfigurációs xml-ből és az OTFVisControlGroupból | ||
+ | Config config = ConfigUtils.loadConfig(args[0], new OTFVisConfigGroup()); | ||
+ | |||
+ | // Ha a kimeneti fájl/mappa már létezik, felülírjuk | ||
+ | config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists) ; | ||
+ | |||
+ | // A szimulációval kapcsolatos beállítások | ||
+ | config.qsim().setSnapshotStyle(SnapshotStyle.queue) ; | ||
+ | config.qsim().setVehicleBehavior(QSimConfigGroup.VehicleBehavior.teleport); | ||
+ | config.transit().setUseTransit(true); | ||
+ | |||
+ | // A vizualizációval kapcsolatos beállítások | ||
+ | OTFVisConfigGroup visConfig = ConfigUtils.addOrGetModule(config, OTFVisConfigGroup.GROUP_NAME, OTFVisConfigGroup.class); | ||
+ | visConfig.setDrawTime(true); | ||
+ | visConfig.setDrawNonMovingItems(true); | ||
+ | visConfig.setAgentSize(125); | ||
+ | visConfig.setLinkWidth(10); | ||
+ | visConfig.setDrawTransitFacilityIds(false); | ||
+ | visConfig.setDrawTransitFacilities(false); | ||
+ | |||
+ | // A Scenario szuperkonténer létrehozása | ||
+ | Scenario scenario = ScenarioUtils.loadScenario(config) ; | ||
+ | |||
+ | // A Controler létrehozása | ||
+ | final Controler controler = new Controler(scenario) ; | ||
+ | |||
+ | // Megadjuk a controlernek a felülíró modult | ||
+ | controler.addOverridingModule(new OTFVisLiveModule()); | ||
+ | |||
+ | // A szimuláció futtatása | ||
+ | controler.run(); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === A Controler és eseményei === | ||
+ | A MATSim magja a Controler. Az adatok beolvasása után ez felelős az egész szimuláció kézben tartásáért, természetesen minden részfeladatot almodulok hajtanak végre. Az alábbi ábrán a MATSim Controler-ének sémája látható. A teljes program eseményvezérelt, az alábbi ábrán látható, hogy a Controler milyen eseményeket válthat ki (ezek a <code>ControlerEvent</code>-ek, amiket <code>ControlerListener</code>-ek kezelnek. | ||
+ | |||
+ | [[Fájl:Matsim_controler.jpg]] | ||
+ | |||
+ | A fenti ábra minden pontjához tartozik egy esemény (pl a Startuphoz <code>StartupEvent</code>, a Before Mobsim-hez <code>BeforeMobsimEvent</code>, és így tovább. Ezek mind a <code>ControlEvent</code> leszármazottai. A teljes lista megtalálható a MATSim javadoc-jában, [http://ci.matsim.org:8080/job/MATSim_M2/ws/matsim/target/site/apidocs/org/matsim/core/controler/events/ControlerEvent.html a ControlerEvent osztály] és [http://ci.matsim.org:8080/job/MATSim_M2/ws/matsim/target/site/apidocs/org/matsim/core/controler/listener/ControlerListener.html a ControlerListener interfész] oldalakon. | ||
+ | |||
+ | A Controlerhez hasonlóan működik minden modul a saját eventjeivel és listenerjeivel. A MATSim saját kiterjesztése történhet ezeknek a moduloknak a kiterjesztésével vagy lecserélésével (például egy új pontozási szabály hozzáadásával), de akár a modulok lecserélése nélkül is kiválthatunk érdekes viselkedést. | ||
+ | |||
+ | === Egy példakiterjesztés modulváltoztatás nélkül === | ||
+ | Tegyük fel, hogy statisztikákat szeretnénk a balra kanyarodásról. A MATSim [http://ci.matsim.org:8080/job/MATSim_M2/ws/matsim/target/site/apidocs/index.html eseményeit böngészve] láthatjuk, hogy létezik <code>LinkEnterEvent</code> és <code>LinkLeaveEvent</code>. Ezek rendelkeznek információval az eseményt kiváltó járműről, a szóban forgó útszakaszról, és az <code>Event</code> ősosztályból pedig egy időbélyeggel. A <code>Link</code>-ek rendelkeznek kezdő és végponttal, amik rendelkeznek koordinátákkal, így a két event együtteséből ki tudjuk szűrni a balra kanyarodásokat. | ||
+ | |||
+ | Ehhez egy olyan <code>Listener</code>-t kell definiálnunk, ami a fent említett <code>LinkEnterEvent</code>-re és <code>LinkLeaveEvent</code>-re is figyel, és ezek információiból ki tudjuk szűrni a balra kanyarodásokat. | ||
+ | |||
+ | Egy másik megközelítésben definiálhatnánk egy <code>LeftTurnEvent</code>-et, amit bekötnénk a már létező <code>EventHandler</code>-ek valamelyikébe (például a <code>LinkLeaveEventHandler</code>-be). | ||
+ | |||
+ | Ugyan lehet, hogy a balra kanyarodási statisztikáknak nincsen sok értelme, de hasonló megközelítésű számításokat jelenleg is végez a rendszer, nézzünk erre néhány példát: bizonyos statisztikákat, például az átlagos aktivitáshosszt jelenleg is így számolja a rendszer. Az újratervező modul is felhasználhatja az eseményeket: például megfelelő <code>Listener</code>-ek figyelhetik, hogy milyen élek vannak tele egy-egy adott időpillanatban, és az újratervezőmodul ennek megfelelően választhat más útiterveket. A pontozómodul is használ eseményeket, hiszen a pontozáshoz szükséges tudni, hogy egy-egy aktivitás mennyi ideig tartott. | ||
+ | |||
+ | A MATSimhez egy új modul definiálása hatalmas feladatnak tűnhet - egyrészt bonyolult algoritmusokat és architektúrát kell átlátni, másrészt a jelenlegi program dokumentációja erősen hiányos -, ugyanakkor, ahogy a fenti példa mutatja, a MATSim-et kiterjeszthetjük a meglévő modulok lecserélése nélkül is. | ||
+ | |||
== Alkalmazások == | == Alkalmazások == | ||
177. sor: | 330. sor: | ||
[https://vimeo.com/166501600 A szimulációból készült videót itt lehet megtekinteni.] | [https://vimeo.com/166501600 A szimulációból készült videót itt lehet megtekinteni.] | ||
+ | |||
+ | === Európa légiforgalma === | ||
+ | A VSP, TU Berlin által készített szimuláció az OAG Aviation repülési adataira épül, és jó példája annak, hogy a MATSim-et nem csak úthálózatok szimulálására lehet használni. A modell a MATSim egy átalakított verzióját használja, amiben lehetőség van a csomópontok (ezesetben repterek) számára korlátokat szabni (például kifutópályák száma). | ||
+ | |||
+ | A szimulációban jól megfigyelhető, hogy a sok reptéren tiltott éjszakai repülési időszak végeztével (körülbelül hajnali 5 óra) milyen drasztikus mértékben megemelkedik a légiforgalom. | ||
+ | |||
+ | [https://vimeo.com/54271303 A szimulációból készült videót itt lehet megtekinteni.] |
A lap jelenlegi, 2017. május 25., 10:43-kori változata
A MATSim (Multi-Agent Transport Simulation) egy aktivitás-alapú, multi-agent közlekedési szimulációs keretrendszer, melynek elsődleges célja a forgalom és a torlódások szimulálása, de egyéb alkalmazási is léteznek. Java-ban fejlesztették és nyílt forráskódú. Könnyen kiterjeszthető, és moduláris jellege miatt a részegységei könnyen lecserélhetőek más implementációkra.
Tartalomjegyzék
Bevezetés
A MATSim célja egyetlen nap közlekedésének szimulálása. A közlekedésnek rengeteg, akár 10^7 résztvevője lehet.
A program a co-evolúciós elvet használja, melynek lényege az hogy a résztvevők újra és újra optimalizálják a napi aktivitásukat miközben egymással versengenek a közlekedési infrastruktúrában. Minden résztvevő memóriájában eltárolunk egy rögzített mennyiségű napi tervet: egy napi terv egy aktivitási láncból és a hozzá tartozó hasznossági pontból áll. Az aktivitási láncokat empirikus adatok alapján készítjük, a hozzájuk tartozó pontokra pedig úgy érdemes gondolni, mint a tevékenységlánc egyfajta gazdasági hasznosságára.
Egy MATSim futás konfigurálható számú iterációból áll. Minden iterációban, mielőtt a résztvevők megkezdenék a mobilitási szimulációt (mobsim), kiválasztanak egy napi tervet a memóriájukból, majd végrehajtják a mobilitási szimulációt, végül pedig megváltoztatják a napi terveikhez tartozó hasznossági pontokat. A napi terv kiválasztása függ a tervek hasznossági pontjától. A résztvevők egy bizonyos százaléka (például 10%) számára megengedett, hogy a kiválasztott tervet klónozzák és módosítsák: ezt a folyamatot hívják újratervezésnek.
Az újratervezést az újratervező modulok hajtják végre. Általában egy tervnek négy elemeét veszik figyelembe: indulási időpont, útvonal, mód és célállomás (és ezáltal implicit módon az aktivitás hosszát is). További szempontok is figyelembe vehetők, mint például aktivitások hozzáadása vagy elvetése, parkolás, stb., de ezek egyelőre csak kísérleti stádiumban részei a MATSimnek. Az újratervező funkciók különböző stratégiákat alkalmazhatnak: lehet, hogy a fenti szempontok közül az egyiket véletlen mutációval változtatja, míg egy másikat a úgy, hogy a számára lehető léegjobbat választja ki (Best response). Ha az újratervezés eredményeként egy résztvevőnek túl sok terve lesz (a tervek száma konfigurálható), akkor a legkisebb pontszámú tervet elveti.
Azok a résztvevők, akik nem terveznek újra, választanak egy tervet a memóriájukból valamilyen választási stratégia alapján. Ezután az összes résztvevő számára végrehajtódik a mobsim, vagyis a mobilitási szimuláció, ami egy napnak felel meg. A nap végén a résztvevők pontozzák az aznap végrehajtott tervüket. A napok iterációját addig ismételjük, amíg az átlagos pontszám stabilizálódik.
A közelekedési folyam modellje
A szimulációnak a magja magának a közlekedésnek a szimulálása. Ez a MATSim közlekedési szimulálójával (röviden mobsim) történik. A közelekedés szimulációja szempontjából a következő eseteket különböztethetjük meg:
- fizikai szimulációk, melyek tartalmazzák a járművek részletes követési modelljeit
- cellular automata, ahol az utak helyett cellákat használunk
- sor-alapú szimulációk, ahol a közelekedés dinamikáját várakozási sorokkal modellezzük
- makroszkopikus modellek, ahol nem különálló egységeket (autókat) tekintünk, hanem a folyamot egy egészként
A MATSim modellje
A MATSim, mivel nagy méretű modellekre tervezték, a kevésbé számításigényes sor-alapú szimulációt használja, a következő módon: amikor egy résztvevő (jármű) belép a hálózat egy élére (egy útszakaszra), akkor hozzáadódik az útszakasz kilépését modellező várakozási sorhoz. A jármű akkor léphet ki az útszakaszról, ha az alábbi feltételek mindegyike teljesül:
- eltelt annyi idő, amennyi szükséges volna az útszakasz bejárásához, ha az üres lenne (úgynezevett free flow)
- a várakozási sor elején van
- a következő él (útszakasz) megengedi a belépést
Ez a megközelítés számítsi szempontból nagyon hatékony, de leegyszerűsítő: a valóságban a járművek lassaban közlekednek, ha egy másik járművet követve kell lassítaniuk (megállniuk) vagy gyorsítaniuk (elindulniuk). Ezek az úgynevezett járműkövetési hatások, amiket a fenti modell figyelmen kívül hagy.
A MATSim hálózati modellje nagyban függ az élek (útszakaszok) két fontos paraméterétől: tárolási kapacitás (storage capacity) és folyam kapacitás vagy kimeneti kapacitás (flow capacity). Az előbbi azt mondja meg, hogy hány jármű fér rá egy adott útszakaszra, míg az utóbbi azt, hogy egy adott időegység alatt hány jármű tudja elhagyni az útszakaszt.
Beépített mobsimek
A MATSim két beépített mobsimet bocsát rendelkezésünkre: a QSim-et és a JDEQSim-et (Java Discrete Event Queue Simulation). A két beépített mobsimtől eltérő szimulációs modellt is használhatunk, volt már példa a C++-ben írt DEQSim (Discrete Event Queue Simulation) hozzákapcsolására a MATSimhez, de beépített funkciókként csak a fenti kettő szimulációs modellt kapjuk.
A több szálon futó QSim a MATSim default szimulációs modellje. Egy idő alapú (time-step) implementációt használ, vagyis az idő múlását kicsiny lépésekben szimulálja. Ezzel szemben a JDEQSim (számítási okokból) a sor alapú hozzáállást egy eseményvezérelt implementációval kombinálja. Így nincs idő alapú szimuláció és így garantált, hogy a járművekhez csak akkor nyúlunk hozzá, ha arra valóban szükség van (vagyis ha egy műveletet kivált egy esemény). Az eseményeket egy global scheduler menedzseli.
További fontos különbség a beépített mobsimek között, hogy a JDEQSim megengedi, hogy az élekhez egy bemeneti kapacitást is definiáljunk (a fent említett tárolási és kimeneti kapacitás mellé). A QSimben nincsen ilyen lehetőség, így a bemeneti kapactisának nincsen felső értéke. Ez azt jelenti, hogy bár az útszakaszon tartózkodó járművek számának van felső határa (storage capacity), az útra belépésnek nincs.
A MATSim co-evolúciós algoritmusa
A co-evolúciós algoritmusok különböző fajokat (co-)evolválnak, akik rendszeres interakcióban (versenyben) vannak egymással. Az evoluciós algoritmusok - leegyszerűsítve - a rendszer valamilyen optimumát keresik, hiszen az optimalizációt egy globális fitness függvény biztosítja. Ezzel szemben a co-evolúciós algoritmusok nem a rendszer optimumát keresik, hanem egy sztochasztikus, fajra vonatkozó optimumot, hiszen itt nincsen globális (mindenkire ugyanúgy érvényes) fitness függvény.
A MATSim-ben minden résztvevő a co-evolúciós algoritmus egy fajának felel meg, a résztvevő tervei pedig a faj egyedeinek. A co-evolúciós algoritmusban az optimalizáció a résztvevők terveire (vagyis a napi tervekre, tevékenységekre és utazásukra) vonatkozik. Idővel a rendszer el fog érni egy (bizonyos korlátokkal szabályozott) egyensúlyi állapotot, ahol a résztvevők nem fogják tudni tovább javítani a napi terveiket.
A MATSim elindítása
A MATSim elindításához látogassunk el a MATsim weboldalára, és töltsük le a legutóbbi verziót. A letöltött tömörített fájl kicsomagolása után csak annyi dolgunk van, hogy duplán kattintsunk a matsim .jar fájljára, és az alkalmazás már el is indult.
A szoftver automatikusan felismeri a gépünkön futó Java verzióját és könyvtárát. Amennyiben ez nem történt meg, tallózzuk be a könyvtárat, ahol a JRE könyvtárunkat. A MATSim futtatásához legalább 7-es verziójú Java szükséges.
A MATSim futtatásához be kell tallózzunk egy konfigurációs filet, minden beállítható paraméterünket ez fogja tartalmazni. A letöltött csomag több példakonfigurációt is tartalmaz, ezeket megtaláljuk az example mappában. Amennyiben a programunk elindítás után hibát dob, abban az esetben nyissuk meg a konfigurációs fájlt és az abban megadott network és plans modulok elérhetőségi útját módosítanunk kell, a megadott elérési út helyett teljes, abszolút elérési utat adjunk meg. Ennek az az oka, hogy a szotfver alapértelmezetten a Java könyvtárunkhoz képest relatívan értelmezi a konfigurációs file-ban hivatkozott egyéb elérési útvonalakat, nem pedig a konfigurációs filehoz képest.
A program paramétereit a konfigurációs fájlokban állíthatjuk be.
A konfigurációs fájlok létrehozása
A konfigurációs fájlok XML fájlok. A fő konfigurációs fájlon kívül egyéb XML fájlokat is meg kell adjunk, például olyanokat amik az úthálózatot vagy olyat ami a napi terveket definiálják.
A hálózat megadása
A hálózat megadása XML formátumban történik, ahol az úthálózat pontjait (vagyis a kereszteződéseket) node tag-ek között kell megadni, ezeket pedig nodes tagek közé rendezni. Az úthálózat éleit (vagyis magukat az utakat) hasonlóképpen lehet megadni, csak link illetve links tagekkel.
Az úthálózat egy node-jának van egy egyedi azonosítója, ezen kívül pedig egy x és egy y koordinátája. A MATSim a távolságszámítást egyszerűen Pithagorasz tétellel végzi, így nyomatékosan kérik a felhasználókat, hogy ne WGS84-es, vagy hasonló gömbi koordinátákat használjanak a MATSim default beállításaival. Derékszögű koordinátarendszert javasolnak, ahol egy koordinátányi távolság egy méternek felel meg.
Az úthálózat linkjeinek már sokkal több paramétere lehet:
- id: az él egyedi azonosítója
- from: az él forrásául szolgáló csúcs azonosítója
- to: az él céljául szolgáló csúcs azonosítója
- length: az él hossza. A javasolt mértékegység a méter, de más is használható, amennyiben ezek az összes konfigurációs fájlban összhangban vannak
- capacity: az él kapacitása, vagyis ahány jármű áthaladhat rajta egy időegység (javasolt: óra) alatt
- freespeed: az a sebesség, amivel a járművek haladnak az élen, amennyiben azon nincs torlódást okozó forgalom (méter per másodperc a javasolt mértékegység)
- permlanes: az él által reprezentált úton rendelkezésünkre álló sávok száma
- modes: a járműtípusok, akik használhatják a sávot. Több is megadható vesszővel elválasztva, például car, bike, taxi.
Megjegyzendő, hogy minden él rendelkezik irányítással, és így egyirányú utaknak felelnek meg. Amennyiben kétirányú utat szeretnénk szmulálni, úgy a linket kétszer kell felvenni a listánkba, alternáló from és to attribútumokkal.
Nézzünk egy példahálózatot:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE network SYSTEM "http://www.matsim.org/files/dtd/network_v1.dtd">
<network name="equil test network">
<nodes>
<node id="1" x="-20000" y="0"/>
<node id="2" x="-15000" y="0"/>
<node id="3" x="-865" y="5925"/>
<node id="4" x="-2498" y="4331"/>
<node id="5" x="-3829" y="3215"/>
</nodes>
<links capperiod="01:00:00">
<link id="1" from="1" to="2" length="10000.00" capacity="36000" freespeed="27.78" permlanes="1" />
<link id="2" from="2" to="3" length="10000.00" capacity="3600" freespeed="27.78" permlanes="1" />
<link id="3" from="2" to="4" length="10000.00" capacity="3600" freespeed="27.78" permlanes="1" />
<link id="4" from="2" to="5" length="10000.00" capacity="3600" freespeed="27.78" permlanes="1" />
</links>
</network>
További példahálózatokat találhatunk a letöltött matsim csomag examples könyvtárában.
A tervek/populáció konfigurálása
A MATSimben a résztvevők napi tervei határozzák meg az utazásaikat. Ezeknek az összességét terveknek (plans) és populációnak (population) is szokás nevezni. A populáció tartalmaz egy emberekből álló (person) listát, minden person tartalmaz egy tervekből álló (plan) listát, és minden plan tartalmaz egy activity-kből és leg-ekből álló listát.
Nézzünk egy példatervet:
<plans>
<person id="1">
<plan selected="yes" score="93.2987721">
<act type="home" x="-25000" y="0" link="1" end_time="06:00" />
<leg mode="car" />
<act type="work" x="10000" y="0" link="20" dur="00:10" />
<leg mode="car" />
<act type="home" x="-25000" y="0" link="1" />
</plan>
</person>
</plans>
Minden embernek pontosan egy terve lehet selected státuszú, ez ugyan a szimuláció alatt többször is változhat (akár egyetlen napon belül az újratervezési fázisban is). A tervhez tartozhat score érték, de ennek az inputban nem kell szerepelnie, hiszen a MATSim fogja kiszámítani a terv végrehajtása után az értékelő ciklusban.
Az aktivitások egy résztvevő napi teendőit szimbolizálják, és összességükből áll össze a résztvevő napi terve. Az aktivitásoknak a következő tulajdonságaik lehetnek:
- Az aktivitás hossza. Ez megadható az end_time attribútummal vagy a dur (duration) attribútummal, értelemszerűen az előbbi a végzés időpontját jelenti, míg az utóbbi a végzés időtartamát.
- Az utolsó napi aktivitáshoz nem tartozik se időtartam, se befejezési időpont
- Az aktivitás helyszíne. Ezt megadhatjuk x és y koorinátákkal, illetve a helyszínhez legközelebbi él azonosítójával.
- A helyszínhez legközelebbi él azt jelenti, hogy az adott aktivitás az adott élről érhető el. Tehát például a munka aktivitáshoz a munkahely utcáját érdemes megadni.
- Amennyiben nem adunk meg legközelebbi élt, úgy a MATSim automatikusan kiszámolja a koordinátákhoz legközelebb eső élt.
- Amennyiben megadunk élt, úgy a koordináták elhagyhatóak.
- Az aktivitás típusa a tevékenység jellegét írja le, például otthon, munka, stb.
- A leg mode attribútuma határozza meg, hogy hogyan fog a résztvevő az egyik helyszínről a másikra utazni, például car, pt (public transportation).
- A legeknek lehet opcionálisan egy trav_time attribútuma, ami az utazás várható idejét adhatja meg.
- A legeknek tartalmazniuk kell egy útvonalat is. A kezdeti legek persze ezt nem tartalmazzák, ezt a MATSim kiszámolja.
Egy résztvevő egyből elkezdi a következő leget, amint az előző (leg vagy activity) befejeződött. Amennyiben a mobsim olyan mode-ba ütközik, amit nem ismer, úgy a teleportálás utazási módot választja: ebben az esetben a kezdeti pontról eltűnik a résztvevő és a célponton felbukkan a várható utazási idő elteltével.
Minimális populációs adatok
A populáció konfigurálása első pillantásra könnyen tűnhet túlságosan soknak, de az adatok között számos olyan van, amely opcionális. Adott esetben nehezen követhető, hogy mit kötelező és mit nem kötelező megadni, ezért álljon itt egy lista a könnyítő faktorokról:
- Egy emberhez elég egyetlen tervet megadni
- A terveket nem kell kiválasztani, se pontozni, vagyis mind a selected, mint a score attribútum elhagyható
- Az aktivitások helyszínéhez elgendő csak a koordinátáit megadni (tehát a link attribútum elhagyható)
- A legeknek elegendő módot megadni, utat nem szükséges (azaz a route attribútum elhagyható)
Egy példa minimális adatokkal:
<population>
<person id="1">
<plan>
<act type="home" x="5.0" y="8.0" end_time="08:00:00" />
<leg mode="car" />
<act type="work" x="1500.0" y="890.0" end_time="17:30:00" />
<leg mode="car" />
<act type="home" x="5.0" y="8.0" />
</plan>
</person>
<person id="2">
...
</person>
</population>
Vizualizáció
A MATSim outputjának vizualizációjához mindenképpen third-party könyvtárakat kell használjunk. A fejlesztők az OTFVIS-t javasolják, így itt is azt mutatjuk be röviden.
Az OTFVIS elvileg letölthető a MATSim nightly (nem stabil) buildeket tartalmazó könyvtárából, mi itt azonban hosszas keresgélés után sem találtuk. Amennyiben a későbbiekben sem található itt meg, úgy alternatívának javasoljuk a matsim projekt github oldalát.
Felhívjúk rá a figyelmet, hogy az OTFVIS futtatása sok memóriát vehet igénybe, így célszerű a megfelelő Java beállításokkal elindítani, például legalább 500MB-tal. A parancs struktúrája Windowson a következő:
java -Xmx500m -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis arguments
Amennyiben Linux-on szeretnénk futtatni, úgy a pontosvesszőt cseréljük le kettőspontra.
Snapshotok készítése és megjelenítése
Snapshotok készítését a következő példaparancshoz hasonló utasításokkal tudjuk elvégezni:
java -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis -convert output/50.events.txt.gz input/network.xml.gz output/50.visualization.mvi 300
A -convert
utasítás után megadhatjuk a MATSim output file-ját, az input hálózatot, majd a file-t amibe szeretnénk elmenteni a snapshotot (ezt .mvi kiterjesztéssel tehetjük meg), valamint a snapshotok időtartamát másodpercekben. Tehát a fenti példaparancs ötpercenként fog egy snapshotot készíteni a hálózatunkról, és ezt elmenti egy .mvi fájlba, amit aztán megjeleníthetünk, a következő módon:
java -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis output/50.visualization.mvi
Interaktív szimuláció
Az OFTVIS-t lehet használni interkatív szimulációra. Megjegyezzük, hogy a program képességei korlátozottak.
Fontos tudni, hogy ebben az esetben az összes adatot (hálózat, populáció, stb) be kell tölteni a memóriába. Bár hardveres gyorsítást (OpenGL) használ, az igazán nagy fájlokkal így is akadhatnak gondok.
Ahhoz, hogy interaktív szimulációt indítsunk, nincs más dolgunk mint átadni az OTFVis-nek a konfigurációs fájlt amit egyébként a MATSimnek adnánk inputként. A következő egy lehetséges példahívás az interkatív vizualizálóra:
java -cp MATSim.jar;otfvis/otfvis.jar org.matsim.contrib.otfvis.OTFVis input/config.xml
Az implementációról szóló részben mutatunk példát arra, hogy hogyan futtathatjuk a saját programunkból az OFTVis-t, és hogyan fog kinézni a végeredmény.
Fejlesztői használat
Ebben azokat az információkat mutatjuk be, amiket szükséges tudnunk ha szeretnénk a saját programunkban használni a MATSim-et. A MATSim könyvtárat letölthetjük a projekt honlapjáról vagy akár a projekt github oldaláról is. Azért javasoljuk az utóbbit, mert itt számos egyéb kiterjesztése is megtalálható, vagy hasznos third party libraryk, mint például a vizualizációhoz használható OFTVis.
A MATSim moduláris felépítésű, de a fejlesztői által a modul nem egy precízen definiált fogalom: felhasználók által készített kiegészítések (úgynevezett contrib-ek, contribution-ök), opcionális elemek és a MATSim fontos, belső egységei (például a pontozás) is egy-egy modulnak számít. A MATSim teljes architektúráját az összes modullal a következő ábra foglalja össze:
A fenti ábra elég szerteágazó és sajnos a legtöbb eleméhez nem tartozik semmilyen dokumentáció. Ellenben nem minden itt felsorolt modult kötelező konfigurálni: némelyik opcionális (mint például az előző részben bemutatott OTFVis), mások pedig rendelkeznek alapértelmezett értékkel (mint például a pontozás, vagyis scoring).
A MATSim használatának általános váza
A fenti ábra komplikáltságához képest a MATSim saját programból való próbafuttatása kevésbé bonyolult. Amennyiben a MATSim-et csak használni szeretnénk, úgy a következő általános váza legyen a programunknak:
- Példányosítsuk a Config osztályt a konfigurációs xml segítségével
- Létrehozhatunk default, "üres" Config-ot is
- Az xml-t érdemes lehet parancssori paraméterben beadni
- Megadhatjuk a Config további beállításait
- Példányosítsuk a Scenariot a Config példányunk segítségével
- A Scenario egy super-konténer ami minden adatot tartalmazni fog a konfigurációs fájlból (utak, populáció, household-ok, facility-k, stb.)
- Megadhatjuk a Scenario további beállításait
- Hozzuk létre a Controller-t a Scenario-t felhasználva
- A Controller felelős a szimuláció futtatásáért
- A Controller-t később bővebben ismertetjük
- Megadhatjuk a Controller további beállításait
Egy egyszerű példafuttatás
Az alábbi kódot az egyik legegyszerűbb módszer, ahogyan futtathatjuk a MATSim-et. Nem használ valódi konfigurációt, csak az alapértelmezett "üreset", de ennek ellenére érdemes lefuttatnunk, hogy ellenőrizzük, hogy mindent könyvtárat megfelelően húztunk e be. Helyes futás esetén a program logolja a konzolra a futás lépéseit, majd logol egy hibát amikor az üres outputot nem tudja kiírni, végül pedig jelzi, hogy sikeresen leállt.
public static void main(String[] args) {
Config config;
// Használjuk a ConfigUtils osztályt default konfigurációhoz vagy konfigurációs xml beolvasásához
config = ConfigUtils.createConfig(); // "üres" konfiguráció létrehozása
// Egyéb, konfigurációval kapcsolatos beállítások
config.controler().setLastIteration(1); // iterációk számának beállítása
config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); //a kimeneti fájlok/mappa felülírása, ha már léteznek
// A Scenario szuperkonténer létrehozása
Scenario scenario = ScenarioUtils.createScenario(config) ;
// A Controler létrehozása
Controler controler = new Controler(scenario);
// A szimuláció futtatása
controler.run();
}
Egy interaktív példa
Amennyiben a MATSimhez az OTFVis vizualizálót használjuk, úgy lehetőségünk van interaktív példát megjeleníteni.Emlékeztetünk, hogy ebben az esetben minden adat a memóriába töltődik!
Az OFTVis a MATSimnek egy külső modulja, és a következő irányelveket érdemes követni a használata során:
- A Config osztályunk konstruktorparaméterében meg kell adni a modult (OTFVisConfigGroup)
- A ConfigUtils osztályból a Config példányunk megadásával lekérdezhetjük a OTFVisConfigGroup példányt
- Ezután módosíthatjuk az OTFVis konfigurációját
- Ezek a megjelenítéssel kapcsolatos beállítások
- A Controler-nek meg kell adnunk az OTFVis-t mint felülíró modul (az
addOverridingModule()
metódus segítségével) - A megjelenítés konfigurálásával készen is vagyunk: amennyiben a szimulációt nem kívánjuk módosítani, úgy futtathatjuk a Controlert
public static void main(final String[] args) {
// Betöltjük a Configot a konfigurációs xml-ből és az OTFVisControlGroupból
Config config = ConfigUtils.loadConfig(args[0], new OTFVisConfigGroup());
// Ha a kimeneti fájl/mappa már létezik, felülírjuk
config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists) ;
// A szimulációval kapcsolatos beállítások
config.qsim().setSnapshotStyle(SnapshotStyle.queue) ;
config.qsim().setVehicleBehavior(QSimConfigGroup.VehicleBehavior.teleport);
config.transit().setUseTransit(true);
// A vizualizációval kapcsolatos beállítások
OTFVisConfigGroup visConfig = ConfigUtils.addOrGetModule(config, OTFVisConfigGroup.GROUP_NAME, OTFVisConfigGroup.class);
visConfig.setDrawTime(true);
visConfig.setDrawNonMovingItems(true);
visConfig.setAgentSize(125);
visConfig.setLinkWidth(10);
visConfig.setDrawTransitFacilityIds(false);
visConfig.setDrawTransitFacilities(false);
// A Scenario szuperkonténer létrehozása
Scenario scenario = ScenarioUtils.loadScenario(config) ;
// A Controler létrehozása
final Controler controler = new Controler(scenario) ;
// Megadjuk a controlernek a felülíró modult
controler.addOverridingModule(new OTFVisLiveModule());
// A szimuláció futtatása
controler.run();
}
A Controler és eseményei
A MATSim magja a Controler. Az adatok beolvasása után ez felelős az egész szimuláció kézben tartásáért, természetesen minden részfeladatot almodulok hajtanak végre. Az alábbi ábrán a MATSim Controler-ének sémája látható. A teljes program eseményvezérelt, az alábbi ábrán látható, hogy a Controler milyen eseményeket válthat ki (ezek a ControlerEvent
-ek, amiket ControlerListener
-ek kezelnek.
A fenti ábra minden pontjához tartozik egy esemény (pl a Startuphoz StartupEvent
, a Before Mobsim-hez BeforeMobsimEvent
, és így tovább. Ezek mind a ControlEvent
leszármazottai. A teljes lista megtalálható a MATSim javadoc-jában, a ControlerEvent osztály és a ControlerListener interfész oldalakon.
A Controlerhez hasonlóan működik minden modul a saját eventjeivel és listenerjeivel. A MATSim saját kiterjesztése történhet ezeknek a moduloknak a kiterjesztésével vagy lecserélésével (például egy új pontozási szabály hozzáadásával), de akár a modulok lecserélése nélkül is kiválthatunk érdekes viselkedést.
Egy példakiterjesztés modulváltoztatás nélkül
Tegyük fel, hogy statisztikákat szeretnénk a balra kanyarodásról. A MATSim eseményeit böngészve láthatjuk, hogy létezik LinkEnterEvent
és LinkLeaveEvent
. Ezek rendelkeznek információval az eseményt kiváltó járműről, a szóban forgó útszakaszról, és az Event
ősosztályból pedig egy időbélyeggel. A Link
-ek rendelkeznek kezdő és végponttal, amik rendelkeznek koordinátákkal, így a két event együtteséből ki tudjuk szűrni a balra kanyarodásokat.
Ehhez egy olyan Listener
-t kell definiálnunk, ami a fent említett LinkEnterEvent
-re és LinkLeaveEvent
-re is figyel, és ezek információiból ki tudjuk szűrni a balra kanyarodásokat.
Egy másik megközelítésben definiálhatnánk egy LeftTurnEvent
-et, amit bekötnénk a már létező EventHandler
-ek valamelyikébe (például a LinkLeaveEventHandler
-be).
Ugyan lehet, hogy a balra kanyarodási statisztikáknak nincsen sok értelme, de hasonló megközelítésű számításokat jelenleg is végez a rendszer, nézzünk erre néhány példát: bizonyos statisztikákat, például az átlagos aktivitáshosszt jelenleg is így számolja a rendszer. Az újratervező modul is felhasználhatja az eseményeket: például megfelelő Listener
-ek figyelhetik, hogy milyen élek vannak tele egy-egy adott időpillanatban, és az újratervezőmodul ennek megfelelően választhat más útiterveket. A pontozómodul is használ eseményeket, hiszen a pontozáshoz szükséges tudni, hogy egy-egy aktivitás mennyi ideig tartott.
A MATSimhez egy új modul definiálása hatalmas feladatnak tűnhet - egyrészt bonyolult algoritmusokat és architektúrát kell átlátni, másrészt a jelenlegi program dokumentációja erősen hiányos -, ugyanakkor, ahogy a fenti példa mutatja, a MATSim-et kiterjeszthetjük a meglévő modulok lecserélése nélkül is.
Alkalmazások
Ebben a részben néhány konkrét példát nézünk, ahol a való életben alkalmazták a MATSimet.
Németország
Az alábbi videóban látható példa egy ötszázezer fős részmintán elvégzett szimuláció eredménye. A teljes szimulációban négymillió résztvevő jármű volt. A résztvevők adatait egy 2008-as közlekedési felmérésből extrapolálták. A hálózat mintegy 360.000. élből és négymillió aktivitás-helyszínből áll, melyek az openstreetmap.org-ról származnak.
A szimulációban a résztvevők teljes napi tervei szerepelnek, az aktivitásokat pedig otthon, munka, oktatás, vásárlás, kikapcsolódás és egyéb kategóriákba sorolták: a videóban egy-egy felvillanó pont egy aktivitás elkezdését jelenti, utána pedig a résztvevő színe jelzi az éppen aktuális aktivitás típusát.
A szimulációból készült videót itt lehet megtekinteni.
Vorarlberg, Ausztria
Az Austrian Institute of Technology 2015-ben fejlesztett ki egy MATSim modellt az ország legnyugatibb tartománya, Vorarlberg számára.
A tartomány hálózatát OpenStreetMap-ből származtatták, a populációt pedig egy 2013-as mobilitási felmérés alapján készítették.
A tartománynak 380.000. lakója van, és a modell mindnyájukat szimulálja, de nem vesz figyelembe ünnepi forgalmat illetve más tartományokból érkezők által okozott forgalmat.
A modell alapján három különböző lehetséges közlekedésfejlesztési tervet és azok hatásait kutatták: a tömegközlekedés fejlesztését, városfejlesztést és elektromos töltőállomások elhelyezését.
A szimulációból készült videót itt lehet megtekinteni.
Európa légiforgalma
A VSP, TU Berlin által készített szimuláció az OAG Aviation repülési adataira épül, és jó példája annak, hogy a MATSim-et nem csak úthálózatok szimulálására lehet használni. A modell a MATSim egy átalakított verzióját használja, amiben lehetőség van a csomópontok (ezesetben repterek) számára korlátokat szabni (például kifutópályák száma).
A szimulációban jól megfigyelhető, hogy a sok reptéren tiltott éjszakai repülési időszak végeztével (körülbelül hajnali 5 óra) milyen drasztikus mértékben megemelkedik a légiforgalom.