/*
* Datei: RobEinfach.java
* Autor(en): Lukas K�nig
* Java-Version: 6.0
* Erstellt: 13.03.2009
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/
package fmg.fmg8.umgebung2D;
import fmg.fmg8.earleyErkenner.EarleyErkenner;
import fmg.fmg8.endlAutomat.AutomatenNummer;
import fmg.fmg8.endlAutomat.EndlicherAutomat;
import fmg.fmg8.endlAutomat.Transition;
import fmg.fmg8.endlAutomat.ZInfo;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.endlAutomat.conditions.ConditionNummer;
import fmg.fmg8.endlAutomat.conditions.mutation.CondMutVerfahren;
import fmg.fmg8.endlAutomat.fitness.FitnessVerfahren;
import fmg.fmg8.endlAutomat.script.ScriptInterpreter;
import fmg.fmg8.endlAutomat.translator.Translator;
import fmg.fmg8.graphVis.graph.Knoten;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.statistik.Parametersatz;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Observer;
import java.util.Random;
/**
* Beschreibt einen Roboter, der im Wesentlichen ein endlicher Automat mit
* einigen Zusatzeigenschaften ist. Insbesondere wird in dieser Klasse nicht
* auf die Besonderheit mutierbarer �bersetzer eingegangen. Wenn mutierbare
* �bersetzer (Translatoren) verwendet werden sollen, dann muss die abgeleitete
* Klasse <code>Roboter</code> verwendet werden.
*
* sensoren[17] speichert den Fitnesswert dieses Roboters (anzugeben in Klasse
* Konstanten).
*
* @author Lukas K�nig
*/
public class RobEinfach {
/**
* Die Versions-ID.
*/
private static final long serialVersionUID = -9000974806198171190L;
/**
* Die aktuelle Position des Roboters.
*/
private Vektor2D position;
/**
* Der Winkel der Blickrichtung (gemessen zu einem Nullwinkel, der in
* die Richtung (1, 0) zeigt).
*/
private double winkel;
/**
* Vektor zur Beschreibung der Blickrichtung.
*/
private Vektor2D blickrichtung;
/**
* Die Ausdehnung als Rechteck in X- und Y-Richtung.
*/
private Vektor2D ausd;
/**
* Die Steuerungsautomaten des Roboters.
*/
private EndlicherAutomat[] vAut;
/**
* Die zu den Steuerungsautomaten geh�renden Fitnessfunktionen.
*/
private FitnessVerfahren[] fitVs;
/**
* Die Fitnesswerte der aktuellen Automaten.
*/
private int[] fits;
/**
* Die Bedingungen, die festlegen, welcher Automat aktiviert wird.
*/
private Condition[] conds;
/**
* Die aktuellen Zustand, in denen sich die endlichen Automaten des
* Roboters befinden.
*/
private Knoten[] aktZustand;
/**
* Die zur bisher besten Fitness geh�renden Automaten.
*/
private String[] besteAut;
/**
* Die bisher besten Fitnesswerte.
*/
private int[] besteFit;
/**
* Vektor der Aktivzeiten in Zyklen der Automaten des Roboters.
*/
private long[] aktivZyklen;
/**
* Der aktuell aktive Automat.
*/
private int aktAut;
/**
* Die Sensoren. Wenn ein Sensor den Wert -1 enth�lt, wird er als
* "nicht aktuell" betrachtet und ein neues Ausrechnen beim n�chsten
* Abfragen veranlasst.
*/
private int[] sensoren;
/**
* Die Umgebung, auf der der Roboter steht.
*/
private Umgebung eltern;
/**
* Speichert die Exkpunkte des Roboters.
*/
private Vektor2D[] eckPunkte;
/**
* Speichert, ob die Eckpunkte aktuell berechnet sind.
*/
private boolean eckPunkteAktuell;
/**
* Die Winkel der Sensoren, gemessen am aktuellen Blickwinkel.
*/
private double[] absSensorWink;
/**
* Die Winkel der Sensoren, gemessen am aktuellen Nullwinkel.
*/
private double[] relSensorWink;
/**
* Die �ffnungswinkel der Sensoren.
*/
private double[] sensOeffn;
/**
* Die Anzahl der Sensoren.
*/
private int sensAnzIR;
/**
* Speichert alle zu pr�fenden Sensorrichtungen (d.h. evtl. n / Sensor).
*
*/
private Vektor2D[][] alleAbsSensRicht;
/**
* Die Bewegung, die aktuell ausgef�hrt wird (parallel zur Weiterausf�hrung
* des endlichen Automaten).
*/
private int aktBewegung;
/**
* Der Parameter f�r die aktuelle Bewegung, das ist die Anzahl der noch
* durchzuf�hrenden Bewegungsschritte.
*/
private int aktBewegungPar;
/**
* Speichert alle aktuell abzuarbeitenden Befehle, die KEINE
* Bewegungsbefehle sind.
*/
private ArrayList<Integer> aktBefehle;
/**
* Die Parameter f�r die aktuell abzuarbeitenden Befehle.
*/
private ArrayList<Double> aktBefehlePar;
/**
* Die Startzeit des Timers.
*/
private Date timerStart;
/**
* Das Mutationsverfahren f�r diesen Roboter.
*/
private CondMutVerfahren mut;
/**
* Die Zyklen zwischen zwei Mutationen.
*/
private long mutZyklen;
/**
* Die aktuelle Dauer des Experiments in Zyklen.
*/
private long expAktZyklen;
/**
* Die Zyklen zwischen zwei Fitnessberechnungen.
*/
private long[] fitAktZyklen;
/**
* Die Zyklen zwischen zwei FitnessRedberechnungen.
*/
private long[] fitRedAktZyklen;
/**
* Die Zyklen seit der letzten Mutation.
*/
private long mutAktZyklen;
/**
* Die Zyklen seit der letzten Bedingungsmutation.
*/
private long condMutAktZyklen;
/**
* Die Zyklen seit der letzten Fitnessberechnung.
*/
private long fitZyklen;
/**
* Die Zyklen seit der letzten FitnessRedberechnung.
*/
private long fitRedZyklen;
/**
* Der Wert, durch den bei der Reduktion dividiert wird.
*/
private double fitRedWert;
/**
* Der zuletzt ausgef�hrte Befehl.
*/
private int lastBf;
/**
* Der Earley-Erkenner.
*/
private EarleyErkenner earlErk;
/**
* Identifizierungsnummer des Roboters (-1 hei�t ung�ltig).
*/
private int id;
/**
* Der Zufallsgenerator.
*/
private Random rand;
/**
* Die Parameter.
*/
private Parametersatz pars;
/**
* Die zuletzt ausgef�hrten Befehle.
*/
private ArrayList<Integer> befehle;
/**
* Die aktuelle Zyklenzahl seit dem letzten Zur�cksetzen auf den Memory-
* Wert.
*/
private long aktMemZyk;
/**
* Die Koordinaten bei der letzten Fitnessberechnung.
* (Wird nur von au�en gesetzt!)
*/
private Vektor2D letztKoord;
/**
* Ob der Roboter selektiert ist.
*/
private boolean selektiert;
/**
* Ein Observer der Klasse.
*/
private Observer observer;
/**
* Ab welcher Sensornummer nicht mehr berechnet werden muss.
*/
public static final int NICHT_BER_AB = 7;
/**
* Die Anzahl der bisher registrierten Unf�lle.
*/
private int anzUnfaelle = 0;
/**
* Der Scriptinterpreter.
*/
private ScriptInterpreter scriptInt;
/**
* Ob das Verhalten bei der n�chsten Mutation mutiert werden soll.
*/
private boolean mutV;
/**
* Initialisiert einen Roboter mit Werten von einem �bergebenen Roboter.
* Dabei wird NICHT der Automat des Roboters kopiert und die ID des neuen
* Roboters wird auf einen UNG�LTIGEN Wert gesetzt.
*
* @param andererRob Der Roboter, dessen Werte �bernommen werden sollen.
* @param params Parametersatz.
* @param zufall Der Zufallsgenerator.
* @param sel Ob der Roboter selektiert ist.
*/
public RobEinfach(
final RobEinfach andererRob,
final Parametersatz params,
final Random zufall,
final boolean sel) {
this(andererRob.getPosition().x,
andererRob.getPosition().y,
andererRob.getWinkel(),
andererRob.getAusd().x,
andererRob.getAusd().y,
andererRob.eltern,
andererRob.earlErk,
andererRob.mut,
-1,
params,
zufall,
sel,
(VisMantel) andererRob.observer,
andererRob.vAuts()[0].getScriptInterpreter(),
andererRob.vAuts().length);
this.expAktZyklen = andererRob.expAktZyklen;
}
/**
* Einfacher Konstruktor, der keine Anfangsposition, evolution�re
* Operatoren, Earley-Erkenner u.�. erfordert. Als TRANSLATOR wird der
* Standardtranslator verwendet.
*
* @param automaten Die Automaten des Roboters.
* @param cond Die Bedingungen.
* @param elt Die Elternumgebung.
* @param ident Identifikationsnummer.
* @param params Parameter.
* @param zufall Zufallsgenerator.
* @param sel Ob der Roboter selektiert ist.
* @param obs Ein Observer f�r den Roboter.
* @param scriInt Der ScriptInterpreter.
*/
public RobEinfach(final String[] automaten,
final Condition[] cond,
final Umgebung elt,
final int ident,
final Parametersatz params,
final Random zufall,
final boolean sel,
final VisMantel obs,
final ScriptInterpreter scriInt) {
this(0,
0,
0,
Konstanten.ROB_AUSDEHNUNG_X,
Konstanten.ROB_AUSDEHNUNG_Y,
elt,
null,
null,
ident,
params,
zufall,
sel,
obs,
scriInt,
automaten.length);
this.erzeugeAusSequenzen(
automaten,
cond,
null,
false);
}
/**
* Initialisiert den Roboter.
*
* @param x X-Koordinate der Anfangsposition.
* @param y Y-Koordinate der Anfangsposition.
* @param wink Anfangswinkel der Blickrichtung in Grad.
* @param xAusd X-Ausdehnung.
* @param yAusd Y-Ausdehnung.
* @param elt Die Elternumgebung des Roboters.
* @param earl Der Earley-Erkenner f�r die Sequenz-Grammatik.
* @param mutation Das Mutationsverfahren f�r diesen Roboter.
* @param ident Die Identifikationsnummer des Roboters.
* @param params Die Parameter.
* @param zufall Der Zufallsgenerator.
* @param sel Ob der Roboter selektiert ist.
* @param obs Ein Observer der Klasse.
* @param scriInt Der ScriptInterpreter.
* @param autAnzahl Die Anzahl der Automaten, mit denen der Roboter
* ausgestattet sein soll.
*/
public RobEinfach(
final double x,
final double y,
final double wink,
final double xAusd,
final double yAusd,
final Umgebung elt,
final EarleyErkenner earl,
final CondMutVerfahren mutation,
final int ident,
final Parametersatz params,
final Random zufall,
final boolean sel,
final VisMantel obs,
final ScriptInterpreter scriInt,
final int autAnzahl) {
this.pars = params;
double verzerr = this.pars.getVerzerr().doubleValue();
this.observer = obs;
this.earlErk = earl;
this.scriptInt = scriInt;
this.initAuts(autAnzahl);
if (autAnzahl == 0) {
SonstMeth.log(SonstMeth.LOG_ERROR,
"Keine Startautomaten fuer Roboter angegeben.",
params);
}
this.selektiert = sel;
this.aktMemZyk = 0;
this.befehle = new ArrayList<Integer>();
this.id = ident;
this.rand = zufall;
double alpha = wink * Math.PI / 180;
this.timerStart = null;
this.aktBefehle = new ArrayList<Integer>();
this.aktBefehlePar = new ArrayList<Double>();
this.aktBewegung = 0;
this.aktBewegungPar = 0;
this.sensoren = new int[256];
this.position = new Vektor2D(x, y);
this.ausd = new Vektor2D(xAusd, yAusd);
this.blickrichtung = new Vektor2D(Math.cos(alpha) * verzerr,
Math.sin(alpha) * verzerr);
this.winkel = this.gultWinkel(wink);
this.eltern = elt;
this.eckPunkte = new Vektor2D[4];
this.setEckpVeraendert();
this.sensAnzIR = Konstanten.SENS_RICHT.length;
this.absSensorWink = new double[this.sensAnzIR];
this.sensOeffn = Konstanten.SENS_OEFFN;
this.relSensorWink = new double[this.sensAnzIR];
this.alleAbsSensRicht = new Vektor2D[Konstanten.ABSTUFUNGEN]
[this.sensAnzIR];
for (int i = 0; i < this.sensAnzIR; i++) {
this.relSensorWink[i] = Konstanten.SENS_RICHT[i];
}
this.setzeSensorRicht();
this.resetFitness();
this.mut = mutation;
if (params != null) {
this.fitZyklen = params.getFitZyklen().longValue();
this.mutZyklen = params.getMutZyklen().longValue();
this.fitRedZyklen = params.getFitRedZyklen().longValue();
this.fitRedWert = params.getFitRedWert().doubleValue();
}
this.mutAktZyklen = 0;
this.condMutAktZyklen = 0;
this.expAktZyklen = 0;
this.mutV = false;
this.lastBf = 0;
}
/**
* Gibt zur�ck, ob der aktuelle Roboter selektiert ist.
*
* @return Ob selektiert.
*/
public boolean isSelektiert() {
return this.selektiert;
}
/**
* Erzeugt einen g�ltigen Winkel zwischen 0�(=) und 360�(<).
*
* @param w Der zu normalisierende Winkel.
*
* @return Der normalisierte Winkel.
*/
private double gultWinkel(final double w) {
double w2 = w;
while (w2 >= 360) {
w2 = w2 - 360;
}
while (w2 < 0) {
w2 = w2 + 360;
}
return w2;
}
/**
* Setzt die Sensorrichtungen in Abh�ngigkeit des aktuellen Blickwinkels.
*/
private void setzeSensorRicht() {
double alpha;
double aLPHA;
double sum;
for (int i = 0; i < this.sensAnzIR; i++) {
this.absSensorWink[i] = this.gultWinkel(this.winkel
+ this.relSensorWink[i]);
aLPHA = this.absSensorWink[i] - this.sensOeffn[i] / 2;
sum = this.sensOeffn[i] / ((double) Konstanten.ABSTUFUNGEN - 1);
for (int j = 0; j < Konstanten.ABSTUFUNGEN; j++) {
alpha = Math.PI * aLPHA / 180;
this.alleAbsSensRicht[j][i] = new Vektor2D(Math.cos(alpha),
Math.sin(alpha));
aLPHA = aLPHA + sum;
}
}
}
/**
* @return Der zu setzende String f�r diesen Roboter.
*/
private String setzString() {
if (this.pars.getAnzModus() == 1) {
if (this.isSelektiert()) {
return this.getFitString();
}
} else if (this.pars.getAnzModus() == 2) {
return this.getFitString();
}
return "";
}
/**
* Setzt die Position des Roboters.
*
* @param x X-Koordinate.
* @param y Y-Koordinate.
* @param gegKollIgnore Ob die Kollision mit einem Gegenstand ignoriert
* werden soll (f�hrt NICHT zu Verschieben des
* Gegenstands).
*
* @return Ob der Roboter gesetzt werden konnte.
*/
public boolean setPos(final double x,
final double y,
final boolean gegKollIgnore) {
double xOld = this.position.x;
double yOld = this.position.y;
byte farbe;
if (this.isSelektiert()) {
farbe = Konstanten.FARBE_SEL;
} else {
farbe = Konstanten.FARBE_ROB;
}
this.position.setzeKoord(x, y);
this.setEckpVeraendert();
if (this.eltern.setzeRobWennMoegl((Roboter) this,
gegKollIgnore,
farbe,
this.setzString())) {
return true;
} else {
this.position.setzeKoord(xOld, yOld);
this.setEckpVeraendert();
return false;
}
}
/**
* Setzt die Blickrichtung auf einen bestimmten Winkel in Grad. Dabei wird
* auch die Schrittl�nge durch die _L�nge_ des Blickrichtungs-Vektors
* gesetzt (automatisch). Der Winkel wird relativ zu einem Nullwinkel
* gemessen.
*
* @param alph Der Winkel der Blickrichtung in Grad.
*
* @return Ob der Blickwinkel ge�ndert werden konnte.
*/
public boolean setBlck(final double alph) {
double alpha = this.gultWinkel(alph) * Math.PI / 180;
double verzerr = this.pars.getVerzerr().doubleValue();
double winkOld = this.winkel;
double bxOld = this.blickrichtung.x;
double byOld = this.blickrichtung.y;
byte farbe;
if (this.isSelektiert()) {
farbe = Konstanten.FARBE_SEL;
} else {
farbe = Konstanten.FARBE_ROB;
}
this.winkel = this.gultWinkel(alph);
this.blickrichtung.setzeKoord(Math.cos(alpha) * verzerr,
Math.sin(alpha) * verzerr);
this.setEckpVeraendert();
if (this.eltern.setzeRobWennMoegl((Roboter) this,
true,
farbe,
this.setzString())) {
this.setzeSensorRicht();
return true;
} else {
this.blickrichtung.setzeKoord(bxOld, byOld);
this.winkel = winkOld;
this.setEckpVeraendert();
return false;
}
}
/**
* Setzt einen Roboter unbedingt in das Feld. Kollisionen werden nicht
* betrachtet.
*
* @param x X-Koordinate der Position.
* @param y Y-Koordinate der Position.
* @param alpha Winkel der Blickrichtung.
*/
public void setRobUnbed(final double x,
final double y,
final double alpha) {
byte farbeRob;
if (this.isSelektiert()) {
farbeRob = Konstanten.FARBE_SEL;
} else {
farbeRob = Konstanten.FARBE_ROB;
}
this.eltern.setzeRob(this.getEckPunkte(),
Konstanten.FARBE_HGND,
true,
false,
true);
this.setPosition(new Vektor2D(x, y));
this.setBlickRicht(alpha);
this.eltern.setzeRob(this.getEckPunkte(),
farbeRob,
true,
false,
true);
}
/**
* @return Returns the blickrichtung.
*/
public Vektor2D getBlickrichtung() {
return this.blickrichtung;
}
/**
* @return Returns the position.
*/
public Vektor2D getPosition() {
return this.position;
}
/**
* @return Returns the winkel.
*/
public double getWinkel() {
return this.winkel;
}
/**
* Erh�ht den aktuellen Parameter um den angegebenen Wert und normiert
* Werte >255 auf 255 und Werte <0 auf 0.
*
* @param wert Wert, um den erh�ht wird (dieser kann auch negativ sein).
*/
private void erhoeheAktPar(final int wert) {
if (this.aktBewegungPar + wert > 255) {
this.aktBewegungPar = 255;
} else if (this.aktBewegungPar + wert <= 0) {
this.aktBewegungPar = 0;
} else {
this.aktBewegungPar = this.aktBewegungPar + wert;
}
}
/**
* Erh�ht den Parameter des angegebenen Befehls in der Warteschlange um
* den angegebenen Wert und normiert Werte >255 auf 255 und Werte <0 auf 0.
*
* @param bef Befehlsnummer in der Liste abzuarbeitender Befehle, deren
* Parameter erh�ht werden soll.
* @param wert Wert, um den erh�ht wird (dieser kann auch negativ sein).
*/
private void erhoeheBefPar(final int bef,
final double wert) {
if (((Double) this.aktBefehlePar.get(bef)).doubleValue()
+ wert > 255) {
this.aktBefehlePar.set(bef, new Double(255));
} else if (((Double) this.aktBefehlePar.get(bef)).doubleValue()
+ wert <= 0) {
this.aktBefehlePar.set(bef, new Double(0));
} else {
this.aktBefehlePar.set(bef,
new Double(((Double) this.aktBefehlePar.get(bef)).doubleValue()
+ wert));
}
}
/**
* Setzt einen neue aktuelle Bewegung und den Parameter.
*
* @param akt Der neue aktuelle Befehl.
* @param par Der Parameter f�r die Bewegung.
*/
private void setzeAktBewegung(final int akt,
final int par) {
this.aktBewegung = akt;
this.aktBewegungPar = par;
}
/**
* Simuliert einen Unfall, bei dem der Roboter um zuf�llige Grad gedreht
* und um einige Pixel verschoben wird. Ein Unfall sollte bei einer
* Kollision eingeleitet werden. Der Unfall findet nur statt, falls
* keine Kollision NACH dem Unfall passieren w�rde.
*
* @param maxWinkel Der Winkel, um den der Roboter maximal gedreht wird.
* @return Ob der Unfall stattgefunden hat.
*/
private boolean unfallSimulation(final double maxWinkel) {
boolean erfolgreich = false;
double xVersch = 0;
double yVersch = 0;
int modus;
ArrayList<Integer> modi = new ArrayList<Integer>(6);
modi.add(new Integer(0));
modi.add(new Integer(1));
modi.add(new Integer(2));
modi.add(new Integer(3));
modi.add(new Integer(4));
modi.add(new Integer(5));
this.anzUnfaelle++;
GlobaleVariablen.collCount++;
while (!erfolgreich && modi.size() > 0) {
modus = this.rand.nextInt(modi.size());
switch (((Integer) modi.get(modus)).intValue()) {
case 0:
xVersch = 1;
yVersch = 0;
break;
case 1:
xVersch = 0;
yVersch = 1;
break;
case 2:
xVersch = 1;
yVersch = 1;
break;
case 3:
xVersch = -1;
yVersch = 0;
break;
case 4:
xVersch = 0;
yVersch = -1;
break;
case 5:
xVersch = -1;
yVersch = -1;
break;
default:
break;
}
if (this.setPos(this.position.x + xVersch * Konstanten.SCHRITTW,
this.position.y + yVersch * Konstanten.SCHRITTW,
true)) {
erfolgreich = true;
}
modi.remove(modus);
}
if (this.setBlck(this.getWinkel()
- (this.rand.nextDouble() * maxWinkel))) {
erfolgreich = true;
}
return erfolgreich;
}
/**
* F�hrt eine einzelne Aktion aus.
*
* @param akt Die Nummer der Aktion (0..255).
* @param par Der Parameter f�r die Aktion (0..255).
* @param bew Gibt an, ob es sich um einen Bewegungsbefehl handelt.
*
* @return Ob die Aktion ausgef�hrt werden konnte.
*/
public boolean aktion(final int akt,
final int par,
final boolean bew) {
boolean b = true;
int bewegungsWeite = 0;
double befehlsKonstante = 0;
final String befehl = Konstanten.BEF[akt];
if (!this.eltern.getAkteure().contains(this)) {
throw new RuntimeException("Roboter ist nicht auf Feld.");
}
if (bew && this.aktBewegungPar <= 0) {
return false;
}
if (befehl.equals("Mov")) {
if (this.setPos(this.position.x
+ this.blickrichtung.x
* Konstanten.SCHRITTW,
this.position.y
+ this.blickrichtung.y
* Konstanten.SCHRITTW,
false)) {
b = true;
bewegungsWeite = (int) Konstanten.SCHRITTW;
} else {
b = unfallSimulation(180);
}
} else if (befehl.equals("TnR")) {
if (this.setBlck(this.winkel + Konstanten.WINKEL_SCHRITT)) {
b = true;
bewegungsWeite = (int) Konstanten.WINKEL_SCHRITT;
} else {
b = unfallSimulation(45);
}
} else if (befehl.equals("TnL")) {
if (this.setBlck(this.winkel - Konstanten.WINKEL_SCHRITT)) {
bewegungsWeite = (int) Konstanten.WINKEL_SCHRITT;
} else {
b = unfallSimulation(45);
}
} else if (befehl.equals("Tmr")) {
if (this.timerStart == null) {
this.timerStart = new Date();
} else {
Date aktZeit = new Date();
befehlsKonstante = ((double) (aktZeit.getTime()
- this.timerStart.getTime())) / 1000;
this.sensoren[7] = (int) (((Double) (this.aktBefehlePar.get(
this.aktBefehle.indexOf(new Integer(akt))))).doubleValue()
- befehlsKonstante) + 1;
this.timerStart = new Date();
}
}
if (bew) {
this.erhoeheAktPar(-bewegungsWeite);
} else {
this.erhoeheBefPar(this.aktBefehle.indexOf(new Integer(akt)),
-befehlsKonstante);
}
return b;
}
/**
* F�hrt alle anstehenden Aktionen und die �bergebene neue Aktion aus.
*
* @param akt Die Nummer der neuen Aktion (0..255).
* @param par Der Parameter f�r die neue Aktion (0..255).
*
* @return Ob alle anstehenden Aktionen ausgef�hrt werden konnten.
*/
private boolean gesamtAktion(final int akt,
final int par) {
boolean b;
Iterator<Integer> itB;
Iterator<Double> itP;
byte aktB;
byte aktP;
if (fmg.fmg8.sonstiges.SonstMeth.enthaelt(
Konstanten.BEWEGUNGSBEFEHLE, akt)) {
if (this.aktBewegung == akt) {
this.erhoeheAktPar(par);
} else {
this.setzeAktBewegung(akt, par);
}
} else {
if (this.aktBefehle.contains(new Integer(akt))) {
this.erhoeheBefPar(this.aktBefehle.indexOf(new Integer(akt)),
par);
} else {
this.aktBefehle.add(new Integer(akt));
this.aktBefehlePar.add(new Double(par));
}
}
// F�hre aktuelle Bewegung aus:
b = this.aktion(this.aktBewegung, this.aktBewegungPar, true);
// F�hre alle sonst anstehenden Aktionen aus:
itB = this.aktBefehle.iterator();
itP = this.aktBefehlePar.iterator();
while (itB.hasNext() && itP.hasNext()) {
aktB = ((Integer) itB.next()).byteValue();
aktP = (byte) (int) ((Double) itP.next()).doubleValue();
b = b & this.aktion(aktB, aktP, false);
}
return b;
}
/**
* Berechnet die Eckpunkte des Roboters.
*/
private void berechneEckpunkte() {
Vektor2D e1 = new Vektor2D(this.position.x, this.position.y);
Vektor2D e2 = new Vektor2D(this.position.x, this.position.y);
Vektor2D e3 = new Vektor2D(this.position.x, this.position.y);
Vektor2D e4 = new Vektor2D(this.position.x, this.position.y);
Vektor2D b = this.blickrichtung;
Vektor2D bn = new Vektor2D(-this.blickrichtung.y, this.blickrichtung.x);
e1.x = e1.x + (b.x * this.ausd.x + bn.x * this.ausd.y) / 2;
e1.y = e1.y + (b.y * this.ausd.x + bn.y * this.ausd.y) / 2;
e2.x = e2.x + (b.x * this.ausd.x - bn.x * this.ausd.y) / 2;
e2.y = e2.y + (b.y * this.ausd.x - bn.y * this.ausd.y) / 2;
e3.x = e3.x + (-b.x * this.ausd.x + bn.x * this.ausd.y) / 2;
e3.y = e3.y + (-b.y * this.ausd.x + bn.y * this.ausd.y) / 2;
e4.x = e4.x + (-b.x * this.ausd.x - bn.x * this.ausd.y) / 2;
e4.y = e4.y + (-b.y * this.ausd.x - bn.y * this.ausd.y) / 2;
this.eckPunkte[0] = e1;
this.eckPunkte[1] = e2;
this.eckPunkte[2] = e3;
this.eckPunkte[3] = e4;
this.eckPunkteAktuell = true;
}
/**
* @return Returns the eckPunkte.
*/
public Vektor2D[] getEckPunkte() {
if (!this.eckPunkteAktuell) {
this.berechneEckpunkte();
}
return this.eckPunkte;
}
/**
* Ob die Methode naechsterZustand() initial aufgerufen wird.
*/
private boolean initial = true;
/**
* Geht in den n�chsten Zustand �ber.
*/
public void naechsterZustand() {
int aktion;
int parameter;
LinkedList<Transition> bedingungen;
Transition aktBed;
ZInfo zusatz;
int folgeZ = 0;
Iterator<Transition> it;
int i = 0;
while (i < this.conds.length) {
if (this.conds[i].evaluiere(this)) {
if (this.initial || i != this.aktAut) {
this.aktAut = i;
this.vAut[this.aktAut].setzeChanged();
this.vAut[this.aktAut].notifyObservers(
new Integer(this.aktAut));
this.initial = false;
}
break;
}
i++;
}
this.expAktZyklen++;
this.fitAktZyklen[this.aktAut]++;
this.fitRedAktZyklen[this.aktAut]++;
this.aktivZyklen[this.aktAut]++;
this.mutAktZyklen++;
this.aktMemZyk++;
this.condMutAktZyklen++;
if (this.fitRedAktZyklen[this.aktAut] > this.fitRedZyklen) {
this.setFitness(this.aktAut,
(int) ((double) this.getFitness()[this.aktAut]
/ this.fitRedWert));
this.fitRedAktZyklen[this.aktAut] = 0;
}
if (this.fitAktZyklen[this.aktAut] > this.fitZyklen) {
this.befehle.clear();
this.befehle.add(new Integer(this.lastBf));
this.setFitness(this.aktAut,
this.getFitness()[this.aktAut]
+ this.fitVs[this.aktAut].fitness(
(Roboter) this));
this.fitAktZyklen[this.aktAut] = 0;
}
if (this.pars.getEvol().booleanValue()) {
if (this.aktMemZyk > this.pars.getMemInt().longValue()) {
this.resetToBest();
}
if (this.mutAktZyklen > this.mutZyklen) {
this.mutV = true;
this.mutiere();
this.mutAktZyklen = 0;
this.mutV = false;
} else {
this.mutV = false;
}
if (this.condMutAktZyklen > this.pars.getCondMutZyk()) {
this.mutiereBeds();
this.condMutAktZyklen = 0;
}
}
if (this.aktZustand[this.aktAut] == null) {
this.aktZustand[this.aktAut]
= this.vAut[this.aktAut].holeStartzustand();
}
if (this.isSelektiert()) {
if (this.aktZustand[this.aktAut] != null) {
this.vAut[this.aktAut].setzeChanged();
this.vAut[this.aktAut].notifyObservers(
this.aktZustand[this.aktAut]);
}
}
if (this.aktZustand[this.aktAut] != null) {
zusatz = (ZInfo) this.aktZustand[this.aktAut].getInfo();
aktion = zusatz.getAktion();
parameter = zusatz.getParam();
this.gesamtAktion(aktion, parameter);
this.lastBf = aktion;
bedingungen = zusatz.getBeds();
it = bedingungen.iterator();
this.aktZustand[this.aktAut] = null;
while (it.hasNext() && folgeZ == 0) {
aktBed = (Transition) it.next();
if (aktBed.evaluiere(this)) {
folgeZ = aktBed.getFolgezustand();
this.aktZustand[this.aktAut]
= this.vAut[this.aktAut].holeKnoten(
new Integer(folgeZ));
}
}
} else {
this.lastBf = 0;
}
}
/**
* Gibt einen Sensorenwert als den zugeh�rigen im Elternfeld gemessenen
* Wert zur�ck. Au�erdem wird der betreffende Sensor im Array auf den
* entsprechenden Wert gesetzt.
*
* @param sensor Die Nummer des zu berechnenden Sensors.
*
* @return Der gemessene Sensorwert.
*/
public int getSensorWert(final int sensor) {
if (sensor < NICHT_BER_AB) {
if (this.sensoren[sensor] < 0) {
this.sensoren[sensor] = this.eltern.berSensWerte(
(Roboter) this, sensor);
}
}
return this.sensoren[sensor];
}
/**
* Achtung, diese Methode sollte nicht in jedem Zyklus aufgerufen werden,
* da sie zeitaufw�ndig sein kann.
*
* @return Alle Sensorwerte.
*/
public int[] getSensorWerte() {
for (int i = 0; i < 7; i++) {
this.getSensorWert(i);
}
return this.sensoren;
}
/**
* @return Returns the alleAbsSensRicht.
*/
public Vektor2D[][] getAlleAbsSensRicht() {
return this.alleAbsSensRicht;
}
/**
* @return Returns the sensOeffn.
*/
public double[] getSensOeffn() {
return this.sensOeffn;
}
/**
* Markiert die aktuellen Eckpunkte und berechneten Sensorwerte als
* ung�ltig.
*/
private void setEckpVeraendert() {
this.eckPunkteAktuell = false;
for (int i = 0; i < NICHT_BER_AB; i++) {
this.sensoren[i] = -1;
}
}
/**
* ACHTUNG! Diese Methode garantiert kein g�ltiges Platzieren des Roboters
* auf dem Feld. Sie ist nur dazu gedacht, den Roboter einmalig zu Beginn
* der Simulation zu verschieben. Es muss jedoch immer gepr�ft werden, ob
* die Verschiebung g�ltig war!
*
* @param pos The position to set.
*/
public void setPosition(final Vektor2D pos) {
this.setEckpVeraendert();
this.position = pos;
}
/**
* ACHTUNG! Diese Methode garantiert kein g�ltiges Platzieren des Roboters
* auf dem Feld. Sie ist nur dazu gedacht, den Roboter einmalig zu Beginn
* der Simulation zu verschieben. Es muss jedoch immer gepr�ft werden, ob
* die Verschiebung g�ltig war!
*
* @param beta Die Blickrichtung des Roboters.
*/
public void setBlickRicht(final double beta) {
double verzerr = this.pars.getVerzerr().doubleValue();
this.setEckpVeraendert();
this.winkel = beta;
double alpha = this.gultWinkel(beta) * Math.PI / 180;
this.winkel = this.gultWinkel(beta);
this.blickrichtung.setzeKoord(Math.cos(alpha) * verzerr,
Math.sin(alpha) * verzerr);
}
/**
* Setzt den aktuellen Zustand des aktiven Automaten auf den Startzustand
* zur�ck.
*/
private void zustZuruecksetzen() {
this.aktZustand[this.aktAut]
= this.vAut[this.aktAut].holeStartzustand();
}
/**
* Mutiert die zu <code>this</code> geh�renden Automaten.
*/
public void mutiere() {
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println("ACHTUNG");
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
this.mut.mutiere((Roboter) this);
if (this.isSelektiert()) {
this.vAut[this.aktAut].setzeChanged();
this.vAut[this.aktAut].notifyObservers(
new AutomatenNummer(
this.vAut[this.aktAut].erzeugeStringSeq(),
this.aktAut));
}
}
/**
* Mutiert die Bedingungen.
*/
public void mutiereBeds() {
for (int i = 0; i < this.conds.length; i++) {
this.conds[i] = this.mut.mutiere(this.conds[i]);
if (this.isSelektiert()) {
this.vAut[i].setzeChanged();
this.vAut[i].notifyObservers(
new ConditionNummer(this.conds[i].toString(),
i));
}
}
}
/**
* Setzt die Attribute des Objekts zur�ck.
*/
public void zuruecksetzen() {
this.expAktZyklen = 0;
for (int i = 0; i < this.vAut.length; i++) {
this.fitAktZyklen[i] = 0;
this.fitRedAktZyklen[i] = 0;
}
this.mutAktZyklen = 0;
this.condMutAktZyklen = 0;
this.lastBf = 0;
this.resetFitness();
this.timerStart = null;
this.zustZuruecksetzen();
}
/**
* Setzt die Fitness auf den Initialwert zur�ck.
*/
public void resetFitness() {
this.sensoren[Konstanten.FIT_SENS - 1] = 0;
this.setzeBesten();
}
/**
* @param autNum Die Nummer des Automaten.
* @param wert Der Wert, auf den gesetzt wird.
*/
public void setFitness(final int autNum, final int wert) {
this.fits[autNum] = wert;
this.setzeBesten();
}
/**
* Setzt die Fitnesswerte.
*
* @param werte Die werte.
*/
public void setFitness(final int[] werte) {
for (int i = 0; i < werte.length; i++) {
this.setFitness(i, werte[i]);
}
}
/**
* Setzt beste Fitness und Automaten aller Automaten neu, falls deren
* aktuelle Fitness den besten Wert aller Zeiten hat.
* Die Automaten werden als String-Sequenzen in der Standardformatierung
* gespeichert.
*/
private void setzeBesten() {
for (int i = 0; i < this.vAut.length; i++) {
if (this.getFitness()[i] > this.besteFit[i]) {
this.besteFit[i] = this.getFitness()[i];
this.besteAut[i] = this.vAut[i].erzeugeStringSeq();
}
}
}
/**
* Setzt die Automaten des Roboters auf die vormals besten Automaten zur�ck
* und setzt die Fitness auf 0.
*/
public void resetToBest() {
for (int i = 0; i < this.vAut.length; i++) {
if (this.getFitness()[i] <= 0
&& this.getFitness()[i] < this.besteFit[i]
&& this.besteFit[i] > 0) {
this.erzeugeAusSequenz(i, this.besteAut[i], null, null, false);
this.setFitness(i, 0);
SonstMeth.log(0,
"Automat "
+ i
+ " auf besten zur�ckgesetzt (Roboter "
+ this.getId()
+ ").",
this.pars);
} else if (this.getFitness()[i] > this.besteFit[i]) {
// Unkorrekter Fall.
this.setzeBesten();
SonstMeth.log(SonstMeth.LOG_ERROR,
"Beste Fitness war nicht korrekt "
+ "gesetzt (Methode: Roboter.resetToBest).",
this.pars);
}
}
this.aktMemZyk = 0;
}
/**
* @return Returns the eltern.
*/
public Umgebung getEltern() {
return this.eltern;
}
/**
* @return Returns the id.
*/
public int getId() {
return this.id;
}
/**
* Eine Textausgabe von <code>this</code>.
*
* @return Eine Textausgabe.
*/
public String toString() {
String s = "\n(";
s = s + this.id;
for (int i = 0; i < this.vAut.length; i++) {
s = s + " <" + this.getFitness()[i] + ": ";
s = s + this.conds[i] + ", ";
s = s + this.vAut[i].erzeugeSequenz() + "> ";
}
s = s + ")";
return s;
}
/**
* @return Returns the ausd.
*/
public Vektor2D getAusd() {
return this.ausd;
}
/**
* @return Returns the aktZustand.
*/
public Knoten getAktZustand() {
return this.aktZustand[this.aktAut];
}
/**
* @return Returns the befehle.
*/
public ArrayList<Integer> getBefehle() {
return this.befehle;
}
/**
* @return Returns the letztKoord.
*/
public Vektor2D getLetztKoord() {
return this.letztKoord;
}
/**
* @param letztK The letztKoord to set.
*/
public void setLetztKoord(final Vektor2D letztK) {
this.letztKoord = letztK;
}
/**
* Selektiert den aktiven Roboter.
*
* @param sel The selektiert to set.
*/
public void setSelektiert(final boolean sel) {
if (this.selektiert != sel) {
this.selektiert = sel;
this.vAut[this.aktAut].setzeChanged();
this.vAut[this.aktAut].notifyObservers(
new AutomatenNummer(this.vAut[this.aktAut].erzeugeStringSeq(),
this.aktAut));
}
}
/**
* F�hrt abschlie�ende Aktionen nach Abschluss einer Simulation aus.
*/
public void simBeendet() {
if (this.pars.getGraphisch().booleanValue()) {
for (int i = 0; i < this.vAut.length; i++) {
this.vAut[i].setzeChanged();
this.vAut[i].notifyObservers(
new AutomatenNummer(this.vAut[i].erzeugeStringSeq(),
i));
}
}
}
/**
* Initialisiert alle Variablen, die zu jedem Automaten separat Daten
* speichern (Arrays) oder von einer �nderung der Automatenanzahl
* betroffen sein k�nnen.
*
* @param anzAuts Die Anzahl der Automaten.
*/
protected void initAuts(final int anzAuts) {
this.aktAut = 0;
this.aktZustand = new Knoten[anzAuts];
this.besteAut = new String[anzAuts];
this.besteFit = new int[anzAuts];
this.conds = new Condition[anzAuts];
this.fits = new int[anzAuts];
this.aktivZyklen = new long[anzAuts];
this.fitVs = new FitnessVerfahren[anzAuts];
this.vAut = new EndlicherAutomat[anzAuts];
this.fitAktZyklen = new long[anzAuts];
this.fitRedAktZyklen = new long[anzAuts];
for (int i = 0; i < anzAuts; i++) {
this.aktivZyklen[i] = 0;
this.fitAktZyklen[i] = 0;
this.fitRedAktZyklen[i] = 0;
this.aktZustand[i] = null;
this.besteAut[i] = "";
this.besteFit[i] = 0;
if (i < Konstanten.AUT_CONDS.length) {
this.conds[i] = Konstanten.AUT_CONDS[i];
} else {
this.conds[i]
= SonstMeth.ausFormatBed(this.conds[i - 1].formatted());
}
this.fits[i] = 0;
if (i < Konstanten.FIT_VERFAHREN.length) {
this.fitVs[i] = Konstanten.FIT_VERFAHREN[i];
} else {
this.fitVs[i] = this.fitVs[i - 1];
}
this.vAut[i] = new EndlicherAutomat(this.earlErk, this.scriptInt);
if (this.pars.getGraphisch().booleanValue()
&& this.observer != null) {
this.vAut[i].addObserver(this.observer);
}
}
this.pars.setFitnessVerfahren(this.fitVs);
}
/**
* Erzeugt die Automaten neu aus den �bergebenen Sequenzen.
* Wenn die Anzahl neuer Automaten nicht der Anzahl der bereits
* vorhandenen entspricht, werden die Automaten neu initialisiert, d.h.
* die meisten laufenden Variablen und Z�hler werden zur�ckgesetzt (siehe
* dazu Methode <code>private void initAuts(final int anzAuts)</code>.
* <P>
* Die Bedingungen werden nur initialisiert, wenn sie nicht als
* <code>null</code> �bergeben wurden; anderenfalls werden die Bedingungen
* aus den Konstanten geladen.
*
* @param seq Die Sequenzen.
* @param cond Die Bedingungen (<code>null</code> erlaubt).
* @param trans Die Translatoren, die �bersetzung der jeweiligen
* Verhaltensautomaten vornehmen sollen.
* @param pruefen Ob die Sequenzen syntaktisch gepr�ft werden sollen.
*/
public void erzeugeAusSequenzen(final String[] seq,
final Condition[] cond,
final Translator[] trans,
final boolean pruefen) {
Translator[] trans2 = trans;
if (trans2 == null) {
trans2 = new Translator[seq.length];
}
if (seq != null) {
if (this.vAut.length != seq.length) {
this.initAuts(seq.length);
}
for (int i = 0; i < seq.length; i++) {
if (trans2[i] != null) {
trans2[i].setModus(SonstMeth.MODUS_VERHALTEN);
}
this.vAut[i].erzeugeAusSequenz(
seq[i],
trans2[i],
pruefen);
if (cond != null && i < cond.length && cond[i] != null) {
this.conds[i] = cond[i];
}
}
}
if (this.isSelektiert()) {
for (int i = 0; i < this.vAut.length; i++) {
this.vAut[i].setzeChanged();
this.vAut[i].notifyObservers(
new AutomatenNummer(this.vAut[i].erzeugeStringSeq(),
i));
}
}
}
/**
* Erzeugt einen Automaten des Roboters aus seiner Sequenz und einer
* Bedingung. Die Bedingung muss nicht angegeben werden. Wenn kein
* Translator angegeben wird, wird der Standardtranslator verwendet.
*
* @param autNum Die Automatennummer.
* @param seq Die Sequenz.
* @param cond Die Bedingung.
* @param trans Der Translator.
* @param pruefen Ob die Sequenz syntaktisch gepr�ft werden soll.
*/
public void erzeugeAusSequenz(final int autNum,
final String seq,
final Condition cond,
final Translator trans,
final boolean pruefen) {
this.vAut[autNum].erzeugeAusSequenz(
seq,
trans,
pruefen);
if (cond != null) {
this.conds[autNum] = cond;
if (this.isSelektiert()) {
this.vAut[autNum].setzeChanged();
this.vAut[autNum].notifyObservers(
new ConditionNummer(this.conds[autNum].toString(),
autNum));
}
}
if (this.isSelektiert()) {
this.vAut[autNum].setzeChanged();
this.vAut[autNum].notifyObservers(
new AutomatenNummer(this.vAut[autNum].erzeugeStringSeq(),
autNum));
}
}
/**
* @return Returns the observer.
*/
public Observer getObserver() {
return this.observer;
}
/**
* @return Returns the anzUnfaelle.
*/
public int getAnzUnfaelle() {
return this.anzUnfaelle;
}
/**
* Setzt die Anzahl der Unf�lle zur�ck.
*/
public void resetAnzUnf() {
this.anzUnfaelle = 0;
}
/**
* @return Returns the pars.
*/
public Parametersatz getPars() {
return this.pars;
}
/**
* Gibt die zu <code>this</code> geh�rende Automatensequenz zur�ck.
*
* @param autNum Die Nummer des Automaten.
*
* @return Die Automatensequenz.
*/
public synchronized LinkedList<Integer> erzeugeSequenz(final int autNum) {
return this.vAut[autNum].erzeugeSequenz();
}
/**
* Gibt eine Sequenz als String zur�ck.
*
* @param autNum Die Nummer des Automaten.
* @param l Die auszugebende Sequenz.
*
* @return String.
*/
public String ausgabe(final int autNum, final LinkedList<Integer> l) {
return this.vAut[autNum].ausgabe(l);
}
/**
* @return Returns the active vAutomat.
*/
public EndlicherAutomat getAktVAut() {
return this.vAut[this.aktAut];
}
/**
* Gibt alle Verhaltensautomaten zur�ck.
*
* @return Die V-Automaten.
*/
public EndlicherAutomat[] vAuts() {
return this.vAut;
}
/**
* Gibt zur�ck, ob der �bergebene Knoten der Startknoten des aktiven
* Automaten ist.
*
* @param k Der zu �berpf�fende Knoten.
* @param autNum Die Nummer des zu �berpr�fenden Automaten.
*
* @return Ob der Knoten der Startknoten ist.
*/
public boolean istStartZ(final int autNum, final Knoten k) {
return this.vAut[this.aktAut].istStartZ(k);
}
/**
* @return Ein Array der Stringsequenzen der Automaten des Roboters.
*/
public String[] erzeugeStrSeqs() {
String[] sequenzen = new String[this.vAut.length];
for (int i = 0; i < sequenzen.length; i++) {
sequenzen[i] = this.erzeugeStringSequenz(i);
}
return sequenzen;
}
/**
* @param autNum Die Nummer des Automaten, dessen Sequenz erzeugt werden
* soll.
*
* @return Die String-Sequenz des Automaten mit der angegebenen Nummer.
*/
public String erzeugeStringSequenz(final int autNum) {
return this.vAut[autNum].erzeugeStringSeq();
}
/**
* @return Summe aller Fitnesswerte dieses Roboters.
*/
public long getFitSum() {
long sum = 0;
for (int i = 0; i < this.vAut.length; i++) {
sum += this.fits[i];
}
return sum;
}
/**
* @return Returns the fits.
*/
public int[] getFitness() {
return this.fits;
}
/**
* @return Returns the conds.
*/
public Condition[] getConds() {
return this.conds;
}
/**
* L�dt den Roboter mit Verhaltensautomat, Translator und Bedingungen
* aus Dateien mit Namen, die dem Muster<BR>
* graphName.X<BR>
* entsprechen, wobei X \in {gra, tra, con} ist.
*
* @param graphName Der Name der Datei, aus der der Roboter geladen
* werden soll.
*/
public void ladeAuts(final String graphName) {
String pfad = this.pars.getStdPfad() + File.separator;
String[] sequenzen;
Condition[] bedingungen = null;
FileInputStream fs;
ObjectInputStream is;
String datRawName = pfad + graphName + ".";
Translator[] trans;
try {
fs = new FileInputStream(
datRawName + fmg.fmg8.graphVis.Konstanten.GRAPH_ENDUNG);
is = new ObjectInputStream(fs);
sequenzen = (String[]) is.readObject();
is.close();
} catch (final Exception e) {
throw new RuntimeException("Graph nicht geladen.");
}
try {
fs = new FileInputStream(datRawName
+ fmg.fmg8.graphVis.Konstanten.BED_ENDUNG);
is = new ObjectInputStream(fs);
bedingungen = (Condition[]) is.readObject();
is.close();
} catch (final Exception e) {
SonstMeth.log(SonstMeth.LOG_WARNING,
"Bedingung(en) nicht gefunden: "
+ datRawName
+ fmg.fmg8.graphVis.Konstanten.BED_ENDUNG,
this.pars);
}
// Erzeuge Verhaltensautomaten.
trans = new Translator[sequenzen.length];
for (int i = 0; i < trans.length; i++) {
trans[i] = fmg.fmg8.endlAutomat.translator.Konstanten.STD_TRANSL_BE;
}
this.erzeugeAusSequenzen(
sequenzen,
bedingungen,
trans,
false);
}
/**
* Speichert die Automaten des Roboters unter einem vorgegebenen Namen.
*
* @param graphName Der Dateiname, unter dem gespeichert werden soll.
*/
public void speichereAuts(final String graphName) {
String pfad = this.pars.getStdPfad() + File.separator;
FileOutputStream fs;
ObjectOutputStream os;
try {
// Speichere Automaten.
fs = new FileOutputStream(
pfad
+ graphName
+ "."
+ fmg.fmg8.graphVis.Konstanten.GRAPH_ENDUNG);
os = new ObjectOutputStream(fs);
os.writeObject(this.erzeugeStrSeqs());
os.close();
// Speichere Bedingungen.
fs = new FileOutputStream(
pfad
+ graphName
+ "."
+ fmg.fmg8.graphVis.Konstanten.BED_ENDUNG);
os = new ObjectOutputStream(fs);
os.writeObject(this.conds);
os.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Gibt die Fitnesswerte als String zur�ck.
*
* @return Die Fitnesswerte als String.
*/
public String getFitString() {
String s = "";
for (int i = 0; i < this.fits.length - 1; i++) {
s += this.fits[i] + ",";
}
s += fits[this.fits.length - 1];
return s;
}
/**
* @param conditions Die Bedingungen.
*/
public void setConds(final Condition[] conditions) {
this.conds = conditions;
}
/**
* Setzt die Bedingung mit der Nummer <code>autNum</code>.
*
* @param autNum Die Automatennummer.
* @param cond Die zu setzende Bedingung.
*/
public void setCond(final int autNum, final Condition cond) {
this.conds[autNum] = cond;
}
/**
* Setzt die Aktivzeit des Automaten zur�ck.
*
* @param autNum Die Nummer des zur�ckzusetzenden Automaten.
*/
public void resetAktivZyk(final int autNum) {
this.aktivZyklen[autNum] = 0;
}
/**
* @param autNum Der Automat, dessen Aktivzyklen zur�ckgegeben werden
* sollen.
*
* @return Die Aktivzyklen des Automaten.
*/
public long getAktivZyklen(final int autNum) {
return this.aktivZyklen[autNum];
}
/**
* @return Die Nummer des aktiven Automaten.
*/
public int getAktAutNum() {
return this.aktAut;
}
/**
* @return Die Verhaltensautomaten.
*/
public EndlicherAutomat[] getVAut() {
return this.vAut;
}
/**
* @return Ob das Verhalten mutiert werden soll.
*/
public boolean isMutV() {
return this.mutV;
}
/**
* @return Der Earleyerkenner von <code>this</code>.
*/
public EarleyErkenner getEarlErk() {
return this.earlErk;
}
/**
* @return Das Mutationsverfahren.
*/
public CondMutVerfahren getMut() {
return this.mut;
}
/**
* @return Die aktuelle Zyklenzahl des Gesamtexperiments.
*/
public long getExpAktZyklen() {
return this.expAktZyklen;
}
/**
* @param eaz Die neue Experimentzyklenzahl. Achtung: Nur zur
* Initialisierung setzen.
*/
public void setExpAktZyklen(final long eaz) {
this.expAktZyklen = eaz;
}
}