Natürliche Beispiele von Multiagentensysteme Utz J.Pape 11. Mai 2003 Inhaltsverzeichnis 1 Einführung 1.1 Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 2 Natürliche Agentensysteme 2.1 Schwärme . . . . . . . . . 2.1.1 Ziel / Anwendung 2.1.2 Regeln . . . . . . . 2.1.3 Simulation . . . . 2.1.4 Umsetzung . . . . 2.2 Einkesselung . . . . . . . 2.2.1 Ziel / Anwendung 2.2.2 Regeln . . . . . . . 2.2.3 Formalisierung . . 2.2.4 Berechnung . . . . 2.2.5 Simulation . . . . 2.2.6 Umsetzung . . . . 2.3 Termiten-Nest-Bau . . . . 2.3.1 Ziel / Anwendung 2.3.2 Regeln . . . . . . . 2.4 Aufgabenteilung . . . . . 2.4.1 Ziel / Anwendung 2.4.2 Regeln . . . . . . . 2.4.3 Formalisierung . . 2.4.4 Berechnung . . . . 2.4.5 Simulation . . . . 2.4.6 Umsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 2 2 3 3 4 4 4 5 5 5 6 8 8 8 8 8 9 9 9 10 11 3 Appendix 3.1 matlab code . . . . 3.1.1 flock ex.m . 3.1.2 wolf ex.m . 3.1.3 wasp ex2.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 12 12 14 17 1 . . . . . . . . . . . . . . . . Einführung Als König Solomon eine Schlacht beobachtete, war er beeindruckt von der Art des Zusammenspiels der einzelnen Armeeteile. Die autonomen Teile, die eine ganzheitliche Aufgabe effizient erfüllen konnten. Um hochkomplexe Systeme zu simulieren, werden diese heutzutage durch kleine autonome Teile (Agenten), deren Verhalten durch simple Regeln vorgegeben ist, realisiert. Dabei nutzt man die 1 Emergenzeigenschaft derartiger Systeme aus, um die Funktionalität des hochkomplexen Systems zu erhalten. Da in der Natur viele Agentensysteme vorhanden sind, versucht man die evolutionäre Erfahrung, die in diesen Systemen steckt, zu extrahieren, und so diese Konstruktionsprinzipien auf die Problemstellungen anzuwenden. In dieser Ausarbeitung werden vier Beispiele natürlicher Agentensysteme besprochen. 1.1 Beispiel Beobachtet man Ameisen bei ihrer Futter-Suche, so stellt man fest, dass nach kurzer Zeit optimale Wege vom Nest zu den Futterquellen existieren. Mathematisch gesehen handelt es sich um einen minimal aufspannenden Baum, bei dem das Nest und die Futterquellen die Knoten und die Ameisenstraßen die Kanten sind. Allerdings wird wohl kaum eine Ameise einen minimal aufspannenden Baum berechnen können, es stellt sich also die Frage, wie diese optimalen Wege entstehen. Mit einer Modellierung als Multi-Agent-System (MAS) ist es gelungen, die Futter-Suche der Ameisen zu simulieren. Agenten sind dabei natürlich die Ameisen, wobei jede für sich folgende fünf Regeln befolgt: 1. Weiche Hindernissen aus 2. Wandere zufällig in der Gegend herum, wenn Duftstoffe in der Nähe vorhanden sind, favorisiere diese Richtung 3. Wenn Nahrung getragen wird, hinterlasse Duftstoffe und gehe in Richtung des Nest-Duftstoffes. 4. Wenn Nahrung getragen wird und Ameise sich im Nest befindet, lasse die Nahrung fallen 5. Wenn keine Nahrung getragen wird, die Ameise sich nicht im Nest befindet und Nahrung sieht, nimm diese Nahrung auf Dabei können Ameisen sich fortbewegen, Duftstoffe registrieren und produzieren und Nahrung tragen. Die Umwelt ist charakterisiert durch Nahrungsstellen und einem Nest, dass durch einen einzigartigen Duftstoff gekennzeichnet ist. Abbildung 1: Pfadsuche bei Ameisen Wie in Abbildung 1 deutlich wird, laufen die Ameisen zunächst zufällig herum (linke Seite), nach kurzer Zeit jedoch bildet sich durch die Duftstoffe sichtbar gemacht ein klarer optimaler Weg vom Nest zur Nahrung heraus. Dass durch nur fünf Regeln ein derart komplexes Problem in kurzer Zeit gelöst werden kann, regt das Interesse an, Agentensysteme auch für eine Vielzahl anderer komplexer Probleme einzusetzen. 2 2 Natürliche Agentensysteme Bei den nun folgend vorgestellten Agentensystemen handelt es sich um: • Schwärme • Einkesselung • Termiten-Nest-Bau • Aufgabenteilung Soweit Simulationsprogramme1 dazu erstellt wurden, werden diese kurz besprochen und die Ergebnisse präsentiert. 2.1 2.1.1 Schwärme Ziel / Anwendung Schwärme von Fischen und auch Vögeln sind in der Lage, Hindernissen auszuweichen und ein gemeinsames Ziel anzusteuern. Dabei gibt es weder viele Unfälle innerhalb des Schwarms, noch löst sich der Schwarm auf bzw. kommen mehrere Individuen abhanden. Wie ist das möglich ohne eine zentrale Steuerungsinstanz? Ähnliche Probleme treten z.B. bei der Flugsteuerung und auch bei der Steuerung von Schiffkonvois auf. Nach Adaption an das neue Problem besteht die Möglichkeit, dass ein ähnliches Agentensystem auch diese Probleme lösen kann. Zur Vereinfachung wird das Problam darauf reduziert, dass sich keine Fische aus dem Schwarm ausbrechen und dass keine Kollisionen innerhalb des Schwarms entstehen. 2.1.2 Regeln Drei Regeln müssen von jedem Fisch (Agenten) befolgt2 werden: 1. Halte einen Mindestabstand zu anderen Fischen ein 2. Passe die Geschwindigkeit den Fischen in der Umgebung an 3. Bleibe nahe am Zentrum des Schwarms Um die Möglichkeiten des Schwarms dahin gehend zu erweitern, er auch Hindernissen ausweichen und z.B. Nahrung ansteuern kann, müssen folgende drei Regeln hinzugefügt werden: 1. Folge dem Fisch vor Dir 2. Wenn kein Fisch vor Dir ist, steuere die nächste Nahrungsquelle an und meide Hindernisse mit einem großen Mindestabstand 3. Wenn ein Hinderniss auftritt, verlangsame Deine Geschwindigkeit und nähere Dich weiter dem Zentrum des Schwarms Dabei sorgt die letzte Regel dafür, dass Fische am Rande des Schwarms auch nicht gegen ein Hindernis schwimmen. So wird der Schwarm zu einem sich selbst organisierenden Gebilde. 3 flock 50 fish 40 30 20 y 10 0 −10 −20 −30 −40 −50 −50 −40 −30 −20 −10 0 x 10 20 30 40 50 Abbildung 2: Schwarm Initialsisierung flock 100 fish 90 80 70 y 60 50 40 30 20 10 0 −50 −40 −30 −20 −10 0 x 10 20 30 40 50 Abbildung 3: Schwarm Endzustand 2.1.3 Simulation Zu Beginn der Simulation befinden sich 10 Fische nebeneinander (s. Abbildung 2). Nach etwa 30 Zeitschritten ergibt sich schon ein Schwarm-ähnliches Gebilde (s. Abbildung 3). Da nur die ersten drei regeln implementiert wurden, formiert sich kein symmetrischer, geordneter Schwarm, aber trotzdem ist es beeindruckend, dass man mit nur drei Regeln derartige Resultate erhalten kann. Auch nach sehr großen Zeitschritten ist der Schwarm noch immer zusammen. 1 Sämtliche Simulationsprogramme wurden in Matlab 6.1 umgesetzt. ist an dieser Stelle nicht ganz korrekt, da - wie wir später noch sehen werden - die Agenten nicht durch die Regeln determiniert, sondern stochastisch beschrieben werden. 2 befolgen 4 2.1.4 Umsetzung Das Hauptprogramm besteht aus zwei verschachtelten for-Schleifen. Dabei iteriert die äußere Schleife über die Zeitschritte und die innere über die Agenten und bewegt jeden Agenten um einen Zeitschritt. Dieses Konstrukt findet sich bei sämtlichen Simulationen wieder, da eine andere Implementierung als diese komplizierter ist. Sowohl Agenten als auch Umwelt, die es hier nicht gibt, agieren gekoppelt über die diskretisierte Zeit. Bei einer objektorientierten Implementierung sollte natürlich jeder Agententyp einer Klasse und jeder Agent einem separaten Objekt entsprechen. Da es hier - wie auch bei den anderen Simulationen - jedoch nicht um programmiertechnisch beispielhaftes Programmieren ging, sondern nur um Ergebnisse mit vertretbaren Programmieraufwand, finden sich die Agenten und Eigenschaften jeweils in Vektoren. In jedem Zeitschritt berechnet der Agent zunächst seine Umgebung (get neighbors()), um so seine Geschwindigkeit den übrigen Agenten anzupassen (average speed()). Als nächstes wird für die Richtung des Agenten noch das Zentrum des Schwarms hinzugezogen (get center orientation()). Nach der Beachtung einiger Restriktionen (z.B. Geschwindigkeitsbegrenzung), werden die neuen Koordinaten berechnet. Diese sind allerdings nicht determiniert, sondern stochastisch (s. rand()). Damit keine Kollisionen auftreten, überprüft der Agent auf seiner neuen Position, ob in dieser Umgebung (wiederum get neighbors()) schon andere Agenten vorhanden sind. Ist dies der Fall, verringert er seine Geschwindigkeit und überprüft erneut die neue Position. Ggf. bleibt der Agent stehen (z==0). Natürlich macht die Umsetzung weitere Annahmen wie z.B. dass der Agent die Umgebung um seinen Mittelpunkt herum beobachten könnte. Dies ist in der Natur für Fische nicht möglich. Um dies zu berücksichtigen, müsste get neighbors() komplizierter gestaltet werden. Das Ergebnis würde sicherlich kaum beeinflusst werden. 2.2 2.2.1 Einkesselung Ziel / Anwendung Bei der Einkesselung geht es darum, ein Zielobjekt von allen Seiten zu umstellen. Z.B. Wölfe können alleine keinen Elch reißen, jedoch in einer Gruppe, wenn der Elch umkreist ist, kann ein Wolf seitlich von hinten auf den Rücken des Elchs springen. Dabei stellt sich die Frage, wie die Wölfe die Umzingelung schaffen, ohne dabei zu kommunizieren. Viele Anwendungen dieses Szenarios finden sich im militärischen Bereich. 2.2.2 Regeln Da es zwei verschiedene Agententypen gibt, müssen auch zwei Mengen von Regeln gegeben sein. Der Elch gehorcht dabei nur einer Regel: 1. Maximiere den Abstand zum nächsten Wolf Die Wölfe müssen versuchen zwei Ziele mit einander zu vereinbaren: 1. Minimiere den Abstand zum Elch 2. Maximiere den Abstand zum nächsten Wolf Letztere Regel ist notwendig, damit die Wölfe sich nicht selbst gegenseitig behindern. Man kann leicht sehen, dass diese Strategien jeweils für die Wölfe und den Elch optimal sind. Sind Wölfe und Elch gleich schnell, so werden bei einer Simulation mit diesen Regeln die Wölfe niemals den Elchen fangen. Sind die Wölfe hingegen schneller, so wird der Elch jedesmal gefangen. 5 2.2.3 Formalisierung Wie zuvor betrachtet, lassen sich MAS formalisieren. Dies führen wir zunächst an diesem Beispiel vor: h{h(p, v, o), (p, o), (p, o), {timestep(τ )}i}, h(), {}, i, {agents : tb, env : tb}i (1) Das MAS besteht also aus einer Menge von Agenten, einer Umwelt, die aber in unserem Falle leer ist, und einer homodynamischen zeitbasierten Kopplung. Die Agenten haben das Zustandstupel (p, v, o), dabei steht p für die Position, v für die Geschwindigkeit und o für den Typ des Agenten. Normalerweise würde man den Typen nicht in den Agenten als Zustand mitführen, da es sich einfach um zwei verschiedene Typen handeln würde, d.h. die Menge der Agenten würde aus zwei Teilmengen bestehen. Da aber hier die Agenten (Wolf und Elch) derart ähnlich sind, bietet sich obige Vorgehensweise an. Jeder Agent benötigt die Position und den Typ der anderen Agenten, um obige Regeln zu befolgen, daher befinden sich diese jeweils in den Input/Output Tupeln. Die Geschwindigkeit hingegen ist nur intern für jeden Agenten verfügbar. 2.2.4 Berechnung Der Simulation liegt ein hexagonales Grid zugrunde. Damit ist die Bedingung für eine erfolgreiche Einkesselung, dass der Elch sich nicht mehr bewegen kann, d.h. er von sechs Wölfen umgeben ist. Jeder Agent muss in seinem Zeitschritt ein neues Feld aussuchen. Zunächst werden alle in Betracht kommenden Felder, d.h. jene Felder, die der Agent mit seiner Geschwindigkeit erreichen kann, ausgewählt und für diese ein Score berechnet. Der Agent begibt sich dann auf das Feld mit dem höchsten Score. Die Formeln für den Score lauten: Swolf = k ∗ d(nearest wolf ) − d(moose) (2) Smoose = d(nearest wolf ) (3) Dabei ist in Gleichung (2) k eine Abstoßungskonstante zwischen den Wölfen. Diese muss natürlich recht klein sein, so dass immer der Anteil zur Minimierung der Distanz zum Elch überwiegt. d(◦) ist hier ein Abstandsmaß. 2.2.5 Simulation Die Simulation beginnt mit der Startformation wie in Abbildung 4 zu sehen. Die Wölfe nehmen sofort die Fährte auf und setzen dem Elch nach (vgl. Abbildung 5). Abbildung 6 zeigt, wie der Elch nach einigen Zeitschritten umzingelt ist. Die Statistik in Abbildung 7 gibt Aufschluss über die benötigte Anzahl von Zeitschritten bis die Wölfe den Elch gefangen haben. Aus dieser wird deutlich, dass der Elch immer gefangen wird. 2.2.6 Umsetzung Wie auch bei dem anderen Simulation, besteht das Hauptprogramm aus den zwei verschachtelten Schleifen. Die Agenten sind auch wieder in Vektoren gespeichert. Die timestep-Funktion ist hier die get next pos() Funktion. In dieser wird zuerst je nach Typ die Geschwindigkeit ermittelt3 . Und anschließend für jedes Feld, welches mit der berechneten Geschwindigkeit erreicht werden kann, der Score ermittelt (get score()). Das Feld mit dem maximalen Score ist die neue Position des Agenten. Ist der Score mehrerer Felder gleich groß, so wird per Zufall das neue Feld ermittelt (choose rnd()). 3 Eleganter wäre es natürlich, diese in einen extra Eigenschafts-Vektor zu speichern, aber der Einfachheit halber wurde darauf verzichtet. 6 wolves catch moose 25 moose wolf 20 15 10 y 5 0 −5 −10 −15 −20 −25 −25 −20 −15 −10 −5 0 x 5 10 15 20 25 Abbildung 4: Einkesselung Startzustand wolves catch moose 25 moose wolf 20 15 10 y 5 0 −5 −10 −15 −20 −25 −25 −20 −15 −10 −5 0 x 5 10 15 20 25 Abbildung 5: Einkesselung während des Laufs Die Koordinaten des hexagonalen Grids bestehen aus einem x und einem y Wert. Der y Wert, der die Zeile angibt ist fortlaufend. Der x Wert läuft jedoch pro Zeile in zweier Schritten. D.h. die x-Werte der 0. Zeile enthalten nur ungerade Zahlen, die der 1. Zeile nur die geraden Zahlen, die der 2. Zeile wiederum die ungeraden Zahlen usw. Dadurch wird zwar die Berechnung und die Distanzmessung etwas komplizierter, jedoch ist für die Darstellung so keine Umrechnung notwendig. Die Schleife im Hauptprogramm bricht ab, wenn die maximale Anzahl an Zeitschritten erreicht wurde, oder der Elch gefangen wurde (moose caught()). Letztere Funktion berechnet den Abstand von jedem Wolf zum Elch, wenn jeder Abstände exakt 1 ergibt, dann ist der Elch gefangen. Dies wurde der Einfachheit und der Schnelligkeit wegen so realisiert, werden mehr als sechs Wölfe eingesetzt, funktioniert dies so nicht mehr. Dann muss abgefragt werden, ob alle Positionen um den Elch herum schon besetzt sind (was aber zeitaufwendiger ist). 7 wolves catch moose 25 moose wolf 20 15 10 y 5 0 −5 −10 −15 −20 −25 −25 −20 −15 −10 −5 0 x 5 10 15 20 25 Abbildung 6: Einkesselung Endzustand number of steps for surroundings 70 60 #surroundings 50 40 30 20 10 0 0 10 20 30 40 50 timesteps 60 70 80 90 100 Abbildung 7: Einkesselung Statistik 2.3 2.3.1 Termiten-Nest-Bau Ziel / Anwendung Termiten bauen atemberaubende Nester. Diese sind z.T. mehr als 5m hoch, mehr als 10t schwer und älter als 350 Jahre. Allerdings existiert kein Architekt. Es gibt keine Termite, die den anderen Termiten Anweisungen gibt. Als Agentensystem organisiert, werden jedoch wieder nur wenige Regeln benötigt, um solche stabilen und großen Gebäude bauen zu können. Ob man die hieraus gewonnenen Erkenntnisse nutzen kann, um möglicherweise künstliche Agenten-Bauarbeiter-Manschaften zu konstruieren, ist fraglich. Aber schon die Vorführung als Beispiel dient zum Zeigen der Anwendungsbreite von Agentensystemen. 2.3.2 Regeln Die Agenten müssen drei Regeln erfüllen: 8 1. Produziere Bau-Material mit Duft 2. Wandere zufällig, bevorzuge Duftrichtung 3. Entscheide stochastisch über Material-Abwurf abhängig von: • Duftkonzentration • getragenem Bau-Material Simulationen zeigen, dass zunächst eine gleichmäßige Punktverteilung der Materialien zustanden kommt. Diese Punkte werden zu Säuzlen erhöht, da die Duftkonzentration in der Mitte eines jeden Punktes am größten ist. Dadurch dass die Säulen aber ein wenig zur Seite geneigt (auf Grund des stochastischen Charakters der Regeln) sind, werden die Säulen auf einer bestimmten Höhe durch Bögen miteinander verbunden. Denn sobald die Neigung einer Säule diese selbst so nahe an eine andere Säule nähert, wird auch die Duftkonzentration der benachbarten Säule in die stochastische Berechnung einbezogen, so dass der neigende Effekt verstärkt wird und in besagten Bögen mündet. Da alle Säulen derartig mit einander verbunden werden, entsteht so ein neues Stockwerk. Auf diesem erfolgt der Bau der Säulen auf gleichem Wege. An diesem Beispiel wird besonders deutlich, dass es sehr viele freie Parameter gibt, u.a.: • Wie weit reicht die Duftkonzentration? • Wie stark beeinflußt die Duftkonzentration den Abwurf des Materials? • Wieviel Zufall ist im Spiel? • Wieviel Material wird auf einmal abgeworfen? Auch in den anderen Beispielen ist es immer außerordentlich schwierig, die freien Parameter zu bestimmen. 2.4 2.4.1 Aufgabenteilung Ziel / Anwendung Beobachtet man einen Wespenstamm, so stellt sich heraus, dass es verschiedene funktionale Gruppen gibt. Untersuchungen haben aber gezeigt, dass alle Wespen genetisch identisch sind. Die Frage ist, wie sich die Wespen derart organisieren, dass sich die Gruppen bilden und auch in entsprechender Stärke vorhanden sind; und dies ohne zentrale Planung. Sehr abgewandelt lässt sich dieses Beispiel nutzen, um sich selbst-organisierendes Management durch Agentensysteme zu realisieren. 2.4.2 Regeln Bevor wir zu den Regeln kommen, muss noch kurz die Umwelt erläutert werden. Diese ist diesmal nicht leer, sondern besteht an einem bestimmten Punkt aus der Brut. Diese stimuliert eine Nahrungsnachfrage. Wird diese befriedigt, dann sinkt sie, andernfalls steigt sie mit der Zeit immer weiter an. Die Wespen folgen drei Regeln: 1. Wenn auf eine andere Wespe getroffen wird, dann kämpfe: • Stärkere Wespe gewinnt mir größerer Wahrscheinlichkeit • Gewinner erhält etwas Kraft vom Verlierer 2. Wespen in der Nähe von Brut tendieren dazu, Futter zu holen 9 2.4.3 Formalisierung Das System kann folgendermaßen formalisiert werden: h{agenti }, env, {agent : tb, env : tb}i (4) Dabei ist ein Element der Menge der Agenten definiert durch: h(pi , Fi , σi , ξi , φi ), (pi , Fi , σi ), (pi , Fi , σi ), {timestep(τ )}i (5) Die Variablen haben folgende Bedeutung: • p Position des Agenten • F Kraft des Agenten • σ Grenzwert bis Agent Futter holt • ξ Lernfaktor: Wie wahrscheinlich ist, dass Agent Futter holt, wenn er schon Futter holen war • φ Faktor zum vergessen, dass der Agent Futter holen war Schon da die Agenten kämpfen müssen, ist es klar, dass die Position und die Kraft als Input/Output-Werte vorhanden sein müssen. Die beiden Faktoren zum Lernen und Vergessen hingegen werden nur von der Wespe selbst verändert. Und die diesmal nicht passive Umwelt ist gegeben durch: h(p(D) , D, W ), {timestep(τ )}i (6) Die Brut wird mit eniem D bezeichnet für Demand, daher ist p(D) die Position der Brut, D die Nachfrage selbst und W die von den Agenten verrichtete Arbeit. 2.4.4 Berechnung Die Differenzierung der Agenten in verschiedene Gruppen wird auch sichtbar, wenn die Brut und ihre Nachfrage nicht implementiert wird, daher wurde dies entsprechend so realisiert. Daher muss lediglich die Realisierung des Kampfes besprochen werden. Dies geschieht mittels der FermiFunktion (s. Abbildung 7). Durch diese kann durch einen freien Parameter h bestimmt werden, inwieweit der Ausgang des Kampfes durch die Kraftdifferenz der Agenten determiniert ist. 1 p(Fi , Fj ) = (7) 1+ 7 berechnet die Wahrscheinlichkeit, dass Agent j den Kampf gegen Agent i gewinnt. Abbildung 8 zeigt die Kurvenverläufe für verschiedenes h. Je größer h ist, umso mehr fällt die Kraftdifferenz Fi − Fj ins Gewicht. Ist h ganz klein, dann ist die Fermi Funktion eine waagerecht, ist h jedoch sehr groß, dann entsteht eine sigmoide bzw. Stufenfunktion. 2.4.5 eh(Fi −Fj ) Simulation Die Aufteilung der Kraft, die am Anfang zufällig verteilt ist, ist in Abbildung 9 sichtbar: Schon hier wird deutlich, dass nach einer Vielzahl von Zeitschritten genau ein Agent mit Abstand die größte Kraft besitzt. Daneben gibt es es kleinere Gruppe von mäßig starken Agenten und der Großteil der Agenten hat keine Kraft. Untermauert wird dies durch Abbildung 10: Die Gruppen wurden gebildet durch die Menge der Kraft eines Agenten im Verhältnis zu der Kraft des stärksten Agenten. Genau ein Agent (die Königin) hat mehr als 90% der maximalen Kraft, mittlere Kraft besitzen die Agenten, die zwischen 10% und 90% der maximalen Kraft besitzen und die schwache Gruppe beinhaltet die restlichen Agenten. Es wird also deutlich, dass sich drei Gruppen bilden: 10 1 h=1 h=2 h=0.5 0.9 0.8 0.7 p(Fi,Fj) 0.6 0.5 0.4 0.3 0.2 0.1 0 −2 −1.5 −1 −0.5 0 Fi−Fj 0.5 1 1.5 2 Abbildung 8: Fermi Funktion forces of wasps 35 30 25 force 20 15 10 5 0 0 50 100 150 200 250 timesteps 300 350 400 450 500 Abbildung 9: Wespen - Kraftverteilung • Die Königin, die die Kraft der anderen Agenten skaliert.4 • Eine mobile, starke Gruppe zum Abwehren der Feinde und zum Auskundschaften der Umgebung • Eine Pflegegruppe, die nicht mobil ist und die Brut pflegt. 2.4.6 Umsetzung Die Umsetzung erfolgte hierbei nur über eine Hauptschleife, die über die Zeitschritte iteriert. Vor Beginn der Schleife wird vorab für jeden Zeitschritt durch Zufall die Anzahl der kämpfenden Wespen ermittelt5 . In jedem Zeitschritt wird dann ein Begegnungsvektor zufällig ermittelt mit 4 Dies ist dadurch möglich, dass der Kampfausgang stochastisch und nicht determiniert ist die Anzahl der Wespen, die in die Nähe der Brut gelangen wird ermittelt, allerdings wird dies nicht weiter benutzt... 5 Auch 11 groups of wasps 45 40 35 low force medium force high force number of wasps 30 25 20 15 10 5 0 0 50 100 150 200 250 timesteps 300 350 400 450 500 Abbildung 10: Wespen - Gruppenverteilung Länge der Anzahl der kämpfenden Wespen. Da aber keine Wespen gegen sich selbst kämpfen sollen, und es auch Probleme bei der abschließenden Kraftzuordnung ergibt, taucht keine Wespe in diesem Vektor (egal in welcher Spalte) doppelt auf (non redundant()). Anschließend wird über die FermiFunktion die Gewinner aller Kämpfe ermittelt (fight()) und anschließend mit Vektoroperationen die Kräfte nach obiger Definition verschoben. Dabei kann unterschieden werden zwischen festen und relativen Kaftportionen, allerdings ist nur erstere Wahl sinnvoll, da ansonsten ein erfolgreicher Kampf mit der Königin, auf Grund der stochastischen Natur des Kampfes, verheerende Folgen hätte. Literatur [Bonabeau99] Bonabeau, Dorigo, Theraulaz: Swarm Intelligence: From Natural to Artificial Systems. Oxford Press, 1999. [Kennedy01] Kennedy, Eberhart: Swarm Intelligence. Morgan Kaufmann, 2001. [Parunak03] Parunak: Making Swarming Happen. Conference on Swarming and C4ISR, 2003. [Parunak97] Parunak: “Go to the Ant“: Engineering Principles from Natural Multi-Agent Systems. Annals of Operations Research 75 (1997) 69 101. [Resnick94] Resnick: Turtles, Termites, and Traffic Jams. MIT Press, 1994. 3 3.1 3.1.1 Appendix matlab code flock ex.m function flock_ex n = 10; %number of fishes T = 50; %number of timesteps L=50; %limits for plot 12 vmax = 3; x = zeros(1,n); %x coordinates y = (-n/2:1:n/2-1)*5; %y coordinates vx = round(rand(1,n)*vmax); %velocity x coordinate vy = round(rand(1,n)*vmax); %velocity y coordinate %central of coordination system cx = 0; cy = 0; figure(1); plot(x,y,’bo’); title(’flock’); xlabel(’x’); ylabel(’y’); legend(’fish’); axis([-L+cx L+cx -L+cy L+cy]); M(1)=getframe; pause for t=1:T for i=1:n [x(i) y(i) vx(i) vy(i)] = timestep(i,x,y,vx,vy); plot(x,y,’bo’); title(’flock’); xlabel(’x’); ylabel(’y’); legend(’fish’); axis([-L+cx L+cx -L+cy L+cy]); M(t*n+i) = getframe; end %for i %fit coordinate system [xc yc] = get_center(x,y); if abs(cx-xc)>L/2, cx = cx + L/2; end %if if abs(cy-yc)>L/2, cy = cy + L/2; end %if end %for t %******************************************** function [xn,yn,vxn,vyn] = timestep(i,x,y,vx,vy) %returns new position and velocity for fish i v_distant = 5; %double of minimal distant v_learn = 0.5; %learn rate for velocity v_max = 5; %learn velocity I=get_neighbors(i,v_distant*2,x,y); if isempty(I), vxn = vx(i); vyn = vy(i); 13 else, [vxn vyn] = average_speed(I,vx,vy); vxn = v_learn*vxn + (1-v_learn)*vx(i); vyn = v_learn*vyn + (1-v_learn)*vy(i); end %if [xd yd] = get_center_orientation(i,x,y); %get correct orientation %swim to swarm center if ((xd>v_distant) & (vxn~=0) & (sign(vxn)~=sign(xd))), vxn = vxn*-1; end %if if ((yd>v_distant) & (vyn~=0) & (sign(vyn)~=sign(yd))), vyn = vyn*-1; end %if if (xd>v_distant), vxn = vxn+xd*v_learn; end %if if (yd>v_distant), vyn = vyn+yd*v_learn; end %if %limit for speed if (abs(vxn)>v_max), vxn = sign(vxn)*v_max; end %if if (abs(vyn)>v_max), vyn = sign(vyn)*v_max; end %if %actualize coordinates x(i) = x(i)+vxn*(3/4+rand(1)/2); y(i) = y(i)+vyn*(3/4+rand(1)/2); %check for collisions and abuse them bcollision = ~isempty(get_neighbors(i,v_distant/2,x,y)); z=10; while ((bcollision) & (z>0)), x(i) = x(i)-vxn/10; y(i) = y(i)-vyn/10; z=z-1; bcollision = ~isempty(get_neighbors(i,v_distant/2,x,y)); end %while %save correct coordinates xn = x(i); yn = y(i); vxn = vxn/10*z; vyn = vyn/10*z; %******************************************** function [xo,yo] = get_center_orientation(i,x,y) [xc yc] = get_center(x,y); xo = xc-x(i); yo = yc-y(i); 14 %******************************************** function [xc,yc] = get_center(x,y) %returns center of fishes xc = sum(x)/size(x,2); yc = sum(y)/size(y,2); %******************************************** function [sx,sy]=average_speed(I,vx,vy) %returns average speed of I sx=sum(vx(I))/size(I,2); sy=sum(vy(I))/size(I,2); %******************************************** function I=get_neighbors(i,d,x,y) %get neighbor fishes of i up to distance d z = 1; I = []; %index set for indices of neighbor fishes for j=1:size(x,2) if ((i~=j) & (distance(i,j,x,y)<=d)), I(z) = j; z = z+1; end %if end %j %******************************************** function d=distance(i,j,x,y) %returns distant from i to j d = ((x(i)-x(j))^2 + (y(i)-y(j))^2)^0.5; 3.1.2 wolf ex.m function j=wolf_ex(plot_it) x = [3 0 1 0 1 0 1]; %x coordinates;moose is first! y = [0 1 2 3 4 5 6]; %y coordinates f = [0 1 1 1 1 1 1]; %flags: 0 if moose, 1 else L = 25; m = size(x,2); %number of animals n = 100; %maximum of timesteps if plot_it, figure(1); plot(x(1),y(1),’ro’); hold on; plot(x(2:m),y(2:m),’bo’); title(’wolves catch moose’); xlabel(’x’); ylabel(’y’); legend(’moose’,’wolf’); 15 axis([-L L -L L]); hold off; M(1)=getframe; pause end %if for j=1:n for i=1:m [x(i) y(i)] = get_next_pos(i,x,y,f); if plot_it, plot(x(1),y(1),’ro’); hold on; plot(x(2:m),y(2:m),’bo’); title(’wolves catch moose’); xlabel(’x’); ylabel(’y’); legend(’moose’,’wolf’); axis([-L L -L L]); hold off; M(j*n+i) = getframe; end %if end %for i if moose_caught(x,y), break; end %if end %for j %************************************************** %get next field position function [xmax,ymax] = get_next_pos(i,x,y,f) mod_xi = mod(x(i),2); smax = -100000; d=(f(i)+1)*2; %velocity for moose=1,wolves=2 %iterate over neighbor cells for xj=x(i)-d:x(i)+d if mod(xj,2)==mod_xi, s = get_score(xj,y(i),i,x,y,f); if choose_rnd(s,smax), smax = s; xmax = xj; ymax = y(i); end %if if (abs(xj-x(i))<=2) & (d==4), s = get_score(xj,y(i)+2,i,x,y,f); if choose_rnd(s,smax), smax = s; xmax = xj; ymax = y(i)+2; end %if s = get_score(xj,y(i)-2,i,x,y,f); if choose_rnd(s,smax), smax = s; 16 xmax = xj; ymax = y(i)-2; end %if end %if else s = get_score(xj,y(i)-1,i,x,y,f); if choose_rnd(s,smax), smax = s; xmax = xj; ymax = y(i)-1; end %if s = get_score(xj,y(i)+1,i,x,y,f); if choose_rnd(s,smax), smax = s; xmax = xj; ymax = y(i)+1; end %if end %if end %for xj %************************************************** %get score function s=get_score(xi,yi,i,x,y,f) %get nearest animl with flag 1 global k; k=0.1; s=0; %check if position is available for j=1:size(x,2) if (j~=i) & (xi==x(j)) & (yi==y(j)), s=-10000; end %if end %for j if s==0, %calculate distance dmin = 100000; for j=1:size(x,2) if (j~=i) & (f(j)==1), d = dist(xi,yi,x(j),y(j)); if d<dmin, dmin = d; end %if end %if end %for j %for moose if f(i)==0, if (xi==x(i)) & (yi==y(i)), s = -10000; else s = dmin; 17 end %if else %wolves s = -dist(xi,yi,x(1),y(1))+k*dmin; end %if end %if %distance function function d=dist(x1,y1,x2,y2) dx = abs(x1-x2); dy = abs(y1-y2); d = dy + max(dx-dy,0)/2; %if scores are equal take randomly one of the scores function b = choose_rnd(s,smax) b = (s>smax) | ((s==smax) & (rand(1)>0.5)); %check if moose is caught function b = moose_caught(x,y) b=1; for i=2:size(x,2) b = b & (dist(x(i),y(i),x(1),y(1))==1); end %for i 3.1.3 wasp ex2.m function wasp_ex2(n,tn) %n number of wasps %tn number of timesteps c_limit = n/2; f_init = 10; p = rand(2,n)*f_init; %wasp paremeter force and foragers D = zeros(1,tn); %forage demand y1 = zeros(1,tn); %low force group y2 = zeros(1,tn); %medium force group y3 = zeros(1,tn); %high force group learn = 0.01; %learning coefficient forget = 0.01; %forgetting coefficient force_transfer = 0.5; %factor for force transfer v_n = round(rand(tn,2)*c_limit); %meetings and to brood %going through the time for t=1:tn v_meet = round(rand(v_n(t,1),2)*(n-1)+1); %which wasps will meet v_meet = non_redundant(v_meet); v_n(t,1) = size(v_meet,1); v_brood = round(rand(v_n(t,2),1)*(n-1)+1); %which wasps will be near the brood %lets fight if v_n(t,1)>0, winner_looser = fight(v_meet)’-rand(1,v_n(t,1))<=0; 18 I_win = find(winner_looser==1); I_los = find(winner_looser==0); %transfer force p(1,v_meet(I_win,1)) = p(1,v_meet(I_win,1)) + min(p(1,v_meet(I_win,2)),force_transfer); p(1,v_meet(I_win,2)) = max(p(1,v_meet(I_win,2))-force_transfer,0); p(1,v_meet(I_los,2)) = p(1,v_meet(I_los,2)) + min(p(1,v_meet(I_los,1)),force_transfer); p(1,v_meet(I_los,1)) = max(p(1,v_meet(I_los,1))-force_transfer,0); end %if %grouping y1(t) = sum(p(1,:)<=1/10*max(p(1,:))); y2(t) = sum(p(1,:)<=9/10*max(p(1,:)))-y1(t); y3(t) = n-y1(t)-y2(t); F(t,:) = p(1,:); end %for i %plot the stuff figure(1); hold on; plot(1:tn,y1,’b’); plot(1:tn,y2,’r’); plot(1:tn,y3,’g’); legend(’low force’,’medium force’,’high force’); title(’groups of wasps’) xlabel(’timesteps’) ylabel(’number of wasps’) hold off; figure(2) plot(F); title(’forces of wasps’); xlabel(’timesteps’); ylabel(’force’); function v = non_redundant(v_in) k=1; s=1; r=[0]; v=[]; if ~isempty(v_in), for i=1:size(v_in,1) b = 0; for j=1:size(v_in,2) b = (sum(find(r==v_in(i,j)))>0) | b; if ~b, r(k) = v_in(i,j); k=k+1; end %if end %for j if ~b, v(s,:) = v_in(i,:); s=s+1; end %if end %for i else, v=v_in; 19 end %if function v_r=fight(v) v_r = fermi(v(:,1),v(:,2)); %fermi function function p=fermi(f1,f2) h=1.5; p = 1./(1+exp(h.*(f1-f2))); 20