/*
* Datei: MutArt1VT.java
* Autor(en): Lukas König
* Java-Version: 6.0
* Erstellt (vor): 09.02.2011
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
* author or licensor (but not in any way that suggests that they endorse
* you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
* distribute the resulting work only under the same or a similar license to
* this one.
*
* + Detailed license conditions (Germany):
* http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
* http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/
package eas.users.lukas.marbImplicitEvolution;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import eas.math.MiscMath;
import eas.miscellaneous.StaticMethods;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.EndlicherAutomat;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.Transition;
import eas.simulation.spatial.standardBrains.marb.MARBBrain;
import eas.startSetup.marbBuilder.graph.Knoten;
/**
* Die erste Mutationsart mit angepasstem Modus für die Mutation von
* Translatoren.
*
* @author Lukas König
*/
public class MutArt1VT implements MARBMutation {
/**
*
*/
private static final long serialVersionUID = -5283317635242826579L;
/**
* Der Zufallsgenerator.
*/
private Random rand;
/**
* Der konstante Parameter zur Einschr�nkung direkter Zahlmutationen.
* Es muss gelten: 0 < k <= 255.
*/
private int k;
private int numAgentSensors;
private int numAgentActuators;
/**
* Konstruktor.
*
* @param random Der Zufallsgenerator.
* @param kKonst Die Konstante k aus der Definition der Mutation: Gibt an
* wie Groß die änderung bei bspw. Sensorwerten maximal
* sein darf.
* @param mod Der Modus (Verhalten oder übersetzer).
* @param params Der Parametersatz.
*/
public MutArt1VT(
final Random random,
final int kKonst,
final int numSensors,
final int numActuators) {
this.rand = random;
this.k = kKonst;
this.numAgentSensors = numSensors;
this.numAgentActuators = numActuators;
}
/**
* Falls (mind.) eine "false"-Kante im Automaten existiert, wird eine
* zufällige "false"-Kante gelöscht. Sonst bleibt der Automat unverändert.
* Die Zufälligkeit bezieht sich nur auf die Wahl des Ausgangsknotens.
*
* SYNTAKTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob eine Kante entfernt wurde.
*/
public final boolean mutationFalseKanteRem(final EndlicherAutomat ea) {
HashMap<Integer, LinkedList<Transition>> alleBeds
= ea.getAlleBedingungen();
ArrayList<Integer> alleKnoten
= new ArrayList<Integer>(alleBeds.keySet());
LinkedList<Transition> aktBeds;
Integer aktKnoten;
Iterator<Transition> it;
String aktBed;
Transition vollstBed;
Integer fZustand;
int pruefIndex;
while (alleKnoten.size() > 0) {
pruefIndex = this.rand.nextInt(alleKnoten.size());
aktKnoten = alleKnoten.get(pruefIndex);
aktBeds = alleBeds.get(aktKnoten);
it = aktBeds.iterator();
while (it.hasNext()) {
vollstBed = it.next();
aktBed = vollstBed.getCond().formatted();
if (aktBed.charAt(1) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE) {
fZustand = new Integer(vollstBed.getFolgezustand());
ea.entferneKante(aktKnoten, fZustand, vollstBed);
return true;
}
}
alleKnoten.remove(pruefIndex);
}
return false;
}
/**
* fügt eine "false"-Kante in den Automaten ein, falls mindestens ein
* Zustand existiert. Die eingefügte Kante zeigt
* von rand(Z) nach rand(Z)
* mit Z = Zustände des Automaten.
*
* SYNTAKTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob eine Kante eingefügt wurde.
*/
public final boolean mutationFalseKanteEin(final EndlicherAutomat ea) {
ArrayList<Integer> knListe = ea.getKnList();
Integer zufallsKnoten1;
Integer zufallsKnoten2;
if (knListe.size() > 0) {
zufallsKnoten1 = knListe.get(this.rand.nextInt(knListe.size()));
zufallsKnoten2 = knListe.get(this.rand.nextInt(knListe.size()));
if (!ea.kanteExistiert(zufallsKnoten1, zufallsKnoten2)) {
ea.einfuegKante(
zufallsKnoten1,
zufallsKnoten2,
" " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE + " ",
1);
return true;
}
}
return false;
}
/**
* löscht einen Zustand ohne eingehende Kanten aus dem Automaten,
* falls mindestens ein solcher Zustand existiert.
*
* SYNTAKTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob ein Zustand gelöscht wurde.
*/
public final boolean mutationZustandRem1(final EndlicherAutomat ea) {
ArrayList<Integer> knListe = ea.getKnList();
Knoten zufallsKnoten1;
int zufallsIndex;
while (knListe.size() > 0) {
zufallsIndex = this.rand.nextInt(knListe.size());
zufallsKnoten1 = ea.holeKnoten(knListe.get(zufallsIndex));
if (!ea.istStartZ(zufallsKnoten1)
&& zufallsKnoten1.holeVorgaenger().size() == 0) {
ea.entferneKnoten(knListe.get(zufallsIndex));
return true;
}
knListe.remove(zufallsIndex);
}
return false;
}
// /**
// * Löscht einen Zustand ohne ausgehende Kanten und IDLE als Befehl aus dem
// * Automaten, falls mindestens ein solcher Zustand existiert.
// *
// * SEMI-SEMANTISCH
// *
// * @param ea Der zu mutierende Automat.
// * @return Ob ein Zustand gelöscht wurde.
// */
// public final boolean mutationZustandRem2(final EndlicherAutomat ea) {
// ArrayList<Integer> knListe = ea.getKnList();
// Knoten zufallsKnoten1;
// int zufallsIndex;
//
// while (knListe.size() > 0) {
// zufallsIndex = this.rand.nextInt(knListe.size());
// zufallsKnoten1 = (Knoten) ea.holeKnoten(knListe.get(zufallsIndex));
// if (((ZInfo) zufallsKnoten1.getInfo()).getAktion()
// == Konstanten.IDLE_BEFEHL
// && zufallsKnoten1.holeNachfolger().size() == 0
// && !ea.istStartZ(zufallsKnoten1)) {
//
// ea.entferneKnoten(knListe.get(zufallsIndex));
// return true;
// }
// knListe.remove(zufallsIndex);
// }
// return false;
// }
/**
* Fügt einen Zustand ohne eingehende Kanten in den Automaten ein.
* Falls der Namensraum für Zustände überläuft, bleibt der Automat
* unverändert. Falls vorher kein Startzustand
* existierte, wird der neue Zustand zum Startzustand.
*
* SYNTAKTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob ein Zustand eingefügt wurde.
*/
public final boolean mutationZustandEin(final EndlicherAutomat ea) {
int parameter;
int befehl;
ArrayList<Integer> knListe = ea.getKnList();
final int byteMax = 255;
Integer name;
parameter = this.rand.nextInt(this.k) + 1;
befehl = StaticMethods.glVertZwischen(
1,
this.numAgentActuators,
this.rand);
for (int i = 1; i <= byteMax; i++) {
name = new Integer(i);
if (!knListe.contains(name)) {
ea.einfuegenKnoten(name, befehl, parameter, 1);
if (ea.holeStartzustand() == null) {
ea.setStart(ea.holeKnoten(name));
}
return true;
}
}
return false;
}
/**
* Mutiert eine zufällige Bedingung nach dem folgenden Muster:
* false <> a = b <> a ~ b <> a <= b <> a < b <> a # b <> a != b <> true
* Falls keine Bedingung existiert, bleibt der Automat unverändert.
*
* SEMANTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob eine Bedingung mutiert wurde.
*/
public final boolean mutationBedA(final EndlicherAutomat ea) {
ArrayList<Transition> bedingungen = ea.getBedListe();
Transition aktBed;
String aktString;
String neuString = "";
int pos;
int zufallsindex;
ArrayList<Character> zeichen = new ArrayList<Character>(2);
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GL));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KLGL));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GRGL));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KL));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GR));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UGL));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE));
boolean links = this.rand.nextBoolean();
boolean oben = this.rand.nextBoolean();
boolean var1 = this.rand.nextBoolean();
boolean var2 = !var1 || this.rand.nextBoolean();
String string1;
String string2;
if (bedingungen.size() > 0) {
zufallsindex = this.rand.nextInt(bedingungen.size());
aktBed = bedingungen.get(zufallsindex);
aktString = aktBed.getCond().formatted();
pos = this.indexZeichen(aktString,
zeichen);
if (aktString.charAt(pos)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE) {
if (var1) {
int variable1 = StaticMethods.glVertZwischen(
1,
this.numAgentSensors,
this.rand);
string1 = " "
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING + " "
+ eas.miscellaneous.StaticMethods.normZahl(variable1);
} else {
int nummer1 = this.rand.nextInt(255) + 1;
string1 = eas.miscellaneous.StaticMethods.normZahl(nummer1);
}
if (var2) {
int variable2 = StaticMethods.glVertZwischen(
1,
this.numAgentSensors,
this.rand);
string2 = " "
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING + " "
+ eas.miscellaneous.StaticMethods.normZahl(variable2);
} else {
int nummer2 = this.rand.nextInt(255) + 1;
string2 = eas.miscellaneous.StaticMethods.normZahl(nummer2);
}
neuString = aktString.substring(0, pos - 1)
+ string1
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GL + " "
+ string2
+ aktString.substring(pos + 2);
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GL) {
if (links) {
int lGrenze;
int rGrenze;
if (pos >= 6 && aktString.charAt(pos - 6)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
lGrenze = pos - 7;
} else {
lGrenze = pos - 4;
}
if (aktString.charAt(pos + 3)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
rGrenze = pos + 8;
} else {
rGrenze = pos + 5;
}
neuString = aktString.substring(0, lGrenze)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE + " "
+ aktString.substring(rGrenze);
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF
+ aktString.substring(pos + 1);
}
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF) {
if (links) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GL
+ aktString.substring(pos + 1);
} else {
if (oben) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KLGL
+ aktString.substring(pos + 1);
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GRGL
+ aktString.substring(pos + 1);
}
}
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KLGL) {
if (links) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF
+ aktString.substring(pos + 1);
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KL
+ aktString.substring(pos + 1);
}
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GRGL) {
if (links) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UNGF
+ aktString.substring(pos + 1);
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GR
+ aktString.substring(pos + 1);
}
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KL) {
if (links) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KLGL
+ aktString.substring(pos + 1);
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF
+ aktString.substring(pos + 1);
}
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GR) {
if (links) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GRGL
+ aktString.substring(pos + 1);
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF
+ aktString.substring(pos + 1);
}
}
if (aktString.charAt(pos)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF) {
if (links) {
if (oben) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KL
+ aktString.substring(pos + 1);
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.GR
+ aktString.substring(pos + 1);
}
} else {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UGL
+ aktString.substring(pos + 1);
}
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UGL) {
if (links) {
neuString = aktString.substring(0, pos)
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.NUNGF
+ aktString.substring(pos + 1);
} else {
int lGrenze;
int rGrenze;
if (pos >= 6 && aktString.charAt(pos - 6)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
lGrenze = pos - 7;
} else {
lGrenze = pos - 4;
}
if (aktString.charAt(pos + 3)
== eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
rGrenze = pos + 8;
} else {
rGrenze = pos + 5;
}
neuString = aktString.substring(0, lGrenze)
+ " "
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE
+ " "
+ aktString.substring(rGrenze);
}
}
if (aktString.charAt(pos) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE) {
if (var1) {
int variable1 = StaticMethods.glVertZwischen(
1,
this.numAgentSensors,
this.rand);
string1 = " "
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING
+ " "
+ eas.miscellaneous.StaticMethods.normZahl(variable1);
} else {
int nummer1 = this.rand.nextInt(255) + 1;
string1 = eas.miscellaneous.StaticMethods.normZahl(nummer1);
}
if (var2) {
int variable2 = StaticMethods.glVertZwischen(
1,
this.numAgentSensors,
this.rand);
string2 = " "
+ eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING
+ " "
+ eas.miscellaneous.StaticMethods.normZahl(variable2);
} else {
int nummer2 = this.rand.nextInt(255) + 1;
string2 = eas.miscellaneous.StaticMethods.normZahl(nummer2);
}
neuString = aktString.substring(0, pos - 1)
+ string1
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UGL + " "
+ string2
+ aktString.substring(pos + 2);
}
aktBed.setBedingung(neuString);
return true;
}
return false;
}
/**
* Gibt die Position einer zufälligen Folge von (zeichen1, zeichen2)
* in einem String zurück. Falls keine solche Folge existiert,
* wird -1 zurückgegeben. Der Index bezieht sich immer auf die MITTE
* des ZWEITEN Zeichens (jedes Zeichen wird als 3 character kodiert).
*
* @param bedingung Der zu durchsuchende String.
* @param zeichen1 Das erste Zeichen der Folge.
* @param zeichen2 Das zweite Zeichen der Folge.
*
* @return Die Position einer zufälligen Zeichenfolge wie beschrieben
* im String.
*/
private int indexZeichenfolge(final String bedingung,
final char zeichen1,
final char zeichen2) {
int start = this.rand.nextInt(bedingung.length());
int i;
char lastTok;
while (start % 3 != 1) {
start = (start + 1) % bedingung.length();
}
i = (start + 3) % bedingung.length();
lastTok = bedingung.charAt(start);
while (i != start) {
if (bedingung.charAt(i) == zeichen2
&& lastTok == zeichen1) {
return i;
}
lastTok = bedingung.charAt(i);
i = (i + 3) % bedingung.length();
}
return -1;
}
/**
* Gibt die Position der zu pos gehörenden �ffnenden Klammer zurück.
*
* @param bed Die zu durchsuchende Bedingung.
* @param pos Die Startposition.
*
* @return Die Position der zu pos gehörenden �ffnenden Klammer. 0, falls
* keine existiert.
*/
private int findeKlLinks(final String bed,
final int pos) {
int klammer = 0;
if (pos < 0 || pos >= bed.length()) {
return -1;
}
if (bed.charAt(pos) != eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ) {
klammer = 1;
}
for (int i = pos; i >= 0; i--) {
if (bed.charAt(i) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ) {
klammer += 1;
} else if (bed.charAt(i) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA) {
klammer -= 1;
}
if (klammer == 0) {
return i;
}
}
return 0;
}
/**
* Gibt die Position der zu pos gehörenden schließenden Klammer zurück.
*
* @param bed Die zu durchsuchende Bedingung.
* @param pos Die Startposition.
*
* @return Die Position der zu pos gehörenden schließenden Klammer.
* "lastIndex", falls keine existiert.
*/
private int findeKlRechts(final String bed,
final int pos) {
int klammer = 0;
if (pos < 0 || pos >= bed.length()) {
return -1;
}
if (bed.charAt(pos) != eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA) {
klammer = 1;
}
for (int i = pos; i < bed.length(); i++) {
if (bed.charAt(i) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA) {
klammer += 1;
} else if (bed.charAt(i) == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ) {
klammer -= 1;
}
if (klammer == 0) {
return i;
}
}
return bed.length() - 1;
}
/**
* Mutiert eine zufällige Bedingung nach dem folgenden Muster:
* (A AND true) > A < (true AND A)
* (A OR true) > true < (true OR A)
* (A AND false) > false < (false AND A)
* (A OR false) > A < (false OR A)
* Falls keine mutierbare Bedingung existiert, bleibt der Automat
* unverändert.
*
* SYNTAKTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob eine Bedingung mutiert wurde.
*/
public final boolean mutationBedBeinfacher(final EndlicherAutomat ea) {
ArrayList<Transition> bedingungen = ea.getBedListe();
Transition aktBed;
String aktString;
String neuString;
int posLKlammer;
int posRKlammer;
int pos;
int zufallsindex;
while (bedingungen.size() > 0) {
zufallsindex = rand.nextInt(bedingungen.size());
aktBed = bedingungen.get(zufallsindex);
aktString = aktBed.getCond().formatted();
pos = this.indexZeichenfolge(aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE);
if (pos < 0) {
pos = this.indexZeichenfolge(
aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE);
}
if (pos >= 0) {
posLKlammer = this.findeKlLinks(aktString, pos);
posRKlammer = pos + 3;
neuString = aktString.substring(0, posLKlammer - 1)
+ aktString.substring(posLKlammer + 2,
pos - 4)
+ aktString.substring(posRKlammer + 2);
aktBed.setBedingung(neuString);
return true;
}
pos = this.indexZeichenfolge(
aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND);
if (pos < 0) {
pos = this.indexZeichenfolge(
aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER);
}
if (pos >= 0) {
posLKlammer = pos - 3;
posRKlammer = this.findeKlRechts(aktString, pos);
neuString = aktString.substring(0, pos - 7)
+ aktString.substring(pos + 2,
posRKlammer - 1)
+ aktString.substring(posRKlammer + 2);
aktBed.setBedingung(neuString);
return true;
}
pos = this.indexZeichenfolge(aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE);
if (pos < 0) {
pos = this.indexZeichenfolge(aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE);
}
if (pos >= 0) {
posLKlammer = this.findeKlLinks(aktString, pos);
posRKlammer = pos + 3;
neuString = aktString.substring(0, posLKlammer - 1)
+ aktString.substring(pos - 1, pos + 2)
+ aktString.substring(posRKlammer + 2);
aktBed.setBedingung(neuString);
return true;
}
pos = this.indexZeichenfolge(aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER);
if (pos < 0) {
pos = this.indexZeichenfolge(aktString,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE,
eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND);
}
if (pos >= 0) {
posLKlammer = pos - 6;
posRKlammer = this.findeKlRechts(aktString, pos);
neuString = aktString.substring(0, posLKlammer - 1)
+ aktString.substring(pos - 4, pos - 1)
+ aktString.substring(posRKlammer + 2);
aktBed.setBedingung(neuString);
return true;
}
bedingungen.remove(zufallsindex);
}
return false;
}
/**
* Gibt zufällig eine Position zurück, an der eines der übergebenen Zeichen
* ist. Falls keine solche Position existiert, wird -1 zur�cgegeben.
*
* @param bedingung Der zu durchsuchende String.
* @param zeichen Liste der Zeichen, deren Position gesucht werden soll.
*
* @return Die Position eines zufälligen Zeichens wie beschrieben
* im String oder -1.
*/
private int indexZeichen(final String bedingung,
final List<Character> zeichen) {
int start = this.rand.nextInt(bedingung.length());
int i;
while (start % 3 != 1) {
start = (start + 1) % bedingung.length();
}
i = (start + 3) % bedingung.length();
while (i != start) {
if (zeichen.contains(new Character(bedingung.charAt(i)))) {
return i;
}
i = (i + 3) % bedingung.length();
}
if (zeichen.contains(new Character(bedingung.charAt(i)))) {
return i;
}
return -1;
}
/**
* Mutiert eine zufällige Bedingung nach dem folgenden Muster:
* (A AND true) < A > (true AND A)
* (A OR false) < A > (false OR A)
* Falls keine Bedingung existiert, bleibt der Automat unverändert.
*
* SYNTAKTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob eine Bedingung mutiert wurde.
*/
public final boolean mutationBedkomplexer(final EndlicherAutomat ea) {
// Sei & e {UND, ODER}
// Fall 1: Bed = A => Bed2 = (t & A)
// Fall 2: Bed = (... (A & B) ...) => Bed2 = (... ((t & A) & B) ...)
// Fall 3: Bed = (... (A & B) ...) => Bed2 = (... (A & (t & B)) ...)
// 1. Suche pos mit BED[pos] = UND oder BED[pos] = ODER.
// 2. Falls so ein pos ex.: zufällig Fall 2 oder Fall 3.
// Sonst: Fall 1.
ArrayList<Transition> bedingungen = ea.getBedListe();
Transition aktBed;
String aktString;
String neuString = "";
int posLKlammer;
int posRKlammer;
int pos;
int zufallsindex;
ArrayList<Character> zeichen = new ArrayList<Character>(2);
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND));
zeichen.add(new Character(eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER));
boolean und = this.rand.nextBoolean();
boolean fallZwei = this.rand.nextBoolean();
boolean erzwingeFall1 = this.rand.nextInt(5) == 0;
if (bedingungen.size() > 0) {
zufallsindex = this.rand.nextInt(bedingungen.size());
aktBed = bedingungen.get(zufallsindex);
aktString = aktBed.getCond().formatted();
pos = this.indexZeichen(aktString,
zeichen);
if (pos < 0 || erzwingeFall1) {
// Fall 1
if (und) {
neuString = " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND + " "
+ aktString
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ + " ";
} else {
neuString =
" " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER + " "
+ aktString
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ + " ";
}
} else {
// Fall 2 oder 3
posLKlammer = this.findeKlLinks(aktString, pos);
posRKlammer = this.findeKlRechts(aktString, pos);
if (fallZwei && und) {
neuString = aktString.substring(0, posLKlammer + 2)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND + " "
+ aktString.substring(
posLKlammer + 2,
pos - 1)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ + " "
+ aktString.substring(pos - 1);
}
if (fallZwei && !und) {
neuString = aktString.substring(0, posLKlammer + 2)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER + " "
+ aktString.substring(
posLKlammer + 2,
pos - 1)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ + " "
+ aktString.substring(pos - 1);
}
if (!fallZwei && und) {
neuString =
aktString.substring(0, pos + 2)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA + " "
+ aktString.substring(
pos + 2,
posRKlammer - 1)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.UND + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.TRUE + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ + " "
+ aktString.substring(posRKlammer - 1);
}
if (!fallZwei && !und) {
neuString = aktString.substring(0, pos + 2)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KA + " "
+ aktString.substring(
pos + 2,
posRKlammer - 1)
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.ODER + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.FALSE + " "
+ " " + eas.simulation.spatial.sim2D.marbSimulation.Konstanten.KZ + " "
+ aktString.substring(posRKlammer - 1);
}
}
aktBed.setBedingung(neuString);
return true;
}
return false;
}
/**
* Gibt die Position einer zufälligen Zahl in der Bedingung zurück.
* (Gemeint sind konstante Byte-Werte). Falls keine Zahl existiert,
* wird -1 zurückgegeben. Der Index bezieht sich immer auf die MITTE
* einer 3-stelligen Zahl. (Jedes Zeichen wird als 3 character kodiert.)
*
* @param bedingung Die zu durchsuchende Bedingung.
*
* @return Die Position einer zufälligen Byte-Konstante im String.
*/
private int indexZahl(final String bedingung) {
int start = this.rand.nextInt(bedingung.length());
int i;
char lastTok;
while (start % 3 != 1) {
start = (start + 1) % bedingung.length();
}
i = (start + 3) % bedingung.length();
lastTok = bedingung.charAt(start);
while (i != start) {
if (StaticMethods.istZiff(bedingung.charAt(i))
&& lastTok != eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
return i;
}
lastTok = bedingung.charAt(i);
i = (i + 3) % bedingung.length();
}
if (StaticMethods.istZiff(bedingung.charAt(i))
&& lastTok != eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
return i;
}
return -1;
}
/**
* Gibt die Position einer zufälligen SensorVar in der Bedingung zurück.
* Falls keine SensorVar existiert,
* wird -1 zurückgegeben. Der Index bezieht sich immer auf die MITTE
* der 3-stelligen Sensor-Nummer. (Jedes Zeichen wird als 3 character
* kodiert.)
*
* @param bedingung Die zu durchsuchende Bedingung.
*
* @return Die Position einer zufälligen SensorVar im String.
*/
private int indexSensVar(final String bedingung) {
int start = this.rand.nextInt(bedingung.length());
int i;
char lastTok;
while (start % 3 != 1) {
start = (start + 1) % bedingung.length();
}
i = (start + 3) % bedingung.length();
lastTok = bedingung.charAt(start);
while (i != start) {
if (StaticMethods.istZiff(bedingung.charAt(i))
&& lastTok == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
return i;
}
lastTok = bedingung.charAt(i);
i = (i + 3) % bedingung.length();
}
if (StaticMethods.istZiff(bedingung.charAt(i))
&& lastTok == eas.simulation.spatial.sim2D.marbSimulation.Konstanten.EING) {
return i;
}
return -1;
}
/**
* Mutiert eine zufällige Zahl in einer zufälligen Bedingung.
* Falls keine solche Zahl existiert, bleibt der Automat unverändert.
*
* SEMANTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob eine Bedingung mutiert wurde.
*/
public final boolean mutationBedZahl(final EndlicherAutomat ea) {
ArrayList<Transition> bedingungen = ea.getBedListe();
int zufallsIndex;
Transition zufallsBed;
String bedString;
int alt;
int neu;
String neuS;
int pos;
while (bedingungen.size() > 0) {
zufallsIndex = this.rand.nextInt(bedingungen.size());
zufallsBed = bedingungen.get(zufallsIndex);
bedString = zufallsBed.getCond().formatted();
pos = this.indexZahl(bedString);
if (pos >= 0) {
alt = Integer.parseInt(bedString.substring(pos - 1, pos + 2));
neu = alt + (this.rand.nextInt(2 * this.k)) - this.k;
if (neu < 1) {
neu = 1;
}
if (neu > 255) {
neu = 255;
}
neuS = bedString.substring(0, pos - 1)
+ StaticMethods.normZahl(neu)
+ bedString.substring(pos + 2);
zufallsBed.setBedingung(neuS);
return true;
}
bedingungen.remove(zufallsIndex);
}
return false;
}
/**
* Mutiert eine zufällige Sensorvariable in einer zufälligen Bedingung.
* Falls keine solche Sensorvariable existiert, bleibt der Automat
* unverändert.
*
* SEMANTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob eine Bedingung mutiert wurde.
*/
public final boolean mutationBedSensVar(final EndlicherAutomat ea) {
ArrayList<Transition> bedingungen = ea.getBedListe();
int zufallsIndex;
Transition zufallsBed;
String bedString;
int neu;
String neuS;
int pos;
while (bedingungen.size() > 0) {
zufallsIndex = this.rand.nextInt(bedingungen.size());
zufallsBed = bedingungen.get(zufallsIndex);
bedString = zufallsBed.getCond().formatted();
pos = this.indexSensVar(bedString);
if (pos >= 0) {
neu = StaticMethods.glVertZwischen(
1,
this.numAgentSensors ,
this.rand);
neuS = bedString.substring(0, pos - 1)
+ StaticMethods.normZahl(neu)
+ bedString.substring(pos + 2);
zufallsBed.setBedingung(neuS);
return true;
}
bedingungen.remove(zufallsIndex);
}
return false;
}
/**
* Mutiert Parameter und evtl. Befehl eines zufälligen Zustands, falls
* mindestens ein Zustand im Automaten existiert.
*
* SEMANTISCH
*
* @param ea Der zu mutierende Automat.
* @return Ob ein Zustand mutiert wurde.
*/
public final boolean mutationZustand(final EndlicherAutomat ea) {
ArrayList<Integer> knListe = ea.getKnList();
Knoten zufallsKnoten1;
int veraenderung;
int neuParam;
int altParam;
int neuBefehl;
int zufallsIndex;
if (knListe.size() == 0) {
return false;
} else {
zufallsIndex = this.rand.nextInt(knListe.size());
zufallsKnoten1 = ea.holeKnoten(knListe.get(zufallsIndex));
veraenderung = this.rand.nextInt(2 * this.k) - this.k;
altParam = zufallsKnoten1.getInfo().getParam();
if (veraenderung + altParam > 0) {
neuParam = altParam + veraenderung;
neuBefehl = zufallsKnoten1.getInfo().getAktion();
} else if (veraenderung + altParam < 0) {
neuParam = (veraenderung + altParam) * -1;
neuBefehl = StaticMethods.glVertZwischen(
1,
this.numAgentActuators,
this.rand);
} else { // veraenderung + altparam == 0
neuParam = 1;
neuBefehl = zufallsKnoten1.getInfo().getAktion();
}
zufallsKnoten1.getInfo().setAkt(neuBefehl);
zufallsKnoten1.getInfo().setPar(neuParam);
return true;
}
}
/**
* Die toString-Methode.
*
* @return String.
*/
@Override
public String toString() {
return "Mutationsart1";
}
/**
* @return Der Zufallsgenerator.
*/
public Random getRand() {
return this.rand;
}
/**
* Mutiert den aktiven Verhaltensautomaten des übergebenen Roboters.
* ACHTUNG: BISHER NUR VERHALTENSAUTOMAT!
*
* @param rob Der zu mutierende Roboter.
*
* @return Ob der Automat mutiert wurde.
*/
@Override
public final boolean mutiere(final MARBBrain<?> rob) {
Long[] intObj = new Long[11];
ArrayList<Long> vert = new ArrayList<Long>(11);
boolean b;
for (int i = 0; i < intObj.length; i++) {
intObj[i] = new Long(i);
}
vert.add(new Long(10)); // 0 : mutationBedA
vert.add(new Long(4)); // 1 : mutationBedBeinfacher
vert.add(new Long(7)); // 2 : mutationFalseKanteRem
vert.add(new Long(3)); // 3 : mutationZustandRem1
vert.add(new Long(3)); // 4 : mutationZustandRem2
vert.add(new Long(1)); // 5 : mutationZustand
vert.add(new Long(3)); // 6 : mutationBedZahl
vert.add(new Long(7)); // 7 : mutationFalseKanteEin
vert.add(new Long(4)); // 8 : mutationZustandEin
vert.add(new Long(6)); // 9 : mutationBedkomplexer
vert.add(new Long(1)); // 10: mutationBedSensVar
Long rnd = (Long) MiscMath.randVerteilung(intObj,
vert,
this.rand);
int zufall = rnd.intValue();
// Mutiere Verhaltensautomaten.
switch(zufall) {
case 0:
b = this.mutationBedA(rob.getMarb());
break;
case 1:
b = this.mutationBedBeinfacher(rob.getMarb());
break;
case 2:
b = this.mutationFalseKanteRem(rob.getMarb());
break;
case 3:
b = this.mutationZustandRem1(rob.getMarb());
break;
case 4:
// b = this.mutationZustandRem2(rob.getMarb());
b = false;
break;
case 5:
b = this.mutationZustand(rob.getMarb());
break;
case 6:
b = this.mutationBedZahl(rob.getMarb());
break;
case 7:
b = this.mutationFalseKanteEin(rob.getMarb());
break;
case 8:
b = this.mutationZustandEin(rob.getMarb());
break;
case 9:
b = this.mutationBedkomplexer(rob.getMarb());
break;
case 10:
b = this.mutationBedSensVar(rob.getMarb());
break;
default:
b = false;
}
// Setze Code des Verhaltensautomaten.
// if (b) {
// rob.getMarb().erzeugeAusStdSequenz(seq);
// rob.setAktVCode(rob.getAktVAut().erzeugeSequenz());
// }
return b;
}
/**
* Eine Identifikation des Mutationsobjekts. Die ID muss (case-insensitive)
* eindeutig sein.
*
* @return Die ID.
*/
@Override
public String id() {
return "alteMut";
}
}