Modelleren en simuleren van Complexe Automaten met JADE
Door: Collegekaart: Email: Begeider:
Marvin Jacobsz 0242047
[email protected] Dr. Ir. Alfons Hoekstra
1
Abstract JADE (Java Agent DEvelopment framework) is middleware die bedoeld is voor de ontwikkeling van agentgebaseerde applicaties en tevens dient als runtime omgeving voor deze agents. In hoeverre JADE geschikt is voor het ontwikkelen van een multiscale, multi-science applicatieframework, wordt onderzocht in deze scriptie. Hierbij speelt de zogenaamde ‘Complexe Automaat’ een belangrijke rol. De complexe automaat is een generieke methode om multi-science, multi-scale complexe systemen te modelleren. Één methode om de onderdelen van een complexe automaat te koppenen, hiërarchische koppeling, wordt in deze paper geanalyseerd en besproken. Daarnaast wordt de point-2-point communicatie performance van JADE gemeten en besproken.
2
ABSTRACT ............................................................................................................................................ 2 INLEIDING ............................................................................................................................................ 5 HOOFDSTUK 1: COMPLEXE AUTOMATEN .................................................................................6 INLEIDING............................................................................................................................................. 6 COMPLEXE SYSTEMEN .......................................................................................................................... 6 CELLULAIRE AUTOMATEN .................................................................................................................... 6 Cellulaire automaten ...................................................................................................................... 7 Agents ............................................................................................................................................. 7 COMPLEXE AUTOMATEN....................................................................................................................... 7 Definitie .......................................................................................................................................... 7 Compositie ...................................................................................................................................... 8 Communicatie .................................................................................................................................8 Smart Conduit .................................................................................................................................8 Scale Map ....................................................................................................................................... 8 HOOFDSTUK 2: JADE....................................................................................................................... 10 INTRODUCTIE ..................................................................................................................................... 10 Wat is JADE?................................................................................................................................ 10 Kerneigenschappen....................................................................................................................... 10 ARCHITECTUUR .................................................................................................................................. 10 FUNCTIONALITEIT .............................................................................................................................. 11 Standaard services ........................................................................................................................ 11 ACLMessages................................................................................................................................ 12 HOOFDSTUK 3: COMMUNICATIE PERFORMANCE VAN JADE........................................... 13 INTRODUCTIE ..................................................................................................................................... 13 VORIG WERK ...................................................................................................................................... 13 ‘A Performance Analysis of Multi-Agent Systems’ ....................................................................... 13 ’Scalability and Performance of JADE MTP’............................................................................... 14 BESCHRIJVING EXPERIMENT ............................................................................................................... 16 Opstelling...................................................................................................................................... 16 Hypothese...................................................................................................................................... 17 RESULTATEN ...................................................................................................................................... 17 DISCUSSIE EN CONCLUSIES .................................................................................................................22 HOOFDSTUK 4: COUPLING MECHANISMEN IN DE COMPLEXE AUTOMAAT ............... 24 INLEIDING........................................................................................................................................... 24 MODELLEN ALS CELLULAIRE AUTOMAAT .......................................................................................... 24 Formele beschrijving .................................................................................................................... 24 Executieverloop............................................................................................................................. 25 KOPPELING PARADIGMA’S .................................................................................................................. 25 IMPLEMENTATIE .................................................................................................................................26 MicroAgents.................................................................................................................................. 27 MacroAgents.................................................................................................................................27 Experiment .................................................................................................................................... 28 EINDWOORD ...................................................................................................................................... 31 REFERENTIES.................................................................................................................................... 32 APPENDIX A ....................................................................................................................................... 34 CxA.java........................................................................................................................................ 34 Domain.java.................................................................................................................................. 35 MacroModel.java.......................................................................................................................... 35 MacroModelState.java.................................................................................................................. 39 MicroModel.java........................................................................................................................... 42
3
MicroModelState.java................................................................................................................... 46 StartMicros.java ........................................................................................................................... 47 State.java....................................................................................................................................... 48 APPENDIX B........................................................................................................................................ 50 Opstarten Platform ....................................................................................................................... 50 Opstarten MicroAgents .................................................................................................................50
4
Inleiding In deze Bachelor afstudeerscriptie worden de resultaten beschreven van het bestuderen van het agent framework "JADE" als software omgeving voor het modelleren en simuleren van complexe systemen. Op het moment van schrijven is het project "COAST" actief [1]. Het "COAST" project bestaat uit vijf partners, waaronder de UvA, die zichzelf het volgende doel hebben gesteld: Het ontwikkelen van een multi-scale, multi-science framework voor het modelleren en simuleren van complexe systemen waarbij gebruik gemaakt wordt van het complexe automaten concept. Dit framework is gebaseerd op een hiërarchische aggregatie van gekoppelde cellulaire automaten en agent-gebaseerde modellen. Een belangrijk subdoel van "COAST" is om met het ontwikkelde framework het probleem van 'in stent restenosis in coronaire slagaderen'* te bestuderen. Verwacht wordt dat met het framework een model van 'in stent restenosis' kan worden gemaakt en dat met de simulaties die hiermee worden uitgevoerd een bijdrage kan worden geleverd bij het onderzoek naar hoe deze aandoening ontstaat en hoe zij het best verholpen zou kunnen worden. Het framework dient multi-scale en multi-science te zijn. Multi-scale houdt het volgende in: De componenten van het complexe systeem kunnen we beschouwen als afzonderlijke submodellen. Echter, deze submodellen opereren niet allen op een zelfde tijd- of ruimteschaal, maar kunnen juist of zeer verschillende schalen werken. Vandaar dat we hier de term multi-scale hanteren. De term multi-science is vanuit het bovenstaande over submodellen ook te begrijpen: Het is niet noodzakelijk dat alle submodellen vallen onder dezelfde wetenschappelijke discipline. Het kan bijvoorbeeld zo zijn dat submodel A een biologisch proces beschrijft en dat submodel B een fysisch proces beschrijft en dat zij onderling met elkaar communiceren. Als omgeving om het framework in te implementeren is in het COAST project gekozen voor "JADE" [2]. JADE (Java Agent DEvelopment framework) is een software framework om agent-gebaseerde toepassingen te ontwikkelen en te draaien. De processen die door een bepaald model worden gedefinieerd, worden geïmplementeerd in het gedrag van een agent. Doordat agents met elkaar kunnen communiceren is het mogelijk dat de modellen informatie met elkaar uitwisselen. Zo ontstaat een complexe automaat. De onderzoeksvraag is nu: In hoeverre is JADE een geschikte software omgeving voor het ontwikkelen van een multi-science, multi-scale framework? Om dit te bepalen zijn voor deze scriptie een aantal tests met JADE gedaan. Om te beginnen is er gekeken naar de communicatie performance van Jade. Het experiment wat dat hiervoor gedaan is, is eenvoudig van opzet: Stuur pakketten van variabele grootte rond in het systeem en meet hoe lang dat duurt. Daarna is een multi-scale koppeling mechanismen tussen modellen geïmplementeerd in Jade. Aan de hand van deze implementatie wordt gekeken hoe JADE zich gedraagt. *
In-stent restenosis is een complicatie die kan ontstaan na dat een coronaire slagader is behandeld tegen een vernauwing (stenosis), waarbij na het openen van de slagader een stent is achtergelaten om de slagader open te houden. Het is mogelijk dat er vervolgens weer een vernauwing van de slagader kan optreden, en dat wordt in-stent restenosis genoemd.
5
Hoofdstuk 1: Complexe automaten Inleiding Een methode om systemen te bestuderen is door het formuleren van een model van dat systeem. Als we dit model implementeren in een computer kunnen we aan de hand hiervan simulaties uitvoeren en de resultaten evalueren om het systeem beter te begrijpen. Als het systeem bestaat uit vele afzonderlijke componenten, dan is het veelal handig om elk component als afzonderlijk model te beschrijven. Omdat de modellen dan onderdeel zijn van een groter systeem dat we willen begrijpen, is het noodzakelijk dat zij onderling een bepaalde vorm van koppeling hebben. In dit hoofdstuk wordt ingegaan op de (wetenschappelijke) concepten die er bestaan om de bovenstaande concepten te realiseren. De nadruk zal liggen op de ‘Complexe Automaat’, wat een krachtig paradigma lijkt te zijn voor modelering van multi-scale multi-science systemen. Complexe systemen Een complex systeem kan op vele manieren worden gekenmerkt. In deze scriptie wordt de volgende definitie gehanteerd: Complex systeem: Een verzameling unieke actoren met elk hun eigen attributen en interacties met elkaar, die gezamenlijk emergent gedrag vertonen. Een complex systeem bestaat dus concreet uit een verzameling van entiteiten. Deze entiteiten vertonen individueel een bepaald gedrag. Zij beschikken over een aantal interne parameters en daarnaast over enkele functies die zij kunnen uitvoeren. Het is mogelijk dat in een complex systeem zich meerdere instanties van dezelfde entiteit bevinden. Als deze actoren communicatie over en weer hebben, bijvoorbeeld door met elkaar samen te werken, kan emergent gedrag ontstaan. Hiermee wordt zelforganiserend, collectief gedrag bedoeld dat verassende effecten heeft en dat dus moeilijk te voorspellen valt uit het gedrag van één afzonderlijke actor (het geheel is meer dan de som der delen). Doordat er lokaal interactie is tussen de actoren ontstaat dit globale gedrag. Kenmerkend voor emergent gedrag is daarbij dat er geen centrale component is die het geheel controleert of bestuurt. [3] Voorbeelden van complexe systemen zijn veel te vinden in de natuur. Een mierenkolonie is hier een uitgesproken voorbeeld van. De actoren zijn de leden van de mierenmaatschappij: de koningin, de werksters en de mannetjes. Elk van de leden vertoont zo zijn eigen afzonderlijke gedrag: werksters verzamelen voedsel, mannetjes zorgen voor voortplanting, et cetera. Opmerkelijk is dat elke mier zijn taak doet zonder dat er centrale controle is. Al het gedrag van de mieren tezamen vormt echter een groter geheel: een mierenhoop, met zijn geheel eigen dynamiek. Cellulaire automaten De afzonderlijke actoren van de complexe automaat kunnen onder andere worden gemodelleerd aan de hand van cellulaire automaten en agents.
6
Cellulaire automaten
Een cellulaire automaat [4] wordt in de regel gedefinieerd door vier karakteristieke eigenschappen: 1. Rooster: Een cellulaire automaat bestaat uit een discreet rooster waarop de punten homogeen zijn verdeeld. Op dit rooster ontplooit zich de dynamica van de cellulaire automaat. In principe voldoet elke discrete subset van de Euclidische ruimte, maar in de praktijk wordt vaak gebruik gemaakt van een eindige 1, 2 of 3-dimensionale subset van de Euclidische ruimte. 2. Toestand: Daarnaast bevindt elk punt op het rooster zich in een bepaalde toestand. Het is van belang te melden dat de totale cellulaire automaat zich slechts in een eindig aantal toestanden kan bevinden. Dit impliceert dat elk punt op het rooster zich maar in een eindig aantal toestanden kan bevinden 3. Grenscondities: Deze schrijven voor wat er op de randpunten van het rooster gebeurt. In principe kan het rooster oneindig groot zijn, maar in computersimulaties wordt het rooster uiteraard altijd afgebakend. 4. Transitieregels: De transitieregels schrijven voor hoe de toestanden op het rooster veranderen van tijdstip i naar tijdstip i+1. Naburige cellen spelen daarbij in de regel een grote rol: Een toestand cel kijkt naar de toestand van diens buren en naar zijn eigen toestand en aan de hand van een bepaalde transitieregel wordt de volgende toestand in de cel bepaald. Agents
Het implementeren van een actor kan dus worden gerealiseerd aan de hand van cellulaire automaten, maar daarnaast kan ook worden gekozen voor zogenaamde ‘agent-modellen’. Er is in het algemeen (nog) geen consensus over een uniforme definitie van het begrip agent. De definitie van een agent is momenteel onderwerp van discussie in academische kringen. De reden hiervoor is dat de eigenschappen van een agent verschillen in de afzonderlijke domeinen waarin agents worden gebruikt. Maar hoewel de verschillende definities onderling verschillen, zijn ze het eens dat een agent in ieder geval aan het volgende voldoet: Een agent is een sofware component die gesitueerd is in een bepaalde omgeving en in staat is om autonome acties uit te voeren in deze omgeving om zijn ontwerp doelen te bereiken. [5][6][7] Aan een agent kan gedrag worden toegekend dat overeenkomt met de werking van een model. En hoewel het niet expliciet genoemd is in de definitie kan worden aangenomen dat agents in staat zijn te communiceren met elkaar. Zo kunnen verschillende modellen in de vorm van agents informatie met elkaar uitwisselen. Complexe automaten Definitie
Nu de “bouwstenen” bekend zijn, kan worden gekomen tot het concept waarmee multi-scale complexe systemen kunnen worden gemodelleerd: Complexe automaten. Complexe automaten worden geïntroduceerd in [8] en kunnen als volgt worden beschreven: Een complexe automaat is een verzameling van Cellulaire automaten en agent-based modellen die gezamenlijk de bouwstenen van een model vormen door op een zekere manier aan elkaar gekoppeld te zijn.
7
Compositie
Een complex systeem kan worden gedecomposeerd in subsystemen. Elk van de subsystemen heeft zo zijn eigen interne dynamiek. Deze dynamiek kan worden geïmplementeerd in een cellulaire automaat of agent. Overigens kan een gegeven automaat zelf ook weer bestaan uit een verzameling automaten en zo krijgen we te maken met zogenaamde Hiërarchische koppeling, hierover staat meer informatie in hoofdstuk 4. Communicatie
Omdat het een complex systeem betreft, zullen de agents en/of automaten met elkaar moeten communiceren. Zij zijn daarom gekoppeld door middel van het delen van informatie op hun input en output kanalen. In deze koppeling zit de uitdaging van de complexe automaat. Zij wordt namelijk gekarakteriseerd door een aantal eigenschappen van de gedeelde informatie. De gedeelde informatie kan ‘resolved’ of ‘lumped’ zijn, of een mix tussen beide. In het geval ‘resolved’ data is het signaal dat wordt gedeeld een functie van tijd en ruimte. Hier moet men denken aan bijvoorbeeld randcondities van een automaat. De automaten die naast elkaar liggen wisselen informatie uit over hun grensgebied; deze informatie is dus per definitie afhankelijk van tijd en ruimte. Het tegenovergestelde van ‘resloved’ is ‘lumped’: De data is dan dus niet afhankelijk van tijd en ruimte. Als bijvoorbeeld een automaat in zijn geheel een parameter representeert voor een andere automaat, dan is deze data dus niet tijd of ruimte gebonden. Merk op dat automaat die als parameter dient, op zichzelf wel weer tijd- of ruimtegebonden is, en daardoor is de koppeling dat impliciet ook. Om deze reden is er een breed grensgebied tussen ‘resolved’ en ‘lumped’ koppeling. Smart Conduit
Vanwege het feit dat de communicerende subsystemen elk hun eigen dynamiek hebben, zal het in de meeste gevallen zo zijn dat de informatie die verstuurd wordt door het ene subsysteem, niet onmiddellijk wordt begrepen door het andere subsysteem. Een interface is dan noodzakelijk om informatie uitwisseling correct te laten verlopen. Een zogenaamde Smart Conduit kan de rol aannemen van een dergelijke interface. Een subsysteem communiceert dan direct met de Smart Conduit, die vervolgens deze informatie verwerkt en in gepaste vorm aflevert aan het andere subsysteem. De Smart Conduit is ook verantwoordelijk voor de omgekeerde weg. Scale Map
De scheiding van schalen van de subsystemen kan vooraf bekend zijn of deze kennis kan worden verkregen door het bestuderen van deze subsystemen. Als van elk subsysteem de tijd- en ruimte schaal bekend is, dan worden zij in de regel geplaatst in een scale map. Dit is een xy-rooster met op de horizontale as de tijdschaal en op de verticale as de ruimteschaal. Elk systeem neemt op het rooster een ruimte in die correspondeert met hun karakteristiek schaal en op deze manier wordt de spatiele en temporele relatie tussen de systemen geschetst. Figuur 1 laat een voorbeeld van een scale map zien. Subsysteem 1 vindt plaats op relatief kleine ruimte en in korte tijd, systeem 2 neemt meer ruimte en tijd in, en systeem 3 opereert op grote schaal.
8
Figuur 1: Scale Map (afbeelding afkomstig uit[ 8])
9
Hoofdstuk 2: JADE Introductie Wat is JADE?
JADE is een acroniem voor “Java Agent DEvelopment Framework”. JADE is een speciaal soort middleware dat de ontwikkeling van gedistribueerde multi-agent applicaties ondersteunt. Deze applicaties zijn gebaseerd op het peer-to-peer communicatie principe. Naast de functie van ontwikkelingondersteunend platform voor agent applicaties dient JADE tevens als Agent Platform. Dit houdt in dat JADE de benodigde services aanbiedt aan agents zodat zij in staat zijn op een correcte manier te executeren. Ten slotte biedt JADE de gebruiker een grafische user interface aan, waarmee de agents in het systeem kunnen worden beheerd. Vanuit deze GUI kunnen agents worden aangemaakt of gestopt, kunnen bepaalde agents worden gevolgd, kunnen er boodschappen worden verstuurd naar agents, etcetera. Kerneigenschappen
Een JADE platform kan draaien op één host of meerdere hosts. Als er op het platform meerdere hosts aanwezig zijn, dan kunnen agents, informatie, en andere resources volledig gedistribueerd zijn over al die hosts. Dit is mede mogelijk, omdat het systeem volledig is geïmplementeerd in Java. Volgens [9] is JADE gebaseerd op de volgende drie kernprincipes:
Interoperability (interoperationeel): Omdat JADE de richtlijnen van de FIPA volgt, is het in staat samen te werken met andere agent platformen die ook deze richtlijnen volgen. De FIPA (“Foundation of Intelligent Physical Agents”) is een IEEE organisatie die de standaardisatie van agent systemen tot doel heeft [10]. Uniformiteit en operabiliteit: Het platform biedt de gebruiker een set van API’s aan die onafhankelijk zijn van de geïnstalleerde Java versie, het operating systeem of van het netwerk waarop het platform draait. Gebruikersgemak: De complexiteit van de middleware wordt verborgen achter de set van API’s van het systeem. Daarnaast heeft JADE als voordeel dat een bepaald onderdeel van het systeem kan worden gebruikt, zonder dat enige kennis van andere delen van het systeem is vereist.
Architectuur JADE biedt zowel de vereiste bibliotheken aan om agent applicaties te ontwikkelen, als de runtime omgeving die aan de agents de basisservices leveren om correct te kunnen functioneren. Alle agents in het systeem leven in zogenaamde containers. Een container biedt huisvesting aan één of meer (semantisch gerelateerde) agents. Op hun beurt kunnen er zich weer één of meerdere containers op één host bevinden. De containers zijn de objecten die de eigenlijke services bieden aan de agents. Zij zorgen voor zowel de communicatie tussen de agents in de container zelf, als voor de communicatie tussen de verschillende containers. Dit laatste gebeurt op verschillende manieren. Een aantal standaard protocollen (onder andere IIOP) worden standaard meegeleverd bij de creatie van een container, maar JADE is flexibel: er kunnen andere, eventueel zelf ontworpen protocollen worden meegegeven aan een container. 10
Bovendien wordt er door een container in bepaalde gevallen gebruik gemaakt van RMI (remote method invocation). De verzameling van alle containers in het systeem wordt het platform genoemd. Het container principe fungeert in feite als een abstractie laag die de complexiteit van de onderliggende hardware, het operating systeem en het type netwerk verhult. Functionaliteit Vanuit functioneel oogpunt biedt JADE de diensten aan die noodzakelijk zijn om de gedistribueerde peer-to-peer applicaties te draaien. Elke agent heeft de mogelijkheid om dynamisch andere agents in het systeem te ontdekken en om vervolgens met hen te communiceren. Standaard services
Elk agent systeem dat de richtlijnen van de FIPA volgt beschikt tenminste over de volgende drie zaken: AMS (Agent Management System), DF (Directory Facilitator) en ACC (Agent Communication Channel). Het systeem registreert nieuwe agents met behulp van een speciale agent, de AMS. Deze agent controleert de toegang tot het platform en houdt een registratie bij van welke agent in welke container leeft. Als een agent een boodschap verstuurt, dan wordt de AMS geraadpleegd over de locatie van de ontvanger. Er is exact één AMS per JADE platform. De DF is een agent die bijhoudt welke agents welke soorten diensten aanbieden. Als een agent een bepaalde dienst levert, dan registreert hij dat bij de DF. Mocht een agent een bepaalde dienst zoeken, dan zal hij de DF raadplegen of er een agent in het systeem is die deze dienst aanbiedt, en zo ja, waar hij die kan vinden. De ACC ten slotte, zorgt voor de correcte aflevering van boodschappen tussen agents die in verschillende platformen leven. Elk JADE platform beschikt over een speciaal soort container, een zogenaamde Main Container, waarin de ANS en de DF leven.
Figuur 2: Componenten van de JADE architectuur (afbeelding afkomstig uit[13])
11
ACLMessages
Agents communiceren met elkaar door het uitwisselen van asynchrone boodschappen. Deze boodschappen nemen de vorm aan van “ACL Messages”, een standaard die ontwikkeld is door de FIPA [11]. Met deze standaard kunnen multi-agent systemen die hieraan voldoen met elkaar communiceren zonder enige verdere kennis van elkaar te hebben. Het enige wat een afzender hoeft te doen, is een unieke naam van de ontvanger op te geven, en de boodschap wordt verstuurd. Er is geen tijdafhankelijke relatie tussen twee agents: Op het moment van sturen kunnen de afzender en ontvanger beide beschikbaar zijn, maar dat hoeft niet. Het is mogelijk dat de ontvanger is zijn geheel niet bestaat, of nog niet bestaat. Daarnaast is het voor de afzender mogelijk om een boodschap te sturen naar een groep agents die aan een bepaalde conditie voldoen, bijvoorbeeld aan alle agents die hebben opgegeven geïnteresseerd te zijn in boodschappen met eigenschap X. Een ACL Message bestaat uit een verzameling parameters die allemaal door een agent naar eigen inzicht kunnen worden ingevuld [16]. Figuur 3 laat alle mogelijke variabelen van een ACLMessage zien. Deze variabelen kunnen bijvoorbeeld aangeven in welke context de boodschap is gestuurd of wanneer een antwoord wordt verwacht. De variabelen ondersteunen dus het voeren van complexe conversaties en interacties tussen agents. Daarnaast biedt JADE een verzameling templates aan van typische interactie patronen gericht op specifieke taken, zoals bijvoorbeeld onderhandelingen, veilingen en taak delegatie.
Figuur 3: FIPA ACL Message Parameters (afbeelding afkomstig uit[16])
12
Hoofdstuk 3: Communicatie performance van JADE Introductie Als men een bestaand framework wil gebruiken, dan is het verstandig aanvankelijk te bepalen wat de sterke en zwakke eigenschappen van het framework zijn. In het geval van gedistribueerde peer-to-peer applicaties is de communicatie performance vooral van belang, omdat de uiteindelijke efficiëntie van het programma grotendeels afhankelijk is van de communicatie tussen entiteiten binnen de applicatie. Voor een complexe automaat die geïmplenteerd is in JADE zullen deze entiteiten de vorm aannemen van agents. De agents representeren een deel van het model en zullen informatie moeten uitwisselen met andere agents. Eventueel vindt deze communicatie plaats met tussenkomst van een smart conduit, die besproken is in hoofdstuk 1. In een complexe automaat van enige proportie kunnen vele honderden agents voorkomen die allen (tegelijkertijd) met elkaar willen communiceren. Het is dus evident dat van JADE bekend moet zijn hoe het presteert in point-to-point communcatie. In dit hoofdstuk worden experimenten en resultaten besproken die betrekking hebben op de communicatie performance van JADE. Allereerst zal een aantal eerdere artikelen over reeds uitgevoerde onderzoeken worden besproken. Daarna volgt een beschrijving van een experiment dat is uitgevoerd in het kader van deze scriptie. Vorig werk In het verleden zijn er onderzoeken gedaan naar de communicatie performance van JADE. Er worden er hier twee besproken. ‘A Performance Analysis of Multi-Agent Systems’
Dit is een onderzoek van Jurasovic, Jezic en Kusek. Het artikel waarin het onderzoek wordt gepresenteerd is verschenen in 2006 in [12]. Het doel van de auteurs is het vergelijken van twee multi-agent systemen, namelijk JADE en Grasshopper. Grasshopper is een mobiel agent platform dat draait bovenop een ‘distributed processing environment’. Het grote verschil met JADE is dat dit systeem (ten tijde van het onderzoek) de richtlijnen van de FIPA niet volgt. Experiment
Om de performance van de systemen te bepalen, wordt (onder andere) de gemiddelde roundtrip tijd bepaald. Dit is de tijd die het kost om een ACL boodschap van verzender naar ontvanger te sturen, plus de tijd die een antwoordboodschap nodig heeft om de verzender te bereiken. In de experimentopstelling bestaan een SendAgent en een ReceiveAgent en die wisselen gedurende dertig minuten boodschappen uit. Daarnaast wordt de communicatie overhead per verstuurd bericht bepaald, als functie van de berichtgrootte. Resulaten
De resultaten zijn te zien in figuur 4. Uit de figuur kan worden opgemaakt dat de JADE sneller is als de boodschappen relatief groter zijn (> 16kb), Grasshopper is sneller bij kleinere berichten. Uit tabel (1) blijkt dat de communicatie overhead bij JADE kleiner is, maar dat ze niet veel voor elkaar onderdoen. Voor beide systemen geldt dat de communicatie overhead klein is. Daarnaast valt op dat de communicatie overhead tot berichten van ongeveer 4 kb constant is. 13
Figuur 4: Gemiddelde roundtrip tijden van JADE uitgezet tegen die van Grasshopper (afbeelding afkomstig uit [12])
Tabel 1: Overhead per verzonden boodschap (tabel afkomstig uit [12])
’Scalability and Performance of JADE MTP’
De schrijvers van dit artikel zijn Cortese, Quarta en Vitaglione [13], destijds allen werkzaam bij TILAB, de organisatie die verantwoordelijk is voor de ontwikkeling van JADE. Experiment
Ook in dit experiment wordt de gemiddelde roundtrip tijd bestudeerd om de performance van JADE te bepalen. Omdat de auteurs echter ook de schaalbaarheid van het systeem willen testen, bepalen zij de gemiddelde roundtrip tijd als functie van het aantal koppels dat berichten naar elkaar verstuurd. Er worden n Send- en ReceiveAgents opgestart en elk ie koppel wissel 10.000 berichten met elkaar uit. De onderzoekers houden rekening met het feit dat het processor- en geheugencapaciteit kost om de agents te creëren, en beginnen daarom pas met meten zodra alle agents zijn opgestart. Naast het testen van de performance en schaalbaarheid van JADE wordt ook gekeken naar hoe de uitkomsten van het experiment verschillen als er geen gebruik wordt gemaakt van de JADE middleware. De onderzoekers hebben het experiment herhaald met een implementatie waar agents en hun communicatie worden gesimuleerd aan de hand van respectievelijk verschillende threads en het RMI principe van Java.
14
Resultaten
De performance metingen zijn te vinden in figuur 5. In het experiment is rekening gehouden met de plaats waar de agentkoppels zich bevinden. De lijn die op de punten rondjes heeft, laat het gedrag zien van de gemiddelde roundtrip tijd als de koppels zich op dezelfde host, in dezelfde container bevinden. De ACLMessage wordt in dit scenario niet echt verstuurd, maar een pointer naar de message wordt meegegeven aan de ontvanger. De lijn met de driehoeken op de punten beschrijft het scenario waarin de verzender en ontvanger in aparte containers zitten, op verschillende hosts. De lijn met de vierkanten geeft het verband tussen het aantal koppels en tijd weer wanneer de agents zich op één host bevinden, maar ontvanger en verzender in een aparte container zitten. De gemiddelde roundtrip tijd is in het laatste geval hoger, omdat er maar één processor aanwezig is voor beide agents, waardoor zij dus de cpu-cycles moeten delen. Figuur 6 illustreert de resultaten van het experiment waarin de performance van een JADE implementatie tegen een zelfontwikkelde implementatie wordt uitgezet. Het is opmerkelijk te zien dat de performance van JADE vele malen beter is, dan wanneer er slechts gebruik wordt gemaakt van threads voor agents en RMI voor onderlinge communicatie. De gemiddelde roundtrip tijden verschillen met een factor tien.
Figuur 5: Gemiddelde roundtrip tijden (afbeelding afkomstig uit [13])
15
Figuur 6: JADE versus RMI (afbeelding afkomstig uit [13])
Beschrijving experiment In de context van deze scriptie is zelf ook een experiment opgezet en uitgevoerd. Net zoals bovenstaande experimenten is het doel van dit onderzoek de communicatie performance van JADE te onderzoeken, en ook hier is de gemiddelde roundtrip tijd een maat voor het presteren van het systeem. In dit experiment wordt de gemiddelde roundtrip tijd gemeten als functie van de grootte van het bericht dat wordt verstuurd. Er is een SendAgent en een ReceiveAgent. De SendAgent stuurt een pakket van n bytes naar de ReceiverAgent en als deze het pakket ontvangen heeft, dan stuurt deze het onmiddellijk weer terug. Dit wordt honderd keer gedaan, waarna een gemiddelde tijd, en de standaard deviatie worden berekend. Er wordt gestart met 10 kilobytes en na honderd onderlinge zendingen wordt het wordt het pakket met 10 kilobyte verhoogd. Aanvankelijk wordt zo doorgegaan tot en met 400 kilobytes. Daarnaast zal een grafiek worden besproken die doorgaat tot 1024 kilobytes (= 1 Mb), met stappen van 1 kilobyte. Er worden drie scenario’s onderscheiden: 1. Sender en Receiver zitten op dezelfde host, in dezelfde container 2. Sender en Receiver zitten op dezelfde host, in aparte containers 3. Sender en Receiver zitten op verschillende hosts (in verschillende containers) Daarnaast dient nog te worden opgemerkt dat de Sender en Receiver niet in de main container zitten. Dit is gedaan om de invloed van deze container op de uitkomst van het experiment zoveel mogelijk te beperken. Opstelling
Het experiment is gedaan met de volgende opstelling: Hosts:
Netwerk:
CPU: Geheugen: OS:
Intel Pentium 4, 2.79 Ghz 504 MB RAM Linux kernel 2.4 100 Mbps Ethernet network 16
Hypothese
De verwachting is dat relatie tussen het aantal verzonden bytes en de gemiddelde roundtrip tijd linear is. In een formule: gemiddelde tijd = ( a* aantal bytes) + b waarbij, a = 1 / throughput b = latency Resultaten Hier volgen de resultaten van het experiment.
Figuur 7: 1 host, 1 container 1 host, 1 container
Figuur 7 illustreert de resultaten in het geval dat beide agents in dezelfde container, op dezelfde host zitten. De balkjes geven de standaardafwijking weer. Twee zaken vallen hier op: Ten eerste is duidelijk te zien dat er knikken in de grafiek zitten, wat impliceert dat het verzenden van een kleiner pakket in een aantal gevallen langer duurt dan het versturen van een groter pakket. Daarnaast is er bij een pakketgrootte van 340 kilobyte een knik te zien; de grafiek schiet hier omhoog.
17
Figuur 8: 1 host, 2 containers 1 host, 2 containers
Figuur 8 illustreert de resultaten in het geval dat beide agents op dezelfde host executeren, maar in verschillende containers zitten. Ook in dit geval valt het op dat er knikken in de grafiek zitten.
18
Figuur 9: 2 hosts, 2 containers
Figuur 10: 2 hosts, 2 containers, interval van 1kb - 10 kb 2 hosts, 2 containers
Figuur 9 illustreert het geval dat de agents in een aparte container zitten, op verschillende hosts. De groene lijn laat de uitkomsten van het experiment zien. De blauwe lijn laat dit ook zien, maar waarden zijn uitgemiddeld met hun twee linker- en 19
twee rechterburen. De rode lijn laat een lineaire fit zien. In de figuur is op 10 kb een knik te zien. In figuur 10 worden nogmaals de resultaten getoond, maar dan voor het interval 1 kb tot en met 10 kb. Hier doorheen is ook een lineaire fit gedaan. Deze laatste fit geeft de waarden voor bovengenoemde a en b: a = 1,0818 * 104 ms / bytes b = 3.4760 ms De throughput is dan: 1 / a = 1 / 2.2708 * 10-4 ms / bytes = 4.4037 * 106 bytes / s
Figuur 11: 2 hosts, 2 containers, 1024 metingen
20
Figuur 12: Fit door de data vanaf 400 kb 2 hosts, 2 containers, 1024 metingen
Figuur 11 laat wederom het scenario van 2 hosts, 2 containers zien, maar dan met een eindconditie van 1 Mb. De stapgrootte is nu geen 10 kb, maar 1 kb.Wat in deze grafiek opvalt, is dat er vanaf 400 kilobyte opmerkelijk gedrag ontstaat. Figuur 12 toont dezelfde data als in figuur 11, maar dan vanaf 400 kb. Daarnaast is er een fit te zien in de vorm van een rode lijn. Deze fit geeft de volgende waarde voor a en b: a = 1.3077 * 10-4 ms / bytes b = 38.794 ms De throughput is dan: 1 / a = 1 / 1.3077 * 10-4 ms / bytes = 7.647 * 106 bytes / s
21
Figuur 13: Het effect van JIT 2 host, 2 containers, het effect van JIT
Figuur 13 laat een aantal meetpunten zien die zijn verkregen aan de letterlijke start van het experiment, dus wanneer het programma net begint met executeren. Er is een duidelijke knik te zien in het begin van de grafiek. Dit heeft te maken met de JITtechniek die Java gebruikt. Hierover meer in de volgende paragraaf. Discussie en conclusies Allereerst kan geconcludeerd worden dat de hypothese van lineariteit niet opgaat in scenario’s 1 en 2. Een mogelijke verklaring waarom dat geldt voor scenario 1, is dat er feitelijk geen sprake is van het verzenden van een boodschap, zoals eerder al is opgemerkt. Er wordt een pointer naar de boodschap doorgegeven aan de bestemmingsagent; een proces dat lokaal op de cpu wordt bewerkstelligd. Als de cpu andere prioriteiten heeft, dan zou dat de meetresultaten kunnen beïnvloeden. In scenario 2 wordt RMI toegepast. Ook hier geldt dat de berekeningen lokaal worden geregeld, dus het kan zijn dat het cpu scheduling algoritme hier een rol speelt. Dit zou een oorzaak kunnen zijn voor de piek op 130 kb en het dal op 290 kb. Interessanter zijn de resultaten van scenario 3. De complexe automaat zal immers bestaan uit vele agents en zij zullen fysiek verspreid zijn over meerdere hosts. Dit scenario is dus het meest reëel in een echte implementatie van een complexe automaat. In het geval van scenario 3 gaat de hypothese van lineariteit op tot en met
22
400 kb. Aangezien de spreiding van de uitkomsten per honderd zendingen vrij hoog is, kan een lineaire plot van de data gerechtvaardigd worden. Wat voor verbanden er zijn na 400kb is onduidelijk. Er lijkt een rechte lijn te trekken te zijn door de ruis in het gebied van 450kb tot en met 780 kb. Na een sprong kan dit nogmaals worden gedaan voor het gebied van 790kb tot en met 1 Mb. Mogelijkerwijs zou het wisselen van protocol, wat in JADE mogelijk is, een andere dataset opleveren, waarbij een verband duidelijker is. Er kan ook worden gedacht aan het omdraaien van het experiment: Eerst de grote boodschappen afleveren en zo afbouwend naar de kleinste. Zo zouden factoren als geheugenallocatie, die de performance beïnvloeden, worden blootgelegd. De throughput van JADE ligt in de eerste 400 kb op ongeveer 4 Mb per seconde. Dit doet vermoeden dat JADE, naast het versturen van de daadwerkelijke boodschap, meer data meestuurt, wellicht voor het afhandelen van administratieve zaken. Vanaf 400 kb, ligt de gemiddelde throughput hoger, namelijk op ongeveer 8 Mb per seconde. Dit zou het vermoeden bevestigen, omdat er bij grote berichten relatief meer data tot de echte boodschap behoort. Ook in ‘A Performance Analysis of Multi-Agent Systems’ worden boodschappen van variabele lengte rondgestuurd en de gemiddelde roundtrip tijd gemeten. Als de resultaten van hun onderzoek worden uitgezet tegen de resultaten van het onderzoek in het kader van deze scriptie, dan blijkt dat die redelijk overeenkomen. Hun grafiek (figuur 4) heeft echter een lagere resolutie, gaat tot 512 kb in plaats van 1 Mb en heeft een logaritmische x-as. Als we figuur 10 aanpassen aan het bevenstaande, dan krijgen we een grafiek die hetzelfde gedrag vertoont als de grafiek in figuur 4. Ten slotte nog een opmerking over de Java Virtual Machine (JVM). De JVM hanteert de Just-in-time (JIT) techniek. Dit houdt in dat de bytecode tijdens runtime wordt geoptimaliseerd. In het begin van de executie wordt een programma daardoor iets trager, omdat JIT geheugen en cpu-cycles gebruikt. In het uitgevoerde experiment is hier rekening mee gehouden. Er is pas begonnen met meten, nadat JIT klaar was met optimaliseren.
23
Hoofdstuk 4: Coupling mechanismen in de Complexe automaat Inleiding De mogelijkheid van de submodellen om informatie met elkaar uit te wisselen ligt aan de basis van het complexe automaten concept. De submodellen hebben allen hun eigen interne dynamiek en de manier waarop deze dynamiek zich manifesteert is afhankelijk van input van gerelateerde (sub)modellen. Elk submodel in een systeem heeft zo zijn eigen intrinsieke eigenschappen met zijn eigen data set en dat maakt het koppelen van twee willekeurige submodellen tot de grootste uitdaging voor de ontwerper van een Complexe automaat. Men zou kunnen beredeneren dat elke koppeling tussen twee verschillende submodellen uniek is, omdat elk submodel op zijn manier uniek is. Toch zou het erg handzaam zijn als er een methode is om generieke uitspraken te doen over soorten koppeling tussen systemen. In dit hoofdstuk zal blijken dat de koppelingen tussen multi-scale modellen in een Complexe automaat kunnen worden geclassificeerd. Zodoende kunnen algemeen geldende uitspraken worden gedaan over koppelingen tussen submodellen, afhankelijk van hun onderlinge tijd en ruimteschaal relatie. Modellen als Cellulaire automaat Formele beschrijving
De subsystemen van een Complex systeem kunnen worden gerepresenteerd aan de hand van modellen. Deze modellen kunnen op hun beurt weer de vorm aan nemen van een Cellulaire automaat. Volgens [14] voldoet de zo ontstane automaat aan de volgende eigenschappen: Model M is een functie: M: F F waarbij F de verzameling is van alle mogelijke configuraties waarin het model zich kan bevinden. M wordt dan volledig beschreven door: M [ P, C, B, D, f init ] Waarbij de symbolen de volgende operatoren of variabelen voorstellen: P ‘propagation’ operator C ‘collision’ operator B ‘boundary’ collision operator D simulatie domein init f initiële f waarde Dit formalisme kan vervolgens worden toegepast op de cellulaire automaten die de modellen representeren. De functie van operator ‘P’ is het sturen van de toestand van een automaat die ‘P’ uitvoert naar één of meerdere aangrenzende gekoppelde automaten. De ‘C’ operator is verantwoordelijk voor het updaten van de interne toestand van de automaat, afhankelijk van de informatie die binnenkomt via de ‘P’ operator en de geldende update regels van de automaat zelf. De functionaliteit van de ‘B’ operator is in feite identiek aan de ‘C’ operator, met als enige verschil dat de ‘B’ operator de toestand updatet aan de randgebieden van de automaat, als er in de
24
automaat sprake is van een rand. Het symbool ‘D’ is een variabele die het domein van de automaat voorstelt. Dit domein neemt de gestalte aan van een graaf, waarin de knopen de cellen voorstellen waaruit de automaat bestaat. Ten slotte beschikt een model M over de variabele finit, die simpelweg de initiële toestand weergeeft van de automaat. Executieverloop
Nu alle eigenschappen van een model bekend zijn, kan de executie van de cellulaire automaat worden beschreven aan de hand van de volgende pseudo-code: f ← finit while ¬ EndCondition do D ← U( D ) f ← B( f , D ) f ← C( f , D ) f ← P( f ) Oi(f,D) end while Of(f,D) Stap voor stap de code langslopend, gebeurt er het volgende: Allereerst wordt de toestand van de cellulaire automaat op diens begintoestand gezet. Zolang de eindconditie nog niet is bereikt, wordt er eerst een update op het domein uitgevoerd. Het kan namelijk zo zijn dat de graaf door bepaalde interne of externe omstandigheden veranderd wordt. Daarna wordt de nieuwe toestand berekend op het randgebied van de automaat. Vervolgens wordt de nieuwe toestand berekend in de rest van de automaat. Dan wordt de nieuw berekende toestand van een cel opgestuurd naar andere, naburige cellen. Hierop volgend is er een output moment. Hierin kunnen overige automaat-gerelateerde zaken worden uitgevoerd. Als de eindconditie is bereikt, dan volgt er een definitief output moment. Het is afhankelijk van het type model wanneer een eindconditie bereikt is. Het kan zo zijn dat deze conditie eenvoudigweg bereikt is als het vooraf opgegeven maximaal aantal iteraties is uitgevoerd. Daarnaast is het mogelijk dat de eindconditie afhankelijk is van de ontwikkelingen in de automaat zelf. Zo kan deze conditie bijvoorbeeld bereikt zijn als er zich een evenwichtssituatie voordoet in de automaat. Koppeling paradigma’s Zoals gezegd opereren de automaten in de complexe automaat mogelijk op verschillende tijd- en ruimteschalen. Omdat er twee soorten schalen (ruimte en tijd) worden beschouwd, valt de koppeling tussen twee automaten op te splitsen in vier verschillende gevallen: 1. 2. 3. 4.
Tijd en ruimteschaal overlappen Tijdschaal is hetzelfde, ruimteschaal verschilt. Ruimteschaal is hetzelfde, tijdschaal verschilt. Zowel ruimte als tijdschaal zijn verschillend
In het geval dat zowel de tijd- als ruimteschaal verschillen, kan ook een onderscheid in koppeling worden gemaakt. In het geval van de zogenaamde ‘Hierarchical 25
Coupling’ is er een koppeling tussen een relatief snel en op kleine ruimte opererend systeem, met en relatief traag en op een grotere ruimte opererend systeem. Meestal is hier dan sprake van meerde instanties van het ‘kleine’ systeem die interacteren met het grote systeem. De omgekeerde koppeling bestaat ook: Een systeem dat snel is, maar op een relatief grote ruimte opereert, is gekoppeld aan een systeem dat een kleinere ruimte inneemt, maar langzamer is. Er wordt gedacht dat dit laatstgenoemde koppelingsmechanisme relevant is bij het verbinden van biologische processen met fysische processen[15]. In [14] wordt expliciet voor elk scenario uit de doeken gedaan waar de koppeling voor dat scenario plaatsvindt. Meer specifiek: welke operator in de bovenstaande pseudocode voor model M1 is afhankelijk van de input van welke operator in de code van model M2, en vice versa. De complexe automaat kan nu zelf worden beschouwd als een graaf, waarbij de knopen in deze graaf de verscheidene instanties van de modellen voorstellen. Als er een kant is tussen twee knopen, dan wil dat zeggen dat er een koppeling is tussen de systemen die de knopen representeren. Implementatie In het kader van deze scriptie is één van de koppelingen geïmplementeerd, namelijk de hierarchical coupling. Er is één agent die het macromodel representeert en meerdere agents die de micromodellen representeren. De microagents communiceren allemaal met de macroagent en de macroagent communiceert weer met hen. De agents in het programma voeren geen taken uit die gerelateerd zijn aan een model uit de praktijk, maar updaten hun state via een random functie. In het programma zou deze functie probleemloos kunnen worden vervangen door een update functie die wel betekenis heeft. De Java klassen die de states van de agents representeren zouden dan wel aangepast moeten worden. De agents in het programma zijn geschreven in Java en maken gebruik van de API van JADE. Nu volgt een beschrijving van het geschreven programma dat de koppeling realiseert. De code van het programma is te vinden in Appendix A Executieverloop
Hoewel de agents in dit programma geen echte cellulaire automaten zijn, volgen ze in dit programma in zekere zin wel dezelfde flow of execution als die hierboven in pseudocode is beschreven voor cellulaire automaten. De operatoren uit de code dienen dan wel op een iets andere manier te worden geïnterpreteerd. De aanwezige agents hebben namelijk geen domein, dus hoeft die ook niet te worden geüpdatet en ook de randen hoeven om dezelfde reden niet te worden beschouwd. Ook propagate is niet nodig, want die operator is bedoeld om informatie tussen cellen uit te wisselen, maar er is maar één cel, namelijk de agent zelf. Tijdens de collision fase bepaalt de agent voor zichzelf hoe zijn interne toestand verandert, afhankelijk van de op dat moment beschikbare informatie. Er dient wel te worden benadrukt dat specifiek in dit programma sommige operatoren niet nodig zijn of een andere intepretatie krijgen. Het kan namelijk zo zijn dat een complexe automaat een cellulaire automaat als onderdeel heeft, waarvan diens cellen bestaan uit agents. De agents vormen dan het domein van de automaat en wisselen bijvoorbeeld informatie uit tijdens hun propagate fase.
26
Overzicht van executieverloop
Een overzicht de structuur van het programma wordt geïllustreerd door figuur 14.Het programma begint met het opstarten van een CxA agent, die op zijn beurt de MacroAgent opstart. Dan wordt de agent StartMicros opgestart. Deze maakt een gegeven aantal MicroAgents aan. Aan de agents wordt bij hun initialisatie een zeker gedrag toegekend. De gedragsregels worden geïmplementeerd in een CyclicBehaviour klasse. Een agent voert alle instructies van zijn gedrag uit en bepaalt vervolgens of hij klaar is met zijn taak. Als dat zo is, dan stopt de agent. Als dat niet zo is, dan begint hij zijn gedrag opnieuw uit te voeren. De opgestarte MicroAgents beginnen met het uitvoeren van hun gedrag, terwijl de MacroAgent nog even wacht. Na een zeker (vooraf bepaald) aantal iteraties X zijn ze klaar en sturen ze hun state op naar de MacroAgent. De MicroAgents hebben nu X iteraties van de bovenstaande pseudocode uitgevoerd Hun state wordt beschreven in een State object, die wordt geserializeerd en opgestuurd. De MacroAgent is inmiddels aan het wachten tot hij alle states heeft binnengekregen. Als dat laatste het geval is, dan begint hij aan zijn collision-operator. De interne staat van de MacroAgent wijzigt hierdoor. Afhankelijk van zijn nieuwe state, berekent hij de nieuwe initialisatie states van de MicroAgents. In de output fase van de MacroAgent stuurt hij alle nieuwe initialisatie states op naar de MicroAgents. De MacroAgent heeft nu één iteratie van de bovenstaande pseudocode uitgevoerd. De MicroAgents ontvangen hun nieuwe initialisatie states en beginnen weer van voor af aan. De automaat eindigt als de MacroAgent een vooraf aangeven iteraties heeft doorlopen. MicroAgents
De MicroAgents in dit programma doorlopen een bepaalde levenscyclus. Allereerst worden ze aangemaakt door de StartMicros Agent. Ze krijgen dan een gedragobject mee, dat aangeeft wat ze moeten doen. Ze sturen een bericht naar de MacroAgent om zich aan te melden. Vervolgens doorlopen ze herhaaldelijk de loop die gegeven in de eerder genoemde pseudocode. Omdat de MicroAgents in dit programma geen onderdeel vormen van een echt biologisch of fysisch model, hebben zij slechts dummy variabelen, die gedefinieerd worden in een MicroModelState object. De variabelen nemen de vorm aan van een vooraf bepaald aantal integers. In de collisionfase van de MicroAgents krijgen deze integers via een random generator een nieuwe waarde toegekend. Dit dient als simulatie van het updaten van de variabelen zoals dat gebeurt in een echt model. Nadat een zekere eindconditie is bereikt, wordt het MicroModelState object geserializeerd en opgestuurd naar het MacroModel. Daarna zal de MicroAgent gaan staan wachten totdat hij een nieuw MicroModelState ontvangt. Op het moment dat hij deze ontvangt, wordt dit object gebruikt als nieuwe initialisatie state. Vanaf dit punt gaat de MicroAgent de loop weer in, totdat de eindconditie is bereikt. Zo voltrekt dit proces zich een aantal keer, totdat de MacroAgent besluit dat de automaat de definitieve eindconditie heeft bereikt. MacroAgents
Ook de MacroAgent doorloopt een cyclus. Nadat de MacroAgent is geinitialiseerd door de CxA agent, zal hij gaan wachten totdat hij alle aanmeldboodschappen heeft ontvangen van een vooraf gespecificeerd aantal MicroAgents. Als alle boodschappen zijn ontvangen, begint de cyclus. Eerst wordt van het domein een nieuwe state
27
uitgerekend in de collision operator. Vanwege het feit dat er bij deze MacroAgent geen sprake is van ‘randen’, is de implementatie van de ‘updateBoundery’ methode leeg gelaten. Dan volgt de collision operator. Hiervoor is het noodzakelijk dat eerst alle MircoAgents hun state hebben opgestuurd. Zodra dat is gebeurd, berekent de MacroAgent zijn eigen state. De state van de MacroAgent wordt gedefinieerd door een array waarvan de lengte gelijk is aan het aantal MicroAgents. De array is gevuld met integers en de waarde van de array op plek i is afhankelijk van de MicroModelState van MicroModel i. De waarde wordt namelijk berekend door de een integerwaarde uit MicroModelState te laten fungeren als input voor een random functie die de waarde van de array op plek i teruggeeft. Nogmaals, omdat de agents in dit programma geen submodellen voorstellen uit de ‘echte’ wereld, is hier gekozen voor een willekeurige functie in de collision-operator die qua complexiteit in de buurt komt van een collision-operator in een echt model. Na de collisio-operator volgt de propagate-operator, maar omdat de MacroAgent maar uit één cel bestaat, is ook deze methode leeg gelaten. Uiteindelijk wordt de output fase bereikt. Hierin worden de nieuwe states naar de MicroAgents gestuurd. Er is nu één ronde van de cyclus doorlopen. De MacroAgent bepaalt nu of de eindconditie is bereikt. Als dat niet het geval is, begint de cyclus weer van voren. Als de eindconditie wel is bereikt, wordt er een bericht gestuurd naar alle MicroAgents om ze in te lichten over het feit dat het einde is bereikt. De MacroAgent sluit zichzelf ten slotte af.
Figuur 14: Schema van de implementatie met drie MicroAgents. De vierkanten stellen agents voor. Een zwarte, dikke pijl wijst naar een agent die wordt geconstrueerd uit de agent van waaruit de pijl vertrekt. De ruiten stellen het geïmplementeerde gedrag voor. De dunne pijlen geven aan waartussen communicatie plaatsvindt.
Experiment
Om het het programma te testen, is een experiment gedaan. Er wordt bepaald hoe het programma zich gedraagt naarmate er meer microagents in het systeem aanwezig zijn. 28
De opzet van het experiment is als volgt: In een JADE platform wordt één MacroAgent opgestart, en tien containers. De containers executeren allemaal op een andere host. Die containers worden steeds opgestart met een vast aantal MicroAgents. Het totaal aantal MicroAgents wordt gelijk verdeeld over het aantal containers. De MicroAgents itereren viermaal voordat ze hun state doorsturen naar de MacroAgent. De MacroAgent itereert driemaal en zal daarna het programma stoppen. Het experiment is uitgevoerd met dezelfde opstelling als het experiment in hoofdstuk 3. In Appendix B wordt technisch beschreven hoe het experiment is uitgevoerd. Resultaten
Aantal MicroAgents 10 20 30 40 50 100 100 150 150 150 250 500
Toegekend geheugen aan de JVM (Mb) 64 (default) 64 64 64 64 64 128 128 512 1024 1024 1024
Opstarttijd (ms)
Totale runtijd (ms)
18469 19875 22233 23191 23596 23671 22369 26652 25762 25688 28574 29856
1144 2997 5523 8726 12693 -* 47512 403726 145363 149272 678378 -*
*) Programma eindigt in een crash Discussie en conclusies
Uit de tabel blijkt dat JADE geen problemen heeft als er vijftig of minder agents in het systeem zitten. Als er honderd agents worden opgestart, dan crasht het programma na een tijd. Twee containers krijgen dan geen berichten meer binnen. Als aan de JVM meer geheugen wordt toegekend, dan verloopt de executie zonder problemen. Het geheugen op een host blijkt de voornaamste bottleneck, en dan vooral het geheugen dat wordt toegekend aan het MacroModel. Beschouw het geval van 150 agents. De executietijd neemt met ruim een factor 2 af als 512 Mb wordt toegekend, in plaats van 128 Mb. Een verklaring voor dit feit ligt mogelijk in het gedrag van de JVM. Het aantal states dat de MacoAgent moet opslaan is hoog, en in het geval dat er slechts 128 Mb beschikbaar is, moet de JVM een pragmatische oplossing vinden om al deze states op te slaan. Intern zal de JVM bepaalde onderdelen uit het geheugen weggooien die op dat moment niet cruciaal zijn voor correcte executie. Als alle states zijn verstuurd, is er weer plek voor overige onderdelen. Dit alles levert een hoop overhead op en kost dus tijd. Vanaf 250 agents in het systeem wordt executie problematisch. Het geheugen zit dan helemaal vol. Herhaaldelijk toont JADE de volgende boodschappen:
29
INFO: MessageManager queue size < 10000000 jade.core.messaging.OutBox increaseSize WARNING: MessageManager queue size > 10000000 jade.core.messaging.OutBox decreaseSize
De queue van boodschappen voor de MacroAgent zit vol en het lijkt erop dat JADE bezig is om de queue te vergroten. Dit zal op een gegeven moment niet lukken, simpelweg omdat het geheugen vol zit. Daarop verkleint JADE de queue. Maar dan kunnen weer niet alle boodschappen worden opgeslagen. Zo ontstaat een vicieuze circel. Er zijn slechts twee (rigoureuze) methoden om dit probleem te omzeilen: De eerste is nóg meer geheugen toekennen. De tweede is de code herschrijven, zodat er efficiënter wordt omgegaan met geheugen. Wat verder opvalt is dat de opstarttijd nagenoeg constant is voor alle gevallen. De opstarttijd is de tijd die het kost voor de MacroAgent om alle MicroAgents te registreren. De constante tijd is te verklaren met het feit dat een aanmeldboodschap van een MicroAgent relatief zeer klein is en het de MacroAgent niet veel moeite kost om deze boodschappen te verwerken. De performance van dit programma is te verbeteren door beter geheugenbeleid te hanteren. In deze implementatie worden de states van alle MicroAgents tijdelijk opgeslagen door de MacroAgent. In plaats van zijn hele state object op te sturen, zou een MicroAgent alleen de wijzigingen in zijn state kunnen verturen. Daarnaast zou een MacroAgent kunnen worden opgesplitst in kleinere delen. Deze zouden dan op afzonderlijke hosts kunnen executeren, waardoor er relatief meer geheugen beschikbaar is voor de MacroAgent. Hierdoor ontstaat de mogelijkheid om één MacroAgent aan meer MicroAgent te koppelen, iets wat wenselijk is wanneer er modellen uit de echte wereld worden geïmplementeerd.
30
Eindwoord In deze scriptie is gekeken in hoeverre JADE een geschikt framework is voor complexe automaten. Er is een performance test gedaan om te zien hoeveel tijd een boodschap van variabele lengte nodig heeft om tussen twee agents te worden verstuurd. Daarnaast is er voor de scriptie een bepaald soort koppeling geïmplementeerd, namelijk de hiërarchische koppeling, een koppeling waarvan verondersteld wordt dat deze in de natuur voorkomt. Het goede nieuws is dat JADE in ieder geval werkt als framework voor complexe automaten. In het geschreven programma dat de hiërarchische koppeling representeert is te zien hoe de afzonderlijke onderdelen van de automaat met elkaar communiceren, elkaars boodschappen begrijpen en vervolgens doen met deze informatie wat van ze verwacht wordt. De troughput is een ander verhaal. Voor boodschappen die kleiner zijn dan 400kb is de troughput ongeveer 30% van de beschikbare bandbreedte. Wellicht dat er een hoop meer informatie door JADE wordt verstuurd; informatie die misschien op een nuttige manier kan worden gebruikt. Verder studie zal dat moeten uitwijzen. Daarnaast kan er nog een hoop worden geëxperimenteerd met de implementatie van de koppelingen. Het programma dat geschreven is voor deze scriptie kan op een aantal punten worden aangepast, zodat andere inzichten verworven kunnen worden. Zo is er in dit programma voor gekozen om de MicroAgents te laten starten met executeren, om de MacroAgent hierop vervolgens te laten anticiperen. Andersom zou ook kunnen, of een heel ander scenario, waarbij er nog een agent is die start- en stop condities regelt. Er kan ook nog worden gekeken naar implementaties waar er geen direct contact is tussen de Micro- en MacroAgents, maar waar een smart conduit agent het aanspreekpunt is voor deze agents, en hij de ‘datavertaalslag’ maakt voor deze communicerende entiteiten.
31
Referenties [1] COAST, COmplex Automata Simulation Technique. http://www.complex-automata.org/ [2] JADE, Java Agent DEvelopment framework. http:// jade.tilab.com/ [3] Nino Boccara, Modeling Complex Systems, Springer-Verlag New York, 2004 [4] Andrew Ilachinski, Cellular Automata: A Discrete Universe, World Scientific Publishing Singapore, 2001 [5] Jiming Liu, Autonomous Agents and Mult-Agent Systems: Explorations in Learning, Self-Organization and Adaptive Computation, World scienctific publishing Singapore, 2001 [6] Fabio Luigi Bellifemine; Giovanni Caire; Dominic Greenwood, Developing Multi-Agent Systems with JADE, John Wiley & sons, 2007 [7] Michael Schumacher, Objective Coordination in Multi-Agent System Engineering: Design and Implementation, Springer-Verlag Berlijn New York, 1998 [8] Alfons Hoekstra; Bastien Chopard; Pat Lawford; Rod Hose; Manfred Krafczyk; Joerg Bernsdorf, “Introducing Complex Automata for Modelling Multi-Scale Complex Systems”, Jaartal ? [9] Fabio Bellefemine; Giovanni Caire; Agostino Poggi; Giovanni Rimassa, “JADE – A white paper”, 2003 [10] FIPA, Foundation for Intelligent Physical Agents. http://www.fipa.org [11] Foundation for Intelligent Physical Agents, “FIPA ACL Message Structure Specification”, 2002 [12] Kresimir Jurasovic; Gordon Jezic; Mario Kusek, “A Performance Analysis of Multi-Agent Systems”, InternationalTransactions on Systems Science and Applications vol. 1; nr 4, 2006 [13] E. Cortese; F. Quarta; G. Vitaglione, “Scalability and Performance of JADE Message Transport System”, 2002 [14] Bastien Chopard; Jean-Luc Falcone; Alfons Hoestra, “CxA Coupling Paradigms”, 2007 [15]Alfons Hoekstra; Eric Lorenz; Jean-Luc Falcone; Bastien Chopard, “Towards a Complex Automata Framework for Multi-Scale Modeling: Formalism and the Scale Separation Map”, 2007 32
[16] FIPA TC Communication, FIPA ACL Message Structure Specification, 2002
33
Appendix A Deze appendix bevat code van het programma dat wordt besproken in hoofdstuk 4. CxA.java import import import import import import import
// // //
java.awt.Dimension; jade.core.Agent; jade.core.behaviours.*; jade.core.AID; jade.wrapper.AgentContainer; jade.wrapper.AgentController; jade.lang.acl.*;
Taken van de CxA: - Afhandelen van invoer parameters - Opstarten van de Macro agent public class CxA extends Agent { // Instantie variabelen private int aantalMicroAgents = -1; private boolean debug = false; protected void setup() {
// Handle user input Object[] args = getArguments(); showMe("Handling parameter input..."); if (args != null) { aantalMicroAgents = Integer.parseInt( (String) args[0] ); debug = Boolean.parseBoolean( (String) args[1] ); } showMe("Found input: nrOfMicros=" + aantalMicroAgents +", debug=" + debug);
// Geef debug info en aantal microagents mee aan de Macro agent Object[] param = new Object[2]; param[0] = new Integer(aantalMicroAgents); param[1] = new Boolean(debug); // Container handler ophalen om nieuwe agents in te gooien AgentContainer c = getContainerController(); // Start Macro agent String macroname = "Macro" ; showMe("Starting Macro agent..."); try { AgentController a = c.createNewAgent( macroname, "MacroModel", param ); // TODO: Kan nog parameters meegeven a.start(); } catch (Exception e){ e.printStackTrace(); } }
34
// Print methoden public void show(String s) { System.out.println(s); } public void showMe(String s) { System.out.println(getLocalName() + ": " + s); } }
Domain.java // Prototype klasse; moet nog worden ingevuld public class Domain { public Domain() { } }
MacroModel.java import import import import import
jade.core.AID; jade.core.Agent; jade.core.behaviours.CyclicBehaviour; jade.lang.acl.*; jade.wrapper.StaleProxyException;
public class MacroModel extends Agent { // Initialisatie protected void setup() { int aantalMicroAgents = -1; boolean debug = false; // Haal de parameters op Object[] args = getArguments(); if (args != null) { aantalMicroAgents = (Integer)args[0]; debug = (Boolean)args[1]; } // Consrueer gedrag this.addBehaviour(new MacroModelBehaviour(this, aantalMicroAgents, debug)); } } // Klasse die het gedrag van de sendagent definieert class MacroModelBehaviour extends CyclicBehaviour { // Statistiek variabelen private long starttime = 0; private long endofinit = 0; private long endofall = 0;
35
// Interne tijd variablen private int stoptime = 2; private int time = 0; private int dt = 1; // Micro agent gerelateerde variabelen private int numberOfMicroAgents = 0; private MicroModelState microStates[]; private boolean microSubmits[]; // Staat van deze macro agent private MacroModelState myState; // Message gerelateerde variabelen private MessageTemplate mt1,mt2; private ACLMessage recv_msg; // Control flow booleans private boolean done = false; private boolean debug = false; // Misc variabelen private static int counter = 0; private final int lengteMicroNaam = 5; // Constructor public MacroModelBehaviour(Agent a, int numberOfMicroAgents, boolean debug) { super(a); // Standaard this.debug = debug; // Registreer debug type this.numberOfMicroAgents = numberOfMicroAgents; // Registreer aantal micros starttime = System.currentTimeMillis(); // Meet de tijd nu we beginnen myState = new MacroModelState(numberOfMicroAgents, debug, myAgent); // Ken een state toe this.myState.setHostName(myAgent.getLocalName()); microStates = new MicroModelState[numberOfMicroAgents]; microSubmits = new boolean[numberOfMicroAgents]; clearMicroSubmitsArray(); // Is een initialisatie van de array mt1 = MessageTemplate.MatchPerformative(ACLMessage.REQUEST); mt2 = MessageTemplate.MatchPerformative(ACLMessage.PROPOSE); // Laat micros zich eerst aanmelden while (! allHaveSubmitted() ) { recv_msg = myAgent.receive(mt1); if(recv_msg != null) { recordSubmissionOf(recv_msg); }
36
recv_msg = null; } endofinit = System.currentTimeMillis(); showMe("Verlopen tijd van begin tot einde init (ms): " + (endofinit - starttime)); showMe("All micros have submitted; beginning main loop..."); clearMicroSubmitsArray(); counter = 0; } //
Uit te voeren taak in de loop public void action() { if (! done) { this.myState.updateDomain(); this.myState.updateBoundary();
// De volgende code moet wellicht ergens anders staan, omdat dat logischer correct is... // Wacht tot alle micros hebben gesubmit, zij zijn immers eerder klaar while (! allHaveSubmitted() ) { //showMe(System.currentTimeMillis() + ": Waiting for input..."); recv_msg = myAgent.receive(mt2); if(recv_msg != null) { int index = recordSubmissionOf(recv_msg); recordState(recv_msg, index); } recv_msg = null; } // Ze hebben allen gesubmit; maak de array weer leeg clearMicroSubmitsArray(); counter = 0; this.myState.setArray(microStates); if(debug){showMe("All have submitted.");} this.myState.collision(); // Ontvang eerst alles states van de micro agents this.myState.propagate(); // Parameter is een dummy this.myState.endOfLoop(); // Update de klok time += dt; showMe("The time is now: " + time); // Check of het einde is bereikt if (time > stoptime) { time = 0; // reset de tijd done = true;
37
showMe("Reached the end"); } } else { // Kappen // Stuur iedereen een bericht om het einde aan te kondigen ACLMessage end_msg = new ACLMessage(ACLMessage.CANCEL); if(debug){showMe("Sending the end messages...");} for (int i=0; i
// Hulp methodes // Maak de array die bijhoudt welke micros hebben gesubmit, vrij of initialiseer public void clearMicroSubmitsArray() { for (int i = 0; i < numberOfMicroAgents; i++) { microSubmits[i] = false; } } // Werk de submit array bij public void recordSubmissionOf(int index) { microSubmits[index] = true; if (debug) {showMe("Recorded nr. " + index);} //counter++; }
38
// Gegeven een ACLMessage, wek de submit array bij public int recordSubmissionOf(ACLMessage m) { // Parse nummer AID a = recv_msg.getSender(); String index = a.getLocalName().substring(lengteMicroNaam);; int intdex= Integer.parseInt(index); // Roep bovenstaande methode aan recordSubmissionOf(intdex); return intdex; } // Ontvang de state van een Micro agent en sla deze op public void recordState(ACLMessage m, int index) { try { MicroModelState mms = (MicroModelState)m.getContentObject(); microStates[index] = mms; } catch (UnreadableException e) { e.printStackTrace(); } } // Methode die aangeeft of alle micros hebben gesubmit public boolean allHaveSubmitted() { for (int i = 0; i < numberOfMicroAgents; i++) { if (microSubmits[i] == false) {return false;} } return true; } // Print methoden public void show(String s) { System.out.println(s); } public void showMe(String s) { System.out.println(myAgent.getLocalName() + ": " + s); } }
MacroModelState.java import import import import import
jade.core.AID; jade.core.Agent; jade.lang.acl.*; java.io.IOException; java.util.Random;
// Klasse die de state van een Macro Agent defineert public class MacroModelState extends State { private Domain d; // Domain van de agent private MicroModelState[] mmsa; // States van de micros private String hostName = "Macro (Not Defined)"; // Hostname van de agent
39
private Agent host= null; // Ref naar host agent private int numberOfMicroAgents = -1; // Aantal micros private Random rg = new Random(); // Randomgenerator voor benchmark gebruik private boolean debug = false; // Debug variabele private int[] myVariables; // Maak een state aan public MacroModelState(int numberOfMicroAgents, boolean debug, Agent a) { this.numberOfMicroAgents = numberOfMicroAgents; this.debug = debug; this.host = a; this.myVariables = new int[numberOfMicroAgents]; } // De collision operator public void collision() { if(debug){showMe("Entering collision method");} // Check of de mmsa array niet leeg is if (mmsa != null) { // Verander de state van de micros en verander myVariables if(debug){showMe("Going to loop through micro agent states...");} for (int i=0; i
40
} // Af te handelen als einde van de loop is bereikt // Stuur de nieuwe states op naar de micros public void endOfLoop() { if(debug){showMe("Entering endOfLoop method");} ACLMessage send_msg = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL); // Check of mmsa niet null is if(mmsa != null) { // Loop ;angs alle berokken micros for (int i=0; i<mmsa.length; i++) { String receivername = "Micro" + i; // Construeer de naam van de micro send_msg.addReceiver(new AID(receivername, AID.ISLOCALNAME)); try { send_msg.setContentObject(mmsa[i]); } catch (IOException e) { e.printStackTrace(); } this.host.send(send_msg); } } if(debug){showMe("Finishing endOfLoop method");} else { showMe("MMSA is null; error in sending new states to Micros"); host.doDelete(); } } @Override public void propagate() { // TODO Auto-generated method stub } @Override public void updateBoundary() { // TODO Auto-generated method stub } @Override public void updateDomain() { // TODO Auto-generated method stub } private int[] performMMSAction(int[] mmsa) { int[] rv = mmsa; for (int i=0; i
41
} return rv; } public void setArray(MicroModelState[] mmsa) { this.mmsa = mmsa; } public void setHost(Agent h) { this.host = h; } public void setHostName(String s) { hostName = s;; } public void showMe(String s) { System.out.println(hostName + ": " + s); } }
MicroModel.java import import import import import import import import import import import import
jade.core.Agent; jade.core.behaviours.*; jade.lang.acl.*; jade.core.AID; jade.lang.acl.MessageTemplate; java.lang.StringBuffer; jade.wrapper.StaleProxyException; java.util.Vector; java.text.DecimalFormat; java.io.BufferedWriter; java.io.FileWriter; java.io.IOException;
public class MicroModel extends Agent { // Initialisatie boolean debug = false; private static int myID = -1; // protected void setup() { Object[] args = getArguments(); if (args != null) { myID = (Integer)args[0]; debug =(Boolean)args[1]; } addBehaviour(new MicroModelBehaviour(this, "Macro", myID, debug)); } } // Klasse die het gedrag van de microagent definieert class MicroModelBehaviour extends CyclicBehaviour
42
{ private int myId; private boolean debug; // Tijd kunnen ??? private binnenkrijgen private private
variablelen // NOTE: Deze zouden ook in de State klasse int eindtijd = 3;
// TODO: Deze parameters
int tijdstap = 1; int detijd = 0;
// Object die de staat van het micromodel beschrijft private MicroModelState mms; // Message variabelen private ACLMessage send_msg, recv_msg, end_msg; private MessageTemplate mt1, mt2, mt3; // Control flow private boolean private boolean private boolean
booleans done = false; icansend = false; iwilllisten = false;
// Debug variabele private int a_counter = 0; // Constructor public MicroModelBehaviour(Agent a, String macroName, int id, boolean debug) { super(a); // Standaard myId = id; this.debug = debug; mms = new MicroModelState(debug, myAgent); if (debug) {showMe("Being constructed...");} // Meld aan bij macro agent ACLMessage meldAan = new ACLMessage(ACLMessage.REQUEST); meldAan.addReceiver( new AID( "Macro", AID.ISLOCALNAME)); myAgent.send(meldAan); // Send_msg kan alvast wat constante parameters meekrijgen send_msg = new ACLMessage(ACLMessage.PROPOSE); send_msg.addReceiver(new AID(macroName, AID.ISLOCALNAME)); // Ontvang berichten van Macro agent mt1 = MessageTemplate.MatchSender(new AID(macroName, AID.ISLOCALNAME)); mt2 = MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL); mt3 = MessageTemplate.MatchPerformative(ACLMessage.CANCEL); } // Uit te voeren taak in de loop public void action() {
43
// Als deze agent nog niet klaar is, ga dan verder met de loop if (! done) { this.mms.updateDomain(); this.mms.updateBoundary(); this.mms.collision(); this.mms.propagate(); this.mms.endOfLoop(); if(debug) {showMe("Finished a loop; now incrementing time variable...");} detijd += tijdstap; // Tijd updaten if (detijd > eindtijd) { detijd = 0; // reset de tijd done = true; icansend = true; if(debug){showMe("Reached the end condition; Ready to send state...");} } // De agent is klaar met uivoeren loop; Stuur state op naar macromodel } else if (icansend){ // Zet mijn state object op de post naar de MacroAgent try { if(debug){showMe("Wrapping current state...");} send_msg.setContentObject(mms); myAgent.send(send_msg); icansend = false; iwilllisten = true; } catch (IOException e) { e.printStackTrace(); } if(debug){showMe("State sent; Now listening for new state object...");} // Alles is klaar; Luisteren naar macromodel } else if (iwilllisten) { // Handel eind message af van de Macro end_msg = myAgent.receive(mt3); if (end_msg != null) { if(debug){showMe("Received end message. Closing down now...");} myAgent.doDelete(); try { myAgent.getContainerController().kill(); } catch (StaleProxyException e) { // TODO Auto-generated catch block
44
e.printStackTrace(); } } recv_msg = myAgent.receive(mt2); if(debug && a_counter < 20){showMe("(Still) Listening for new state...");} a_counter++; //if (a_counter > 10000) {deleteMe();} // Aha, ik krijg een nieuwe staat binnen. if (recv_msg != null) { if(debug){showMe("Receiving state");} // Doe iets met de ontvangen staat try { if(debug){showMe("Trying to update my state...");} mms = (MicroModelState)recv_msg.getContentObject(); done = false; // Want we gaan weer verder iwilllisten = false; a_counter = 0; showMe("State updated; now entering loop again..."); } catch (UnreadableException e) { if(debug){showMe("Failed to unwrap new state...");} e.printStackTrace(); } } recv_msg = null; } } /* OVERIGE HULP-METHODEN */ private int getID() { return this.myId; } // Print shortcuts public void show(String s) { System.out.println(s); } public void showMe(String s) { System.out.println(myAgent.getLocalName() + ": " + s); } public void deleteMe() { myAgent.doDelete(); } }
45
MicroModelState.java import java.io.Serializable; import java.util.Random; import jade.core.*; // Klasse die de staat beschrijft waarin een MicroModel agent zich bevindt public class MicroModelState extends State implements Serializable { private Domain d; private private private private
int numberOfVariables = 0; boolean debug = false; Random rg; Agent host = null;
// Dit zijn dummy state variablen om te testen wat de performance is. int[] variableArray; // Default constructor public MicroModelState(boolean debug, Agent a) { super(); rg = new Random(); this.debug = debug; this.host = a; // Vul de array met nullen. Lelijk, maar nu even handig numberOfVariables = 3; variableArray = new int[numberOfVariables]; for (int i= 0; i < this.numberOfVariables; i++) { variableArray[i] = 0; } } // Constructor met variabelen public MicroModelState(int[] paramArray, Agent a, boolean debug) { this(debug, a); numberOfVariables = paramArray.length; variableArray = new int[numberOfVariables]; for (int i= 0; i < this.numberOfVariables; i++) { variableArray[i] = paramArray[i]; } }
public void updateDomain() { // In vullen door gebruiker } public void updateBoundary() { // In vullen door gebruiker } public void collision() { // In vullen door gebruiker, nu random
46
variableArray[rg.nextInt(numberOfVariables)] = rg.nextInt(); } public void propagate() { // In vullen door gebruiker } public void endOfLoop() { // In vullen door gebruiker } public int[] getVariableArray() { return this.variableArray; } public void setVariableArray(int[] arg) { this.variableArray = arg; } public String toString() { String s =""; for (int i = 0; i < numberOfVariables; i++) { s += "Waarde" + (i + 1) + " : " + variableArray[i] + " "; } return s; } }
StartMicros.java import import import import import import import
java.awt.Dimension; jade.core.Agent; jade.core.behaviours.*; jade.core.AID; jade.wrapper.AgentContainer; jade.wrapper.AgentController; jade.lang.acl.*;
public class StartMicros extends Agent{ private private private private private
int aantalMicroAgentsToCreate = -1; int beginIndex = -1; boolean debug = false; String microname = "Micro" ; Object[] param = new Object[2];
protected void setup() { // Handle user input Object[] args = getArguments(); showMe("Handling parameter input..."); if (args != null) { this.aantalMicroAgentsToCreate = Integer.parseInt( (String) args[0] ); this.beginIndex = Integer.parseInt( (String) args[1] ); this.debug = Boolean.parseBoolean((String)args[2]); }
47
showMe("Found input: nrOfMicrosToCreate=" + aantalMicroAgentsToCreate +", beginIndex=" + beginIndex + ", debug=" + debug); // Set de slot van de param array param[1] = new Boolean(debug); // Container handler ophalen om nieuwe agents in te gooien AgentContainer c = getContainerController(); // Maak het gewenste aantal microagents aan en start ze try { for (int i = beginIndex; i < beginIndex + aantalMicroAgentsToCreate; i++ ) { String fullname = microname + i; param[0] = new Integer(i); AgentController a = c.createNewAgent( fullname, "MicroModel", param ); // TODO: Kan nog parameters meegeven a.start(); } showMe("Created the micro agents..."); } catch (Exception e){} // TODO: Exception vangen } // Print methode public void showMe(String s) { System.out.println(getLocalName() + ": " + s); } }
State.java public abstract class State { private Domain d; public State() { d = new Domain(); // Kan verder naar eigen inzicht ingevuld worden } public void editDomain() { } public Domain getDomain() { return this.d; } /* DE OPERATOR FUNCTIES VAN EEN CA MODEL*/ // Update domein public abstract void updateDomain(); // Voer operaties aan de randen uit public abstract void updateBoundary();
48
// Collide operator public abstract void collision(); // Propagate operator; public abstract void propagate(); // Einde van de loop is bereikt; iets doen? public abstract void endOfLoop(); }
49
Appendix B Deze appendix geeft een technische beschrijving van hoe het experiment is hoofstuk 4 is uitgevoerd. Het experiment is fysiek uitgevoerd op de computers van gebouw Euclides†. De MacroAgent executeert op terminal ‘ow149’, de MicroAgents executeren op de terminals ‘ow150’ tot en met ‘ow159’.Op elk van deze terminals wordt remote ingelogd met behulp van ssh. Daarna worden bash-scripts uitgevoerd om het experiment daadwerkelijk te laten beginnen. Opstarten Platform
Onderstaande code is afkomstig uit het bash-script ‘startup.sh’. Het dient om het JADE platform te initialiseren en de MacroAgent te starten. #!/bin/bash # Start het JADE platform op. java jade.Boot & # Wacht een moment tot het platform geheel is geladen. sleep 1 # Start de MacroAgent # via de flag -Xmx kan extra geheugen worden meegegeven aan de JVM. # $1 is de parameter die door de gebruiker wordt meegegeven om het # aantal MicroAgents aan te geven. # $2 is de parameter die door de gebruiker wordt meegegeven om het # aantal Mb geheugen aan de JVM te specificeren. java -Xmx$2 jade.Boot -container "CxA:CxA($1 true)" &
Opstarten MicroAgents
Onderstaande code is afkomstig uit het bash-script ‘startmicros.sh’. Het dient om de MicroAgents op te starten. De code wordt uitgevoerd op de terminals ‘ow150’ tot en met ‘ow 159’. #!/bin/bash # Geef aan hoeveel agents er moet worden aangemaakt aantal=50 # Geef aan welk begin ID de agents mee moeten krijgen begin=$(($1*$aantal)) # Start de agents op; geef aan waar de MacroAgent zich bevindt: ow149 java jade.Boot -container -host ow149 "S$begin:StartMicros($aantal $begin false)" &
†
Locatie gebouw Euclides: Plantage Muidergracht 22-24 1018 TV Amsterdam
50