Rheinische Friedrich-Wilhelms-Universität Bonn Institut für Informatik I Marcell Missura ANT COVERING 29. Juni 2006 Seminararbeit im SS 2006 Betreuer: Ansgar Grüne Zusammenfassung Ameisen betreiben ihre Futtersuche auf eine Art, die dem einzelnen Individuum sehr wenig abverlangt. Sie legen Pheromonspuren auf den Boden, die mit der Zeit verblassen und verwenden diese als Mittel für Orientierung und indirekte Kommunikation. Ohne zentrale Steuerung, ohne Gedächtnis und mit kaum Rechenkapazität hangeln sie sich an einfachen lokalen Regeln zu einem globalen Ziel und schaffen es als Kollektiv effizient die nächstgelegene Futterquelle zu orten. Wir wollen von den Ameisen lernen und übertragen ihre Fähigkeit auf ganz primitive Roboter, die mittels verblassenden Spuren eine unbekannte Umgebung vollständig erforschen. Inhaltsverzeichnis 1 Einführung 2 2 VERTEX-WALK 2.1 Berücksichtigung von Sensorfehlern . . . . . . . . . . . . . . . 4 6 3 DIRECTED-EDGE-WALK 3.1 Berücksichtigung von Sensorfehlern . . . . . . . . . . . . . . . 7 14 4 DFS-WALK 15 4.1 Berücksichtigung von Sensorfehlern . . . . . . . . . . . . . . . 19 1 1 Einführung Ameisen betreiben ihre Futtersuche auf eine Art, die dem einzelnen Individuum sehr wenig abverlangt. Sie legen Pheromonspuren auf den Boden, die mit der Zeit verblassen und verwenden diese als Mittel für Orientierung und indirekte Kommunikation. Sie laufen dort umher, wo noch keine Spur liegt, um unbekannte Gebiete nach Nahrung zu durchsuchen, oder sie folgen der stärksten Spur in ihrer Umgebung, wenn sie gezielt eine Futterquelle erreichen wollen. Es ist dabei nicht notwendig, dass eine einzelne Ameise sich den Weg zur Futterquelle merkt und den anderen Ameisen davon erzählt. Wahrscheinlich ist sich die einzelne Ameise nicht mal dessen bewusst, wie die kooperative Strategie mit den Pheromonen funktioniert. Ohne das große Bild vor Augen zu haben befolgen die Individuen nur ganz einfache lokale Regeln und erreichen damit das globale Ziel des ganzen Kollektivs: so viel Nahrung sammeln, wie möglich, in so wenig Zeit, wie möglich. Wir lassen uns durch dieses Verhalten inspirieren und übertragen es auf eine Gruppe von einfachen Robotern, die ohne zentrale Steuerung und ohne direkte Kommunikation ein unbekanntes Gebiet erforscht. Anschaulich stellen wir uns vor, dass sie den Boden einer Wohnung oder eines Bürogebäudes säubern. Die Umgebung kann sich dynamisch ändern, Türen können auf und zu gehen, Objekte können sich bewegen, sodass ein Vorwissen über die Umgebung ohnehin kaum von Nutzen wäre. Die einzelnen Roboter sind mit nur sehr wenig Speicher und Rechenkapazität ausgestattet. Als einziges Hilfsmittel können die Agenten verflüchtigende Spuren legen, die zum Beispiel auf chemischer Basis mit Flüssigkeiten realisiert werden. Die Agenten stellen wir uns in virtueller Form vor und setzen sie modellhaft in einem Graphen aus. Die Knoten des Graphen symbolisieren atomare räumliche Einheiten, wie etwa Zimmer oder Kacheln. Die Kanten sind Wege zwischen den Räumen. Die Agenten können ihre Startposition alle im selben Knoten, oder aber auch an verschiedenen Stellen im Graphen einnehmen. Wir lassen die Zeit in diskreten Schritten laufen. In jeder Zeiteinheit wenden die Agenten lokale Regeln an, um abhängig von ihrer individuellen Situation einen Knoten in ihrer Nachbarschaft auszuwählen, den sie als nächsten besuchen. Die Spuren hinterlassen die Agenten je nach Strategie entweder auf Kanten oder auf Knoten in Form von einem Zeitstempel. Es ist nicht notwendig, dass die Agenten den absoluten Wert der Zeitstempel auslesen und arithmethische Operationen damit durchführen. Sie vergleichen zwei Spuren nur relativ und entscheiden, welche der beiden Spuren früher gelegt wurde. Sollte ein Agent mehrere Knoten bzw. Kanten mit dem selben Zeitstempel entdecken, dann wird irgendeine Heuristik (z.B. Zufall) zur Entscheidungsfindung herangezogen. Als Ziel geben wir vor, dass je nach Strategie jede Kante oder jeder Knoten mindestens einmal besucht werden muss. 2 Abbildung 1: So könnte zum Beispiel die Umgebung aussehen. Es ist durchaus möglich, dass mehrere Agenten sich zu einem Zeitpunkt in dem selben Knoten befinden. Durch eine kleine Phasenverschiebung in der Taktung der Agenten oder eine hardgecodete Prioritätsfolge wird sichergestellt, dass die Agenten ihren Zug nacheinander ausführen, und zwar so, dass ein Agent die bereits erfolgte Bewegung eines anderen Agenten in der selben Zeiteinheit noch berücksichtigen kann. Wir untersuchen im Folgenden einige Algorithmen, die mit Sicherheit zur vollständigen Abdeckung des Graphen führen, selbst wenn Kanten während der Laufzeit hinzugefügt oder entfernt werden, oder falls einzelne Agenten ausfallen, solange der Graph zusammenhängend bleibt bzw. mindestens ein Agent in einer Zusammenhangskomponente aktiv bleibt. Wir bezeichnen dies als Konvergenz. Wir interessieren uns in erster Linie für eine obere Schranke der Konvergenzgeschwindikeit. Dabei richten wir ein besonderes Augenmerk auf den Einfluss der Anzahl der gleichzeitig arbeitenden Agenten. Weiterhin untersuchen wir, wie sich Sensorfehler auf das Verhalten der Agenten und auf die Konvergenzgeschwindigkeit auswirken. Wir legen hierfür 3 einen Fehlerparamter α fest. Ein Agent kann zwei Spuren erst dann sicher voneinander unterscheiden, wenn die Zeitstempel sich um mindestens α Zeiteinheiten unterscheiden. Liegen zwei Spuren zeitlich näher als α zusammen, ist es dem Zufall überlassen, welche Spur ein Agent als die ältere einschätzt. Diese Ausarbeitung basiert auf dem technischen Bericht mit dem Titel “Distributed Covering by Ant-Robots Using Evaporating Traces“ von Israel A. Wagner, Michael Lindenbaum und Alfred M. Bruckstein [1]. Ein sehr ähnliches Thema wurde behandelt in “Cooperative Cleaners“ [2], wo die Agenten nur noch boolsche Spuren als Hilfsmittel zur Verfügung haben. Weiterführende Informationen über dieses und ähnliche Themen findet man auf der Webseite von Israel Wagner unter der Adresse http://www.cs.technion.ac.il/ wagner/. 2 VERTEX-WALK Als erstes betrachten wir ein Modell, in welchem die Agenten die Spuren auf den Knoten des Graphen hinterlassen. Entsprechend ist es unser Ziel, dass jeder Knoten des Graphen mindestens einmal besucht werden muss. Sei v ∈ V ein Knoten, dann bezeichnet s(v) den Zeitpunkt, zu dem die letzte Spur auf v gesetzt wurde. In jedem Schritt führt ein Agent folgenden Algorithmus aus: VERTEX-WALK(Knoten v) /* erhöhe die Zeit */ t = t+1; /* wähle den ältesten Nachbarn u von v */ u = arg min s(u), u in N(v); /* setze Spur auf u */ s(u) = t; /* weiter zu u */ GO TO u; END VERTEX-WALK Zu jeder Zeiteinheit bewegen sich die Agenten also von v aus zum ältesten Nachbarknoten weiter und legen dort eine Spur. Sei u ein Nachbarknoten von v und d(v) der Grad von v. u wird spätestens nach jedem d(v)-ten Besuch von v besucht, denn dann sind alle anderen Nachbarn von v besucht worden und 4 u ist somit der älteste Nachbar von v. Dies impliziert, dass jeder Nachbar von v irgendwann besucht wird. Da dies für alle v ∈ V gilt, ist garantiert, dass die VERTEX-WALK Strategie irgendwann konvergiert. Selbst wenn Knoten entfernt oder hinzugefügt werden, oder falls einige Agenten ausfallen, werden auf jeden Fall früher oder später alle Knoten abgedeckt, solange mindestens ein Agent arbeitet und der Graph zusammenhängend bleibt. Erwähnt sei noch folgender Spezialfall. Sei ein Teilgraph mit nur wenigen Knoten an den restlichen Graphen angebunden. Wenn immer genau zum richtigen Zeitpunkt, wenn ein Agent versucht den Teilgraphen zu betreten, der entsprechende Knoten vor der Nase des Agenten entfernt wird, und nachdem der Agent weitergezogen ist wieder eingefügt wird, dann bleibt der Graph stets zusammenhängend, aber kein Agent schafft es in den Teilgraphen zu gelangen und zu säubern. Nun ermitteln wir eine obere Schranke für die Laufzeit, die maximal benötigt wird, um den gesamten Graphen zu erkunden. Wir bezeichnen mit f (v) die Anzahl der Besuche von Knoten v, wobei wir Besuche von mehreren Agenten zum selben Knoten in einer Zeiteinheit nur als einen Besuch werten. Wenn zum Beispiel k Agenten alle im selben Knoten s starten und s nur einen Nachbarn u hat, dann haben alle Agenten in der ersten Zeiteinheit keine andere Wahl, als u zu besuchen. Wir zählen bei u trotzdem nur einen Besuch. Als erstes halten wir fest, dass die Besuchszahlen von zwei benachbarten Knoten nicht allzu weit ausseinander liegen können. Es gilt: Lemma 1: f (v) ≤ ∆(f (u) + 1) wobei u und v benachbarte Knoten sind und ∆ = maxv∈V {d(v)}, der maximale Knotengrad im Graphen. Beweis. u wird spätestens bei jedem d(v)-ten Besuch von v besucht, denn dann sind alle anderen Nachbarn von v besucht worden und u ist somit der älteste Nachbar von v. Außerdem gilt: d(v) ≤ ∆. 2 Je weiter zwei Knoten voneinander entfernt sind, umso mehr können die Besuchszahlen abweichen. Seien v1 , vq ∈ V und π = (v1 , v2 , ..., vq ) der kürzeste Pfad von v1 nach vq . Korollar 1: f (vq ) ≤ ∆f (vq−1 ) + ∆ ≤ ∆2 f (vq−2 ) + ∆2 + ∆ ≤ ... 5 ≤ ∆q−1 f (v1 ) + q−1 X ∆i i=1 ≤ ∆q f (v1 ) + ∆q ≤ ∆d f (v1 ) + ∆d mit d = Durchmesser des Graphen, also der längste kürzeste Pfad zwischen zwei Knoten. Beweis. Folgt aus Lemma 1. Im vorletzen Schritt verwenden wir die TatP i q sache, dass q−1 i=1 ∆ ≤ ∆ gilt, was sich durch eine einfache Induktion zeigen lässt. ∆ muss dabei > 1 sein, also müssen wir Graphen mit ∆ = 1 aus diesem Korollar rausnehmen. Wir wissen allerdings, dass solche Graphen degenerierte Fälle sind, die nur aus zwei Knoten bestehen, die mit einer Kante verbunden sind. Dieser Graph kann ein einzelner Agent in einem Schritt erkunden. 2 Dieses Korollar verwenden wir nun, um eine obere Schranke zu ermitteln. Angenommen der Graph ist noch nicht vollständig bedeckt und es existiert noch ein Knoten v mit f (v) = 0. Wenn wir diesen Knoten o.B.d.A. als v1 in Korollar 1 einsetzen, erhalten wir: f (vq ) ≤ ∆d f (v1 ) + ∆d = ∆d Kein Knoten im Graphen kann öfter, als ∆d oft besucht worden sein. Wen es n Knoten im Graphen gibt, dann müssen im gesamten Graphen weniger als n∆d Besuche gezählt worden sein. Da wir pro Zeiteinheit mindestens einen Besuch zählen, kann also die vergangene Zeit die Obergrenze n∆d nicht überschritten haben. Es gilt: tk ≤ n∆d wobei tk die die Zeit ausdrückt, die k Roboter benötigen um den Graphen vollständig zu bedecken. Leider ist diese obere Schranke exponentiell im Durchmesser des Graphen. Eine bessere Abschätzung ist zur Zeit nicht bekannt, aber da Simulationen ein deutlich besseres Verhalten zeigen, hofft man eines Tages eine genauere obere Schranke angeben zu können. 2.1 Berücksichtigung von Sensorfehlern Wenn wir Sensorfehler in Form des bereits beschriebenen Fehlerparameters α berücksichtigen, dann kann ein Agent das Alter von zwei Knoten nicht so 6 recht voneinander unterscheiden, wenn sie nicht um mindestens α Zeiteinheiten weit ausseinander liegen. Betrachten wir wieder zwei benachbarte Knoten u und v. Knoten v kann zunächst α oft besucht werden, bevor zum ersten mal ein Nachbar von v einen Zeitstempel bekommt, der diesen Nachbarn für den Agenten eindeutig als jünger als u riechen lässt. Es ist dabei unerheblich, ob alle α Besuche nur bei einem Nachbar von v gezählt werden, oder ob die α Besuche sich auf mehrere Nachbarn von v ausgenommen u verteilen. Nun können nur noch weniger als ∆ viele Besuche zu v folgen, nach denen noch jeder Nachbar von v ausser u einen aktuellen Zeitstempel bekommt. Beim darauf folgenden Besuch kann der Agent die meisten Nachbarn von v nicht voneinander unterscheiden, aber er kann eindeutig sagen, dass u der älteste Nachbar ist. Dementsprechend ändert sich Lemma 1 zu: Lemma 1.α: f (u) ≤ (∆ + α)(f (v) + 1) daraus folgt: Korollar 1.α: f (vq ) ≤ (∆ + α)d f (v1 ) + (∆ + α)d Und die neue obere Schranke für die Laufzeit lautet: tk ≤ n(∆ + α)d Offensichtlich hat der Sensorfehler keinen allzu großen Einfluss auf die Laufzeit. 3 DIRECTED-EDGE-WALK Wir betrachten nun ein Szenario, in dem die Agenten ihre Spuren wieder auf die Kanten des Graphen legen, aber diesmal in beide Richtungen! Für eine Kante (u, v) ∈ E enthält die Spur s(u, v) den Zeitpunkt, zu dem ein Agent das letzte mal von Knoten u zu Knoten v übergegangen ist und s(v, u) entsprechend die umgekehrte Richtung. Wir gehen also zu einem gerichteten, doppelt verketteten Graphen über. Die Kante (v, u) zeigt dann von v auf u und (u, v) ist eine andere Kante, die von u auf v zeigt. Wir verdoppeln zwar dadurch die Anzahl der Kanten und damit auch die Arbeit der Agenten, aber wie sich zeigen wird, werden wir durch eine deutlich bessere obere Schranke belohnt. Die Agenten befolgen die gewohnte lokale Regel: DIRECTED-EDGE-WALK(Knoten v) 7 /* erhöhe die Zeit */ t = t+1; /* wähle die älteste von v ausgehende Kante */ u = arg min s(v,u), u in N(v); /* setze Spur */ s(v,u) = t; /* weiter zu u */ GO TO u; END DIRECTED-EDGE-WALK Um eine obere Schranke für die komplette Abdeckung aller Kanten des Graphen anzugeben, müssen wir zunächst eine Reihe von Notationen und Lemmata einführen. Für einen Knoten v ∈ V bezeichnen wir mit Pv die Sequenz der Knoten, die zum Zeitpunkt t von v aus besucht wurden. Pv enthält also die Nachbarknoten von v genau in der Reihenfolge, wie sie von v aus besucht wurden. Lemma 1: Pv ist eine Periode mit der Länge d(v). Beweis. Die lokale Regel legt fest, dass ein Agent die Kante mit der ältesten von v ausgehenden Spur als nächstes besucht und sie dabei mit einer frischen Spur zur jüngsten Kante macht. Dieses Verhalten gleicht dem einer Queue, wobei stets das erste Element entfernt und wieder hinten angestellt wird. Ist die Besuchsreihenfolge der von v ausgehenden Kanten einmal festgelegt, so wird sie nie wieder verändert. Eine Kante e wird genau bei jedem d(v)-ten Besuch frisch markiert und Pv ist somit periodisch mit der Länge d(v). 2 Dieses Lemma zeigt bereits die Konvergenz, denn es sagt insbesondere aus, dass früher oder später jede Kante ausgehend von einem Knoten v besucht wird. Da das für alle v ∈ V gilt, wird irgendwann jede Kante des Graphen besucht, solange der Graph zusammenhängend ist. Auch die Robustheit dieser Strategie lässt sich daraus ableiten, denn Kanten und Knoten können während der Säuberungszeit eingefügt und entfernt werden, die Agenten werden die Änderung früher oder später entdecken, solange mindestens ein Agent arbeitet und der Graph zusammenhängend bleibt. Wir zählen, wie oft eine Kante von u nach v von einem Agenten überquert wird, und bezeichnen die Anzahl mit f (u, v), dem Fluss auf der Kante 8 (u, v) ∈ E. Diesmal brauchen wir auf den Besuch von mehreren Agenten in einer Zeiteinheit keine Rücksicht zu nehmen, wir werten also jede einzelne Überquerung einer Kante. Aus Lemma 1 wird schnell ersichtlich, dass zwei von dem selben Knoten ausgehende Flüsse sich höchstens um 1 unterscheiden. Lemma 2: Seien u, v, w ∈ V und v, w Nachbarn von u. Dann ist |f (u, v) − f (u, w)| ≤ 1 Beweis. Folgt aus Lemma 1. 2 Bemerkung: Für zwei eingehende Flüsse zu einem Knoten gilt das nicht unbedingt. Betrachten wir nun weiter Flüsse im Graphen über ganze Schnitte hinweg. Ein Schnitt zerteilt die Knotenmenge V des Graphen in zwei echte Untermengen S ⊂ V und S 0 = V \S. Mit (S, S 0 ) ⊆ E bezeichnen wir die Menge von Kanten zwischen Knotenpaaren, von denen einer in S und der andere in S 0 liegt. Dies sind die Kanten, die den Schnitt zwischen S und S 0 kreuzen. Der Fluss durch den Schnitt ist dann: X f (S, S 0 ) := f (u, v) u∈S,v∈S 0 An dieser Stelle können wir einen Vorteil aus den gerichteten Spuren ziehen, denn wir können den Fluss über einen Schnitt in zwei Richtungen aufteilen und den maximal möglichen Unterschied eingrenzen. Der Fluss durch einen Schnitt in eine Richtung kann sich von dem Fluss durch den Schnitt in die andere Richtung höchstens um k unterscheiden, wobei k die Anzahl der Agenten in G ist. Lemma 3: Für einen beliebigen Schnitt in G gilt: |f (S, S 0 ) − f (S 0 , S)| ≤ k Beweis. Ein Agent, der den Schnitt einmal von S nach S 0 überquert, verändert den Flussunterschied um 1. Bevor er den Schnitt erneut von S nach S 0 überqueren kann, muss er erst wieder von S 0 nach S zurück, wobei er die vorhin verursachte Differenz wieder rückgängig macht. k Agenten können also den Unterschied maximal um k beeinflussen und anfänglich sind alle Flüsse mit 0 initialisiert. 2 Unser Ziel ist einen maximal möglichen Unterschied der Flüsse auf zwei Kanten anzugeben. Damit können wir, wenn wir eine Kante mit Nullfluss 9 annehmen, den Gesamtfluss im Graphen eingrenzen und daraus auf die maximal Konvergenzzeit schließen. Sei v ∈ V ein Knoten von G. Wir bezeichnen mit g(v) = maxu∈N (v) {f (v, u)} den maximalen Fluss ausgehend von v. Der maximale Fluss von v kann sich nur um 1 von dem minimalen Fluss aus v heraus unterscheiden (Lemma 2). Wir sortieren die Knotenmenge V = {v1 , ..., vn } in eine aufsteigende Reihenfolge in Bezug auf den maximalen Fluss g(vi ), sodass gilt: g(v1 ) ≤ g(v2 ) ≤ ... ≤ g(vn ) Wir können den Unterschied der maximalen ausgehenden Flüsse von zwei Knoten, die in der sortierten Knotenmenge nebeneinander liegen, folgendermaßen beschränken. Wir legen einen Schnitt durch den Graphen, der genau zwischen vi und vi+1 verläuft und die sortierte Knotenmenge in zwei disjunkte Teile teilt. Seien S[1 : i] und S[i+1 : n] die Untermengen {v1 , ..., vi } ⊂ V und {vi+1 , ..., vn } ⊂ V . Wir verwenden die Notation C(i, i + 1) als Abkürzung für (S[1 : i], S[i + 1 : n]), die Menge der schnittkreuzenden Kanten. Lemma 4: Zu jedem Zeitpunkt und für alle 1 ≤ i ≤ n gilt: g(vi+1 ) − g(vi ) ≤ 1 + k |C(i, i + 1)| Beweis. Da wir die Knoten nach ihrem maximalen Ausfluss sortiert haben, gilt für k ≤ i und x ein beliebiger Knoten aus V : f (vk , x) ≤ g(vk ) ≤ g(vi ) Und für i + 1 ≤ j: g(vi+1 ) ≤ g(vj ) Lemma 2 ≤ f (vj , x) + 1 Es folgt also: g(vi+1 ) ≤ f (vj , x) + 1 g(vi+1 ) − g(vi ) ≤ f (vj , vk ) + 1 − f (vk , vj ) g(vi+1 ) − g(vi ) − 1 ≤ f (vj , vk ) − f (vk , vj ) Anhand Abbildung 2 kann man sich auch gut vorstellen, dass je weiter die Knoten einer schnittkreuzenden Kante in der Sortierung voneinander entfernt sind, umso größer der Flussunterschied auf dieser Kante werden kann. Der Flussunterschied auf einer Kante zwischen in der Sortierung benachbarten Knoten ist stets am kleinsten. 10 Abbildung 2: Beweis von Lemma 4. Wenn wir den kleinstmöglichen Unterschied mit der Anzahl der schnittkreuzenden Kanten multiplizieren, dann haben wir den gesamten Flussunterschied durch den Schnitt unterschätzt. Anderseits ist der Gesamtunterschied auf den Schnitt nach Lemma 3 durch k von oben beschränkt. |C(i, i + 1)| (g(vi+1 ) − g(vi ) − 1) ≤ Lemma 3 ≤ |f (S[1 : i], S[i + 1 : n]) − f (S[i + 1 : n], S[1 : i])| k Also folgt die Behauptung: |C(i, i + 1)|(g(vi+1 ) − g(vi ) − 1) ≤ k g(vi+1 ) − g(vi ) ≤ 1 + k |C(i, i + 1)| 2 Jetzt können wir den Unterschied der maximalen Flüsse von zwei beliebigen Knoten angeben. Wir müssen nur zählen, wie viele Knoten in der Sortierung zwischen den beiden Knoten liegen und entsprechend oft den größtmöglichen 11 Unterschied zwischen nebeneinanderliegende Knoten aufsummieren. Sei i < j, sodass vi vor vj in der Sortierung steht. Dann gilt: g(vj ) − g(vi ) ≤ j−1 Xµ 1+ l=i k |C(l, l + 1)| ¶ ≤n−1+ n−1 X l=1 k |C(l, l + 1)| Korollar 1: Für zwei beliebige Knoten gilt: ∀ u, v ∈ V : |g(u) − g(v)| ≤ n − 1 + n−1 X i=1 k |C(i, i + 1)| Wir können jetzt noch von maximalen Flüssen zu beliebigen Flüssen auf zwei Kanten übergehen. Wegen Lemma 2 wissen wir, dass wir die Ungleichung höchstens um 1 korrigieren müssen. Korollar 2: ∀ (u, v), (x, y) ∈ E : |f (u, v) − f (x, y)| ≤ n + n−1 X i=1 k |C(i, i + 1)| Im Grunde haben wir damit schon unser Ziel erreicht, aber die Formel ist noch nicht sehr aussagekräftig. Um sie weiter zu vereinfachen, führen wir den Begriff der Schnittresistenz ein. Definition 1: Sei π(V ) eine beliebige Permutation der Knotenmenge. Dann ist die durch π induzierte Schnittresistenz: ρ(π) := n−1 X i=1 1 |C(πi , πi+1 )| Die Schnittresistenz von G definieren wir als die maximale Resistenz über alle möglichen Permutationen von G: ρ(G) := max ρ(π) π∈Sn Die Schnittresistenz ist ein gutes Maß dafür, wie sehr sich ein Graph gegen die gleichzeitige Durchforstung von mehreren Agenten wehrt. Je besser der Graph verbunden ist, umso besser können sich die Agenten im Graphen verteilen und kooperativ durchforsten und umso niedriger fällt auch die Resistenz aus. Es folgt: 12 Korollar 3: ∀ (u, v), (x, y) ∈ E : |f (u, v) − f (x, y)| ≤ n + n−1 X k |C(i, i + 1)| i=1 n−1 X = n+k i=1 1 |C(i, i + 1)| ≤ n + kρ(G) Wir sehen also, dass die Flüsse auf zwei beliebigen Kanten maximal um n + kρ(G) abweichen können. Damit haben wir endlich das Werkzeug in der Hand, um die Zeit von oben einzuschränken, die die k Agenten benötigen, um alle Kanten mindestens einmal zu durchqueren. Nach gewohnter Art stellen wir uns vor, dass es eine Kante im Graphen gibt, dessen Fluss noch 0 ist. Die obere Schranke aus Korollar 3 verwenden wir als maximalen Fluss für jede andere Kante im Graphen. Wir zählen alle Flüsse zusammen und teilen sie durch die Anzahl der Agenten und können dann bestimmen wie viel Zeit maximal vergangen sein kann. Theorem 1: Sei tk die Zeit, die k Agenten mit der Strategie DIRECTEDEDGE-WALK benötigen, um jede Kante des Graphen G mindestens einmal zu besuchen. Dann ist: tk ≤ n∆( n + ρ(G)) k mit n = |V (G)| Anzahl der Knoten, ∆ = maxv∈V d(v) der maximale Ausgangsgrad und ρ(G) die Schnittresistenz von G, wie oben definiert. Beweis. Angenommen es sind noch nicht alle Kanten besucht worden. Dann gibt es mindestens eine Kante mit f (u, v) = 0. Unsere Agenten sind nicht untätig und erhöhen den Gesamtfluss im Graphen zu jedem Zeitpunkt genau um k. D.h. nach tk Zeitschritten ist der Fluss in G insgesamt k tk . Nach Korollar 4 kann aber der Fluss auf keiner Kante im Graphen allzu sehr von 0 abweichen. Es gilt: k tk = X f (u, v) ≤ (|E| − 1)(n + kρ(G)) (u,v)∈E (|E| − 1) ≤ n∆ k tk ≤ n∆(n + kρ(G)) 13 Nun brauchen wir nur noch durch k zu teilen und wir erhalten eine obere Schranke, die nicht überschritten werden kann, solange nicht jede Kante mindestens einmal besucht wurde: tk ≤ n∆( n + ρ(G)) k 2 Abbildung 3: Ein besonderes schwieriger Fall. ρ(G) liegt schlimmstenfalls in O(n), wenn der Graph nur ein langer Pfad ist. Ist der Graph vollständig verbunden, dann liegt ρ(G) sogar in O(1). Wenn wir ∆ konstant halten, dann bleibt unsere Laufzeit also in O(n2 ). Abbildung 3 zeigt, dass es Fälle gibt, in denen diese Zeit auch tatsächlich benötigt wird. 3.1 Berücksichtigung von Sensorfehlern Betrachten wir jetzt, wie sich der DIRECTED-EDGE-WALK Algorithmus unter dem Einfluss von Sensorstörungen verhält. Wir nehmen erneut an, dass ein Agent zwei Spuren erst dann sicher voneinander unterscheiden kann, wenn die Zeitpunkte, zu denen die Spuren gesetzt wurden, mindestens um α Zeiteinheiten ausseinander liegen. Die Periodizität von Pv gemäß Lemma 1 geht uns dadurch verloren, denn ein Agent wählt per Zufall die nächste von v ausgehende Kante aus, wenn mehrere zur Auswahl stehen, die der Agent nicht eindeutig unterscheiden kann. Trotzdem wird mit sicherheit jede von v ausgehende Kante besucht, denn spätestens nachdem α Zeiteinheiten vergangen sind, ist die Zeit weit genug fortgeschritten, sodass die von v ausgehende Kanten Zeitstempel bekommen, die aktuell genug sind, sodass noch nicht besuchte Kanten eindeutig als älter erkannt werden. Die Konvergenzgarantie bleibt also erhalten. Eine neue obere Schranke für die Laufzeit unter der Berücksichtigung von fehlerhaften Sensoren kann ich zu diesem Zeitpunkt leider nicht angeben. In der Originalarbeit ist eine kleine Unklarheit in der Argumentation aufgetaucht, die eine schlüssige Herleitung einer oberen Schranke verhindert. 14 4 DFS-WALK In diesem Kapitel wenden wir uns einem Algorithmus zu, der auf eine klassische Tiefensuche im Graphen basiert. Die Tiefensuche ist bekannt für seine Effizienz, darum sind wir auch bestrebt ihn in unserem Ant Covering Modell zu implementieren. Wir werden jedoch sehen, dass es noch einige Probleme zu lösen gibt, bevor wir den DFS in einem Multi-Agent Szenario zuverlässig einsetzen können. Die Agenten führen hier wieder eine knotenbasierte Abdeckung durch, die Spuren werden auf die Knoten gelegt und das Ziel ist jeden Knoten mindestens einmal zu betreten. Schauen wir uns zunächst den Algorithmus an: DFS-WALK(Knoten v) /* Erhöhe die Zeit. */ t = t+1; /* Suche einen noch nicht besuchten Nachbarknoten. */ if (Exists u in N(v) : s(u) == 0) { s(u) = t; GO TO u; } /* Abbruch Kriterium */ else if (for all u in N(v): s(u) > s(v)) { /* Wenn es keinen älteren Nachbarn gibt, ist der Agent wieder am Anfang der Suche angelangt. */ SHUTDOWN; } /* Backtracking */ else { /* Wähle den jüngsten Nachbarn u von v, der aber noch älter ist, als v selbst. */ u = max {u| u in N(v), s(u) < s(v)}; GO TO u; } END DFS-WALK 15 Während der Suche auf dem Graphen kann ein Agent 3 Arten von Situationen begegnen: 1. Es gibt mindestens einen noch nicht besuchten Nachbarknoten. Die Suche kann fortgesetzt werden. 2. Es gibt keinen unbesuchten Nachbarknoten und mindestens ein Nachbarknoten ist älter, als der aktuelle. Der Agent muss backtracken und einen Schritt zum jüngsten der älteren Nachbarknoten zurückgehen. 3. Alle Nachbarknoten sind jünger, als der aktuelle. Der Agent hat das Ende seiner Suche erreicht und hält an. Man sieht gleich, dass etwas höhere Anforderungen an den einzelnen Agenten gestellt sind. War in den vorherigen Algorithmen nur nach der ältesten Spur gefragt, so muss hier der Agent zwischen “keiner Spur“ und “gesetzter Spur“ unterscheiden können und darauf eine Entscheidung basieren. Die Wahl des jüngsten Nachbarn von v, der aber noch älter ist als v, könnte man auch als eine schwierigere Aufgabe erachten, als einfach nur ein Extremum der anliegenden Spuren zu finden, wie es bei den vorherigen Algorithmen der Fall war. Zudem muss der Agent sein Spurlegeverhalten kontrollieren, sodass er beim Backtracken keine Spur auf dem Graphen hinterlässt, sonst würde das Backtracken nicht funktionieren. Ist nur ein einzelner Agent im Graphen unterwegs, so kann er eine saubere Tiefensuche durchführen und erreicht jeden Knoten garantiert in weniger als 2|V | Schritten. Mehrere gleichzeitig arbeitende Agenten können sich jedoch gegenseitig stören und eine Konvergenz verhindern. Abbildung 4 zeigt einen Fall, wo ein Agent einen anderen dazu bringt auf einem falschem Weg zu backtracken und einen Knoten nicht zu besuchen. Robust ist diese Strategie auch nicht gerade, denn Änderungen am Graphen während der Laufzeit sowie der Ausfall eines Agenten können dazu führen, dass der Graph nicht komplett abgedeckt werden kann. Und wenn ein Agent zu einem Startpunkt zurückkehrt, legt er die Arbeit nieder, anstatt sich erneut auf die Suche zu machen und seinen Kollegen zu helfen. 16 Abbildung 4: Die Spur eines Agenten lässt einen anderen in die falsche Richtung backtracken. 17 Die Agenten starten, wie in der Abbildung in Situation a) dargestellt. Seien die ersten 2 Schritte der Suche, wie in b) und c) dargestellt. Da es keinen freien Nachbarknoten gibt, ist der Agent in der Mitte in Situation c) gezwungen zu backtracken. Er sucht den jüngsten Nachbarn, findet die Spur mit dem Zeitstempel “2“ des anderen Agenten und gerät in Situation d). Von da aus kann er nur noch rückwärts auf der Spur des anderen Agenten backtracken und hält schließlich im Startknoten des anderen Agenten in Situation e). Der leere Knoten unten links wurde nie besucht. Um diesen Problemen entgegenzuwirken, führen wir, eine Art reset Mechanismus ein. Wir statten jeden Agenten mit einer Speicherzelle aus, in der sie eine Spur (Zeitstempel) speichern können. Erreicht ein Agent einen Anfangsknoten, so belegt er seinen Speicher mit dem aktuellen Zeitstempel und leutet individuell für sich eine neue Epoche ein. Alle Spuren, die vor Beginn seiner Epoche gelegt wurden, erachtet der Agent als nicht vorhanden. Es ist als würde der Agent für sich persönlich alle Spuren im Graphen annulieren und eine neue Suche beginnen. Zu Beginn werden alle Agenten mit der Epoche 1 initialisiert. Der Algorithmus wird dementsprechend so angepasst: DFS-WALK(Knoten v) /* Erhöhe die Zeit. */ t = t+1; /* Suche einen noch nicht besuchten Nachbarknoten. */ if (Exists u in N(v) : s(u) < epoche) { s(u) = t; GO TO u; } /* Abbruch Kriterium */ else if (for all u in N(v): s(u) > s(v)) { /* Wenn es keinen älteren Nachbarn gibt, ist der Agent wieder am Anfang der Suche angelangt. */ epoche = t; } /* Backtracking */ else { /* Wähle den jüngsten Nachbarn u von v, der aber noch älter ist, als v selbst. */ 18 u = max {u| u in N(v), s(u) < s(v)}; GO TO u; } END DFS-WALK Nun ist der Algorithmus robuster geworden. Das gegenseitige Stören der Agenten ist jetzt nicht mehr so schlimm, denn ein Agent, der fälschlicher Weise zum Anfangspunkt eines anderen Agenten zurückgekehrt ist, fängt eine neue Suche an und hat eine neue Chance alle Knoten des Graphen zu erreichen. Änderungen am Graphen können die Agenten auch verkraften, denn sie verhalten sich adaptiv, dadruch dass sie ihre Suche immer wieder neu beginnen. Ein Beweis oder ein Gegenbeispiel, ob unter Einsatz der Speicherzellen mehrere Agenten den Graphen garantiert bedecken oder nicht, müsste aber noch erbracht werden. 4.1 Berücksichtigung von Sensorfehlern Abbildung 5: Ein kleiner Sensorfehler lässt den Agenten in die falsche Richtung backtracken. Der leere Knoten wird nicht erreicht. Gegen Sensorfehler ist die DFS Strategie nicht besonders gut gerüstet. Abbildung 5 zeigt, wie ein Fehler beim Backtracken dazu führt, dass ein Knoten nicht besucht wird. Der Agent startet bei Knoten 1 und schreitet über Knoten 2 zu Knoten 3 fort. Nun ist er in der Sackgasse und muss backtracken. Ein Sensorfehler verleitet ihn dazu zu Knoten 1 statt zu Knoten 2 zu backtracken. Dort beendet er seine Suche und der leere Knoten bleibt unbesucht. Selbst wenn der Agent die Fähigkeit besitzt eine neue Suche zu beginnen, existiert eine Wahrscheinlichkeit, dass er immer wieder den selben Fehler macht. Auch wenn mehrere Agenten im Graphen arbeiten, lässt sich ein 19 Beispiel konstruieren, wo jeder Agent in seiner eigenen Falle sitzt und immer wieder den selben Fehler macht. Alternativ könnte der Agent bei Knoten 3 fälschlicher Weise der Meinung sein, dass er den Startknoten erreicht hat und die Suche abbrechen. Startet er eine neue Suche, so könnte er die selben Schritte zu Knoten 1 zurückgehen und dort wiederum irrtümlich abbrechen. Mit einer gewissen Wahrscheinlichkeit kann sich der Agent in einer unendlichen Reihe von Sensorfehlern befinden und immer nur den selben Pfad auf und ab laufen. Man sieht also, der derzeitige Stand der DFS Strategie ist alles andere als befriedigend, aber möglicherweise finden sich zukünftige Lösungsansätze, die eine stabile Implementierung ermöglichen. Literatur [1] M. L. Israel A. Wagner and A. M. Bruckstein. Distributed covering by ant-robots using evaporating traces. Technical report, IBM Haifa Research Laboratory, 1996. [2] I. A. Wagner and A. M. Bruckstein. Cooperative cleaners : a study in ant-robotics. Technical report, IBM Haifa Research Laboratory, 1995. 20