/*
* Datei: RobEA.java
* Autor(en): Lukas König
* Java-Version: 6.0
* Erstellt: 13.03.2009
*
* (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.simulation.spatial.sim2D.marbSimulation;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import eas.math.fundamentalAlgorithms.type2grammars.EarleyParser;
import eas.miscellaneous.StaticMethods;
import eas.plugins.standard.eaPlugin.StandardPluginForEA;
import eas.plugins.standard.eaPlugin.evolvableTranslators.EvolutionPluginCascadingTranslators;
import eas.plugins.standard.eaPlugin.evolvableTranslators.EvolutionPluginCompletelyEvolvable;
import eas.simulation.Wink;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.AutomatenNummer;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.EndlicherAutomat;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.GlobaleMARBVariablen;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.Transition;
import eas.simulation.spatial.sim2D.marbSimulation.endlAutomat.conditions.Condition;
import eas.simulation.spatial.sim2D.marbSimulation.mutation.CondMutVerfahren;
import eas.simulation.spatial.sim2D.marbSimulation.translator.ConstantsTranslator;
import eas.simulation.spatial.sim2D.marbSimulation.translator.Translator;
import eas.simulation.spatial.sim2D.marbSimulation.translator.script.ScriptInterpreter;
import eas.simulation.spatial.sim2D.marbSimulation.translator.versionOhneErgKante.ConstantsTranslatorWOC;
import eas.startSetup.ParCollection;
import eas.startSetup.marbBuilder.graph.Knoten;
/**
* @author Lukas König
*/
public class RobEA extends RobEAEinfach {
/**
*
*/
private static final long serialVersionUID = -5225374253212099717L;
/**
* Ob der Roboter bei der letzten Selektion verschoben wurde.
*/
private boolean versetzt;
/**
* Die aktuellen Translatoren.
*/
private Translator[] translatoren;
/**
* Die Codes der Translatoren (i.A. nicht in der Standardkodierung).
*/
private List<Integer>[] transCodes;
/**
* Ob der Translator bei der nächsten Mutation mutiert werden soll.
*/
private boolean mutT;
/**
* Das Mutationsverfahren für den Translator.
*/
private CondMutVerfahren mutArtTrans;
/**
* Die Zyklen zwischen zwei Translator-Mutationen.
*/
private long mutTransZyklen;
/**
* Die übersetzer für die entsprechenden besten Automaten in
* der Standardkodierung. Beide Listen (Verhalten und Translator) können
* immer nur denselben übersetzer zum Zeitpunkt des Speicherns gehabt
* haben, daher wird zwischen diesen nicht unterschieden.
*/
private LinkedList<Integer>[] besteStdTrans;
/**
* Die zur bisher besten Fitness gehörenden Automaten in der aktuellen
* Kodierung.
*/
private LinkedList<Integer>[] besteStdVerh;
/**
* Die zur bisher besten Fitness gehörenden Automaten in der aktuellen
* Kodierung.
*/
private LinkedList<Integer>[] besteVerhAut;
/**
* Die zur bisher besten Fitness gehörenden Automaten.
*/
private LinkedList<Integer>[] besteTransAut;
/**
* Die bisher besten Fitnesswerte.
*/
private int[] besteFit;
/**
* Eine einzelne leere Sequenz in einer Liste von Strings.
*/
private static final String[] LEERE_SEQUENZ = {""};
/**
* Minimalkonstruktor, der einen Roboter in einer bestehenden Umgebung
* erzeugt, der keine Automaten enthält und keine Observer erhalten kann.
* Der Roboter muss danach platziert werden
* (bspw. mit umg.hinzuRobotRand(r)).
*
* @param umg Die Umgebung des Roboters.
* @param id Die Identifikationsnummer.
* @param params Der Parametersatz.
* @param rand Der Zufallsgenerator.
*/
public RobEA(
final int id,
final EnvironmentEA umg,
final ParCollection params,
final Random rand) {
this(RobEA.LEERE_SEQUENZ, null, umg, id, params, rand,
false, null, null, StaticMethods.convertPluginsToStdPluginsForEA(params.getPlugins(), params));
}
/**
* Initialisierung über vorhandene Automatensequenzen. Die Position wird
* nicht gesetzt.
*
* @param seqs Die Automatensequenzen, über die initialisiert werden
* soll.
* @param cond Die zu den Automaten gehörenden Bedingungen.
* @param umgebung Die Umgebung des Roboters.
* @param ident Die Identifikationsnummer.
* @param params Der Parametersatz.
* @param zufall Der Zufallsgenerator.
* @param sel Ob der Roboter selektiert ist.
* @param obs Ein VisMantel-Observer.
* @param scriInt Ein Scriptinterpreter.
* @param trans Die Translatoren.
* @param plugins Die Plugins.
*/
public RobEA(
final String[] seqs,
final Condition[] cond,
final EnvironmentEA umgebung,
final int ident,
final ParCollection params,
final Random zufall,
final boolean sel,
final ScriptInterpreter scriInt,
final Translator[] trans,
final List<StandardPluginForEA> plugins) {
this(
0,
0,
0,
eas.simulation.ConstantsSimulation.ROB_AUSDEHNUNG_X,
eas.simulation.ConstantsSimulation.ROB_AUSDEHNUNG_Y,
umgebung,
null,
mutVerhFallsEvol(params, zufall),
mutTransFallsEvol(params, zufall),
ident,
params,
zufall,
sel,
scriInt,
seqs.length,
trans,
plugins);
this.erzeugeAusSequenzen(
seqs,
cond,
null,
false);
}
/**
* @return Die Verhaltensmutation, falls evolviert wird, <code>null</code>
* sonst.
*/
private static CondMutVerfahren mutVerhFallsEvol(
final ParCollection params,
final Random zufall) {
if (params.getPlugIDList().contains(new EvolutionPluginCompletelyEvolvable().id())) {
return OpsFactory.getKonstMut(params
.getParValueString(EvolutionPluginCompletelyEvolvable.MUT_ART_VE), zufall, params);
} else {
return null;
}
}
/**
* @return Die Verhaltensmutation, falls evolviert wird, <code>null</code>
* sonst.
*/
private static CondMutVerfahren mutTransFallsEvol(
final ParCollection params,
final Random zufall) {
if (params.getPlugIDList().contains(new EvolutionPluginCompletelyEvolvable().id())) {
return OpsFactory.getKonstMut(params
.getParValueString(EvolutionPluginCompletelyEvolvable.MUT_ART_TR), zufall, params);
} else {
return null;
}
}
/**
* Normaler Konstruktor.
*
* @param x X-Koordinate der Startposition des Roboters.
* @param y Y-Koordinate der Startposition des Roboters.
* @param wink Winkel der Startposition des Roboters.
* @param xAusd X-Wert der Startausdehnung (sollte i.A. auch sp�ter
* nicht verändert werden).
* @param yAusd Y-Wert der Startausdehnung (s.o.).
* @param umgebung Die Umgebung des Roboters.
* @param earl Der Earley-Erkenner.
* @param mutVerh Die Mutation für Verhaltensautomaten.
* @param mutTrans Die Mutation für Translatoren.
* @param ident Die Identifizierungsnummer.
* @param params Der Parametersatz.
* @param zufall Der Zufallsgenerator.
* @param sel Ob der Roboter zu Beginn selektiert ist.
* @param obs Ein VisMantel-Observer.
* @param scriInt Der Scriptinterpreter.
* @param autAnzahl Die Anzahl der Automaten, die der Roboter besitzt.
* @param trans Die Translatoren.
*/
@SuppressWarnings(value = { "unchecked" })
public RobEA(
final double x,
final double y,
final double wink,
final double xAusd,
final double yAusd,
final EnvironmentEA umgebung,
final EarleyParser earl,
final CondMutVerfahren mutVerh,
final CondMutVerfahren mutTrans,
final int ident,
final ParCollection params,
final Random zufall,
final boolean sel,
final ScriptInterpreter scriInt,
final int autAnzahl,
final Translator[] trans,
final List<StandardPluginForEA> plugins) {
super(x, y, wink, xAusd, yAusd, umgebung, earl, mutVerh, ident, params,
zufall, sel, scriInt, autAnzahl, plugins);
if (trans != null) {
this.translatoren = trans;
this.transCodes = new LinkedList[this.translatoren.length];
} else {
this.transCodes = new LinkedList[1];
}
if (params.getPlugIDList().contains(new EvolutionPluginCompletelyEvolvable().id())) {
this.mutArtTrans = mutTrans;
this.mutT = false;
this.mutTransZyklen = this.getPars().getParValueLong(
EvolutionPluginCompletelyEvolvable.MUT_TR_ZYK_ATT);
}
this.initAuts(autAnzahl);
}
/**
* 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.
*/
@Override
@SuppressWarnings(value = { "unchecked" })
protected void initAuts(final int anzAuts) {
super.initAuts(anzAuts);
this.besteFit = new int[anzAuts];
if (this.translatoren == null) {
this.translatoren = new Translator[anzAuts];
}
this.transCodes = new LinkedList[anzAuts];
this.besteStdTrans = new LinkedList[anzAuts];
this.besteTransAut = new LinkedList[anzAuts];
this.besteVerhAut = new LinkedList[anzAuts];
this.besteStdVerh = new LinkedList[anzAuts];
for (int i = 0; i < anzAuts; i++) {
this.besteFit[i] = 0;
this.besteStdTrans[i] = null;
this.besteTransAut[i] = null;
this.besteVerhAut[i] = null;
this.besteStdVerh[i] = null;
if (this.translatoren[i] == null) {
String trStr;
if (super.getPars().getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
trStr = eas.simulation.spatial.sim2D.marbSimulation.translator.ConstantsTranslator.STD_TRANS_STR;
} else {
trStr = ConstantsTranslatorWOC.STD_TRANS_STR;
}
this.translatoren[i] = new Translator(
trStr,
new ScriptInterpreter(
this.getPars(),
ScriptInterpreter.MODUS_VERHALTEN),
this.getPars());
}
this.transCodes[i] = this.translatoren[i].generateSequence();
}
}
/**
* @return Returns the active tAutomat.
*/
public Translator getAktTAut() {
return this.translatoren[this.getAktAutNum()];
}
/**
* @return Ein Array der Stringsequenzen der Translatoren des Roboters.
*/
private String[] erzStdStrTrans() {
String[] sequenzen = new String[this.getVAut().length];
for (int i = 0; i < sequenzen.length; i++) {
sequenzen[i] = this.translatoren[i].erzeugeStringSeq();
}
return sequenzen;
}
/**
* @return Die Translatoren in Standardkodierung.
*/
public String[] getTransStdCodes() {
String[] stdString = new String[this.translatoren.length];
for (int i = 0; i < this.translatoren.length; i++) {
stdString[i] = this.translatoren[i].erzeugeStringSeq();
}
return stdString;
}
/**
* Erzeugt die Translatoren aus Sequenzen, wobei die übergebenen
* Translatoren zugrunde gelegt werden.
*
* @param seqs Die Translatorcodes.
* @param trans Die Translatoren (wenn null, wird null weitergegeben).
* @param pruefen Ob die übersetzer geprüft werden sollen.
*/
@SuppressWarnings(value = { "unchecked" })
public void erzTransAusSeqs(
final String[] seqs,
final Translator[] trans,
final boolean pruefen) {
this.translatoren = new Translator[seqs.length];
this.transCodes = new LinkedList[seqs.length];
Translator[] trans2 = trans;
// Wenn gar keine übersetzer angegeben sind (s.a.u.):
if (trans2 == null) {
trans2 = new Translator[seqs.length];
}
for (int i = 0; i < translatoren.length; i++) {
/*
* Wenn kein Übersetzer angegeben ist, dann muss ein Translatoren-
* Übersetzer angegeben werden, weil die Methode erzTransSeq(...)
* standardmäßig einen Verhaltensübersetzer benutzt.
*/
if (trans2[i] == null) {
String trStr;
if (super.getPars().getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
trStr = ConstantsTranslator.STD_TRANS_STR;
} else {
trStr = ConstantsTranslatorWOC.STD_TRANS_STR;
}
trans2[i] = new Translator(
trStr,
new ScriptInterpreter(
this.getPars(),
StaticMethods.MODUS_TRANSLATOR),
this.getPars());
}
this.erzTransAusSeq(i, seqs[i], trans2[i], pruefen);
}
}
/**
* Erzeugt einen Translator aus einer Sequenz, wobei der übergebene
* Translator als übersetzer dient.
*
* @param transNum Die Nummer des zu erzeugenden Translators.
* @param seq Die Translatorcodes.
* @param trans Die Translatoren (wenn null, wird null weitergegeben).
* @param pruefen Ob die übersetzer geprüft werden sollen.
*/
private void erzTransAusSeq(
final int transNum,
final String seq,
final Translator trans,
final boolean pruefen) {
String bereinigt;
// int altMod = SonstMeth.MODUS_UNGUELTIG;
// if (trans != null) {
// altMod = trans.getModus();
// trans.setModus(SonstMeth.MODUS_TRANSLATOR);
// }
this.translatoren[transNum] = new Translator(
"",
new ScriptInterpreter(
this.getPars(),
ScriptInterpreter.MODUS_VERHALTEN),
this.getPars());
this.translatoren[transNum].generateFromSequence(seq, trans, pruefen, this.getPars());
bereinigt = (new EndlicherAutomat()).bereinige(seq);
this.transCodes[transNum] = StaticMethods.listSeqAusString(bereinigt);
// if (trans != null) {
// trans.setModus(altMod);
// }
}
/**
* Lädt die Automaten mit Translatoren und Bedingungen.
*
* @param graphName Der Name der Datei (mit Pfad nach stdPfad) ohne
* Endung.
*/
@Override
public void ladeAuts(final String graphName) {
String pfad = this.getPars().getStdDirectory() + File.separator;
FileInputStream fs;
ObjectInputStream is;
String datRawName = pfad + graphName + ".";
String[] transSequenzen = null;
Translator[] trans;
super.ladeAuts(graphName);
try {
fs = new FileInputStream(
datRawName + eas.startSetup.marbBuilder.ConstantsGraphVis.TRANS_ENDUNG);
is = new ObjectInputStream(fs);
transSequenzen = (String[]) is.readObject();
is.close();
} catch (final Exception e) {
StaticMethods.log(StaticMethods.LOG_WARNING,
"Translator(en) nicht gefunden: "
+ datRawName
+ eas.startSetup.marbBuilder.ConstantsGraphVis.TRANS_ENDUNG,
this.getPars());
}
if (transSequenzen == null) {
return;
}
// Unnötig??
trans = new Translator[transSequenzen.length];
for (int i = 0; i < trans.length; i++) {
if (super.getPars().getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
trans[i] = ConstantsTranslator.getStdTranslatorBE(this.getPars());
} else {
trans[i] = ConstantsTranslatorWOC.getStdTranslatorBE(this.getPars());
}
}
// Erzeuge Translatoren.
for (int i = 0; i < trans.length; i++) {
if (super.getPars().getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
trans[i] = ConstantsTranslator.getStdTranslatorTR(this.getPars());
} else {
trans[i] = ConstantsTranslatorWOC.getStdTranslatorTR(this.getPars());
}
}
this.erzTransAusSeqs(transSequenzen, trans, false);
}
/**
* Speichert die Automaten mit Translatoren und Bedingungen.
*
* @param graphName Der Name der Datei (mit Pfad nach stdPfad) ohne
* Endung.
*/
@Override
public void speichereAuts(final String graphName) {
String pfad = this.getPars().getStdDirectory() + File.separator;
FileOutputStream fs;
ObjectOutputStream os;
super.speichereAuts(graphName);
try {
// Speichere Translatoren
fs = new FileOutputStream(
pfad
+ graphName
+ "."
+ eas.startSetup.marbBuilder.ConstantsGraphVis.TRANS_ENDUNG);
os = new ObjectOutputStream(fs);
os.writeObject(this.erzStdStrTrans());
os.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @return Ob der Translator mutiert werden soll.
*/
public boolean isMutT() {
return this.mutT;
}
/**
* Mutiert den zu <code>this</code> gehörenden aktiven Verhaltens- und /
* oder Translator-Automaten. Wenn zu einem Automaten kein Translator
* definiert ist, wird dieser mit dem Standardtranslator für Translatoren
* belegt.
*/
@Override
public void mutiere() {
int i = this.getAktAutNum();
LinkedList<Integer> old;
LinkedList<Integer> first;
LinkedList<Integer> firstTrans;
int zyklen = 0;
if (this.isMutV()) {
this.getMutVerh().mutiere(this);
this.translatoren[i].setModus(StaticMethods.MODUS_VERHALTEN);
this.getVAut()[i].generateFromSequence(
StaticMethods.stringAusListSeq(this.getVerhCodes()[i]),
this.translatoren[i],
false, this.getPars());
}
if (this.isMutT()) {
firstTrans = new LinkedList<Integer>();
firstTrans.addAll(this.getTransCodes()[i]);
this.getMutTrans().mutiere(this);
this.translatoren[i].setModus(StaticMethods.MODUS_TRANSLATOR);
old = this.translatoren[i].generateSequence();
first = old;
this.translatoren[i].generateFromSequence(
StaticMethods.stringAusListSeq(this.transCodes[i]),
this.translatoren[i],
false, this.getPars());
while (!old.equals(this.translatoren[i].generateSequence())) {
zyklen++;
old = this.translatoren[i].generateSequence();
this.translatoren[i].generateFromSequence(
StaticMethods.stringAusListSeq(this.transCodes[i]),
this.translatoren[i],
false, this.getPars());
StaticMethods.log(
StaticMethods.LOG_OUTPUT,
"Translatormutation " + zyklen + " für Roboter "
+ this.id()
+ " (Translatorcode-Bytes: "
+ this.translatoren[i].generateSequence().size()
+ ")",
this.getPars());
// DEBUG:
if (this.translatoren[i].generateSequence().size() > 1000000) {
throw new RuntimeException(
"Translator erreichte unzulässige Größe.");
}
// EO DEBUG.
if (zyklen > eas.simulation.ConstantsSimulation.TRANS_WIEDERHOL) {
break;
}
// if (this.translatoren[i].erzeugeSequenz().size() > max) {
// max = this.translatoren[i].erzeugeSequenz().size();
// }
// System.out.println();
// System.out.println(" " + 1);
// System.out.println(this.translatoren[i].erzeugeSequenz().size() + "/" + max);
// System.out.println(this.translatoren[i].getAdjazenzliste().size());
// for (int k = 0; k < this.translatoren[i].getAlleBedingungen().size(); k++) {
// if (this.translatoren[i].getAlleBedingungen().get(k) != null)
// for (int l = 0; l < this.translatoren[i].getAlleBedingungen().get(k).size(); l++) {
// System.out.println(k + "/" + l + ": " + this.translatoren[i].getAlleBedingungen().get(k).get(l).getCond());
// }
// }
}
if (old.size() == 0) {
if (super.getPars().getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
this.translatoren[i].generateFromSequence(
this.translatoren[i].ausgabe(first),
ConstantsTranslator.getStdTranslatorTR(this.getPars()),
false,
this.getPars());
} else {
this.translatoren[i].generateFromSequence(
this.translatoren[i].ausgabe(first),
ConstantsTranslatorWOC.getStdTranslatorTR(this.getPars()),
false,
this.getPars());
}
this.setTransCode(i, firstTrans);
StaticMethods.log(
StaticMethods.LOG_OUTPUT,
"Translator zurückgesetzt für Roboter "
+ this.id()
+ " (Translatorcode-Bytes: "
+ this.translatoren[i].generateSequence().size()
+ ")",
this.getPars());
}
}
if (this.isSelektiert()) {
this.getAktVAut().setzeChanged();
this.getAktVAut().notifyObservers(
new AutomatenNummer(
this.getAktVAut().erzeugeStringSeq(),
this.getAktAutNum()));
}
}
/**
* Geht in den nächsten Zustand über.
*
* @param simZyk Der Simulationszyklus.
*/
@Override
public void step(final Wink simZyk) {
super.step(simZyk);
if (this.getEnvironmentEA().existsPlugin(new EvolutionPluginCompletelyEvolvable().id())) {
// Verhaltensautomaten auf Memory zurücksetzen.
if (simZyk.getLastTick() % this.getPars().getParValueLong(EvolutionPluginCompletelyEvolvable.MEM_AT_VERH)
== this.getPars().getParValueLong(EvolutionPluginCompletelyEvolvable.MEM_AT_VERH) - 1) {
this.resetToBestVerh();
}
// Translatoren auf Memory zurücksetzen.
if (simZyk.getLastTick() % this.getPars().getParValueLong(EvolutionPluginCompletelyEvolvable.MEM_AT_TRANS)
== this.getPars().getParValueLong(EvolutionPluginCompletelyEvolvable.MEM_AT_TRANS) - 1) {
this.resetToBestTrans();
}
// Mutiere Translator, falls Evolution UND erreichte Zyklenzahl.
if (simZyk.getLastTick() % this.mutTransZyklen == this.mutTransZyklen - 1) {
this.mutT = true;
this.mutiere();
this.mutT = false;
GlobaleMARBVariablen.setTMutationInLetztemZyklus(true);
} else {
this.mutT = false;
GlobaleMARBVariablen.setTMutationInLetztemZyklus(false);
}
}
}
/**
* Setzt die Verhaltensautomaten auf die vormals besten zurück
* und setzt die Fitness bei den Automaten auf 0, die sich durch die Aktion
* verändert haben (dies bitte beachten!).
*
* ACHTUNG: Zur übersetzung wird der vormals beste Translator benutzt.
* Daher wird der beste Translator immer bei Fitnessveränderungen
* gespeichert, auch wenn nur für Verhaltensautomaten Memory aktiviert
* ist. Der beste Translator überschreibt in dieser Methode aber nicht
* den aktuellen Translator.
*/
private void resetToBestVerh() {
// System.out.println("MEMORY");
for (int i = 0; i < this.getVAut().length; i++) {
// if (this.getFitness()[i] <= 0
// && this.getFitness()[i] < this.besteFit[i]
// && this.besteFit[i] > 0) {
if (this.getFitness()[i] < this.besteFit[i]
&& this.besteFit[i] > 0) {
// Erzeugen des alten Verhaltens.
this.erzeugeAusSequenz(
i,
StaticMethods.stringAusListSeq(this.besteStdVerh[i]),
null,
null,
false);
// Wiederherstellen des alten Verhaltenscodes.
this.getVerhCodes()[i].clear();
this.getVerhCodes()[i].addAll(this.besteVerhAut[i]);
// TODO: überprüfen, ob diese Zuweisung die beste ist.
this.setFitness(i, 0);
StaticMethods.log(StaticMethods.LOG_OUTPUT,
"Verhaltensautomat "
+ i
+ " auf besten zurückgesetzt (Roboter "
+ this.id()
+ ").",
this.getPars());
} else if (this.getFitness()[i] > this.besteFit[i]) {
// Unkorrekter Fall.
this.setzeBeste();
StaticMethods.log(StaticMethods.LOG_ERROR,
"Beste Fitness war nicht korrekt "
+ "gesetzt (Methode: Roboter.resetToBest).",
this.getPars());
}
}
}
/**
* Setzt die Translatorautomaten auf die vormals besten zurück
* und setzt die Fitness bei den Automaten auf 0, die sich durch die Aktion
* verändert haben (dies bitte beachten!).
*/
private void resetToBestTrans() {
for (int i = 0; i < this.translatoren.length; i++) {
// if (this.getFitness()[i] <= 0
// && this.getFitness()[i] < this.besteFit[i]
// && this.besteFit[i] > 0) {
if (this.getFitness()[i] < this.besteFit[i]
&& this.besteFit[i] > 0) {
// Erzeuge alten Translator aus Standardcode.
if (super.getPars().getParValueBoolean("UseTranslatorWITHCompletingTransitions")) {
this.erzTransAusSeq(
i,
StaticMethods.stringAusListSeq(this.besteStdTrans[i]),
ConstantsTranslator.getStdTranslatorTR(this.getPars()),
false);
} else {
this.erzTransAusSeq(
i,
StaticMethods.stringAusListSeq(this.besteStdTrans[i]),
ConstantsTranslatorWOC.getStdTranslatorTR(this.getPars()),
false);
}
this.getTranslatoren()[i].setModus(StaticMethods.MODUS_VERHALTEN);
// Wiederherstellen des alten Translatorcodes.
this.transCodes[i].clear();
this.transCodes[i].addAll(this.besteTransAut[i]);
// TODO: überprüfen, ob diese Zuweisung die beste ist.
this.setFitness(i, 0);
StaticMethods.log(StaticMethods.LOG_OUTPUT,
"Translator "
+ i
+ " auf besten zurückgesetzt (Roboter "
+ this.id()
+ ").",
this.getPars());
} else if (this.getFitness()[i] > this.besteFit[i]) {
// Unkorrekter Fall.
this.setzeBeste();
StaticMethods.log(StaticMethods.LOG_ERROR,
"Beste Fitness war nicht korrekt "
+ "gesetzt (Methode: Roboter.resetToBest).",
this.getPars());
}
}
}
/**
* Setzt den Fitnesswert eines Automaten.
*
* @param autNum Die Nummer des Automaten.
* @param wert Der Wert, auf den gesetzt wird.
*/
@Override
public void setFitness(final int autNum, final int wert) {
super.setFitness(autNum, wert);
this.setzeBeste();
}
/**
* Setzt die Fitnesswerte aller Automaten.
*
* @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 Codes aller Automaten neu, falls deren
* aktuelle Fitness den besten Wert aller Zeiten hat. Alle Automaten werden
* als Integer-Sequenzen in der aktuellen Kodierung und als
* Standardsequenzen gespeichert.
* Dieser Vorgang wird nur für die Automaten durchgeführt für die
* Memory aktiviert ist (für Translatoren auch, wenn nur für Verhaltens-
* automaten Memory aktiviert ist) und nur falls Evolution aktiviert ist.
*/
private void setzeBeste() {
if (!this.getEnvironmentEA().existsPlugin(new EvolutionPluginCompletelyEvolvable().id())) {
return;
}
for (int i = 0; i < this.getVAut().length; i++) {
if (this.getFitness()[i] > this.besteFit[i]) {
this.besteFit[i] = this.getFitness()[i];
if (this.besteTransAut[i] == null) {
this.besteTransAut[i] = new LinkedList<Integer>();
}
if (this.besteVerhAut[i] == null) {
this.besteVerhAut[i] = new LinkedList<Integer>();
}
if (this.besteStdTrans[i] == null) {
this.besteStdTrans[i] = new LinkedList<Integer>();
}
if (this.besteStdVerh[i] == null) {
this.besteStdVerh[i] = new LinkedList<Integer>();
}
/*
* Speichere aktuelle Translatorencodes, falls Memory für sie
* oder für die Verhaltensautomaten aktiviert ist.
*/
if (this.getPars().getParValueLong(EvolutionPluginCompletelyEvolvable.MEM_AT_TRANS)
<= this.getPars().getParValueDouble("TimeToTermination")
|| this.getPars().getParValueLong(EvolutionPluginCompletelyEvolvable.MEM_AT_VERH)
<= this.getPars().getParValueDouble("TimeToTermination")) {
this.besteTransAut[i].clear();
this.besteTransAut[i].addAll(this.transCodes[i]);
this.besteStdTrans[i].clear();
this.besteStdTrans[i].addAll(this.translatoren[i]
.generateSequence());
}
/*
* Speichere aktuelle Verhaltenscodes, falls Memory für sie
* aktiviert ist.
*/
if (this.getPars().getParValueLong(EvolutionPluginCompletelyEvolvable.MEM_AT_VERH)
<= this.getPars().getParValueDouble("TimeToTermination")) {
this.besteVerhAut[i].clear();
this.besteVerhAut[i].addAll(this.getVerhCodes()[i]);
this.besteStdVerh[i].clear();
this.besteStdVerh[i].addAll(this.erzeugeSequenz(i));
}
// /*
// * Falls mindestens ein Automat neu gesetzt wurde, setze auch
// * den Translator-Standardcode neu.
// */
// if (this.getPars().getMemIntTrans()
// <= this.getPars().getExpLen()
// || this.getPars().getMemIntVerh()
// <= this.getPars().getExpLen()) {
//
// this.besteStdTrans[i].clear();
// this.besteStdTrans[i].addAll(this.translatoren[i]
// .erzeugeSequenz());
// }
}
}
}
/**
* @return Die Translatoren.
*/
public Translator[] getTranslatoren() {
return this.translatoren;
}
/**
* Gibt die Codes der Translatorautomaten zurück.
*
* @return Die Codes der Translatorautomaten.
*/
public List<Integer>[] getTransCodes() {
return this.transCodes;
}
/**
* @param tC Setzt die Translatorcodes.
*/
public void setTransCodes(final LinkedList<Integer>[] tC) {
this.transCodes = tC;
}
/**
* Setzt einen Translatorcode.
*
* @param autNum Die Nummer des Translator-Automaten.
* @param seq Der Code des Translators.
*/
public void setTransCode(final int autNum, final LinkedList<Integer> seq) {
this.transCodes[autNum] = seq;
}
/**
* @param tc Setzt den aktiven Translatorcode.
*/
public void setAktTCode(final List<Integer> tc) {
this.transCodes[this.getAktAutNum()] = tc;
}
/**
* @return Das Mutationsverfahren für Verhalten.
*/
@Override
@Deprecated
public CondMutVerfahren getMut() {
return super.getMut();
}
/**
* @return Das Mutationsverfahren für das Roboterverhalten.
*/
public CondMutVerfahren getMutVerh() {
return super.getMut();
}
/**
* @return Das Mutationsverfahren für den Verhaltensübersetzer.
*/
public CondMutVerfahren getMutTrans() {
return this.mutArtTrans;
}
/**
* @param fitness Die Fitness.
*/
@Deprecated
public void setFitVerboten(final int fitness) {
super.setFitness(0, fitness);
}
// /**
// * Testmethode.
// *
// * @param args Parameter.
// */
// @Deprecated
// public static void main(String[] args) {
// ParCollection params = new ParCollection(args);
// params.ergaenze();
// String seqCode
// = "001 110 100 101 000 012 099 001 000 007 000 000 002 001 000 " +
// "012 099 002 000 004 000 000 005 001 000 000 000 014 105 100 " +
// "001 000 012 099 001 000 004 000 000 010 001 000 012 099 001 " +
// "000 007 000 000 004 001 000 000 000 013 108 100 001 000 012 " +
// "099 001 000 004 000 000 010 001 000 012 099 001 000 007 000 " +
// "000 004 001 000 000 000 012 111 001 001 000 012 099 001 251 " +
// "007 000 000 014 001 000 012 099 001 000 004 000 000 005 001 " +
// "000 000 000 011 111 001 001 000 012 099 001 000 004 000 000 " +
// "010 001 000 012 099 001 000 007 000 000 004 001 000 000 000 " +
// "010 111 001 001 000 012 099 001 000 004 000 000 009 001 000 " +
// "012 099 012 000 008 000 000 012 001 000 012 099 012 000 009 " +
// "000 012 099 001 000 007 000 010 000 000 013 001 000 000 000 " +
// "009 111 001 001 000 012 099 001 000 004 000 000 006 001 000 " +
// "012 099 001 000 007 000 000 007 001 000 000 000 008 103 101 " +
// "100 000 012 099 001 000 007 000 000 004 001 000 012 099 001 " +
// "000 004 000 000 010 001 000 000 000 009 104 101 100 000 012 " +
// "099 001 000 007 000 000 011 001 000 012 099 001 000 004 000 " +
// "000 254 001 000 000 000 006 111 001 001 000 012 099 001 000 " +
// "007 000 000 001 001 000 012 099 001 000 004 000 000 005 001 " +
// "000 000 000 005 106 101 102 000 000 000 004 107 100 001 000 " +
// "012 099 001 000 007 000 000 004 001 000 012 099 001 000 004 " +
// "000 000 010 001 000 000 000 003 102 101 100 000 012 099 001 " +
// "000 007 000 000 008 001 000 012 099 001 000 004 000 000 005 " +
// "001 000 000 000 002 101 101 100 000 012 099 001 000 007 000 " +
// "000 003 254 000 012 099 001 000 004 000 000 005 001 000 000";
//
// String transCode
// = "001, 110, 100, 101, 000, 012, 099, 001, 000, 007, 000, 000, " +
// "002, 001, 000, 012, 099, 002, 000, 004, 000, 000, 005, 001, " +
// "000, 000, 000, 254, 106, 001, 001, 000, 000, 000, 014, 105, " +
// "100, 001, 000, 012, 099, 001, 000, 004, 000, 000, 010, 001, " +
// "000, 012, 099, 001, 000, 007, 000, 000, 004, 001, 000, 000, " +
// "000, 013, 108, 100, 001, 000, 012, 099, 001, 000, 004, 000, " +
// "000, 010, 001, 000, 012, 099, 001, 000, 007, 000, 000, 004, " +
// "001, 000, 000, 000, 012, 111, 001, 001, 000, 012, 099, 001, " +
// "000, 009, 007, 000, 012, 101, 000, 007, 000, 011, 000, 000, " +
// "014, 001, 000, 012, 099, 001, 000, 004, 000, 000, 005, 001, " +
// "000, 000, 000, 011, 111, 001, 001, 000, 012, 099, 001, 000, " +
// "004, 000, 000, 010, 001, 000, 012, 099, 001, 000, 007, 000, " +
// "000, 004, 001, 000, 000, 000, 010, 111, 001, 001, 000, 012, " +
// "099, 001, 000, 004, 000, 000, 009, 001, 000, 012, 099, 012, " +
// "000, 008, 000, 000, 012, 001, 000, 012, 099, 012, 000, 009, " +
// "000, 012, 099, 001, 000, 007, 000, 010, 000, 000, 013, 001, " +
// "000, 000, 000, 009, 104, 101, 100, 000, 012, 099, 001, 000, " +
// "004, 000, 000, 006, 001, 000, 012, 099, 001, 000, 007, 000, " +
// "000, 007, 001, 000, 012, 099, 001, 000, 007, 000, 000, 011, " +
// "001, 000, 012, 099, 001, 000, 004, 000, 000, 254, 001, 000, " +
// "000, 000, 008, 103, 101, 100, 000, 012, 099, 001, 000, 007, " +
// "000, 000, 004, 001, 000, 012, 099, 001, 000, 004, 000, 000, " +
// "010, 001, 000, 000, 000, 007, 106, 001, 001, 000, 000, 000, " +
// "006, 111, 001, 001, 000, 012, 099, 001, 000, 007, 000, 000, " +
// "001, 001, 000, 012, 099, 001, 000, 004, 000, 000, 005, 001, " +
// "000, 000, 000, 005, 106, 101, 102, 000, 000, 000, 004, 107, " +
// "100, 001, 000, 012, 099, 001, 000, 007, 000, 000, 004, 001, " +
// "000, 012, 099, 001, 000, 004, 000, 000, 010, 001, 000, 000, " +
// "000, 003, 102, 101, 100, 000, 012, 099, 001, 000, 007, 000, " +
// "000, 008, 001, 000, 012, 099, 001, 000, 004, 000, 000, 005, " +
// "001, 000, 000, 000, 002, 101, 101, 100, 000, 012, 099, 001, " +
// "000, 007, 000, 000, 003, 001, 000, 012, 099, 001, 000, 004, " +
// "000, 000, 005, 001, 000, 000, 000";
//
// Translator trans = new Translator(
// transCode,
// new ScriptInterpreter(params, StaticMethods.MODUS_TRANSLATOR),
// params);
// Script s = trans.translate(new EndlicherAutomat().bereinige(seqCode));
// ScriptInterpreter sInt = new ScriptInterpreter(params, StaticMethods.MODUS_TRANSLATOR);
// EndlicherAutomat ea = new EndlicherAutomat();
// sInt.generateAutomaton(ea, s);
//// System.out.println(ea.erzeugeSequenz().size());
// System.exit(0);
//
// LinkedList<Integer> seq = ea.erzeugeSequenz();
// System.out.println();
// int zwisch = 0;
// LinkedList<String> array = new LinkedList<String>();
// String seqInt = "";
//
// for (Integer i : seq) {
// zwisch++;
// seqInt = seqInt + i + ", ";
//
// if (zwisch % 100 == 0) {
// array.add(seqInt);
// seqInt = "";
// }
// if (zwisch % 10000 == 0) {
// System.out.print(".");
// }
// }
//
// StaticMethods.speichereTextAusArray("sharedDirectory", "sequenz2.txt", array, params);
// }
/**
* @return Alle Translatoren für diesen Roboter. Dies ist genau einer, wenn
* "completelyEvolvable" eingestellt ist, die Kaskade in der
* Reihenfolge [Verhaltenstranslator, Verhaltenstranslator-Translator, ...]
* im Fall der kaskadierten Evolution.
* (Unter Voraussetzung, dass es nur die zwei Varianten gibt.)
*/
public List<Translator> getAllTranslators() {
LinkedList<Translator> list = new LinkedList<Translator>();
EvolutionPluginCascadingTranslators pluginCasc = (EvolutionPluginCascadingTranslators)
this.getEnvironment().getPluginObject(new EvolutionPluginCascadingTranslators().id());
// Unter Voraussetzung, dass es nur die zwei Varianten gibt...
if (pluginCasc == null) { // CompletelyEvolvable...
list.add(this.getTranslatoren()[0]);
} else { // Cascading...
int i = 1; // Beginne bei 1. Translator-Level (0 = Verhalten).
Translator trans = (Translator) pluginCasc.getAutomat(this.id(), i);
while (trans != null) {
list.add(trans);
i++;
trans = null;
try {
trans = (Translator) pluginCasc.getAutomat(this.id(), i);
} catch (Exception e) {
}
}
}
return list;
}
public boolean isVersetzt() {
return this.versetzt;
}
public void setVersetzt(final boolean vers) {
this.versetzt = vers;
}
/**
* Increases the age of all reacheable states and transitions
*/
public void aging() {
List<Integer> vCode = getVerhCodes()[this.getAktAutNum()];
String seq = StaticMethods.stringAusListSeq(vCode);
EndlicherAutomat ea = new EndlicherAutomat();
ea.generateFromSequence(seq, getTranslatoren()[this.getAktAutNum()], false, this.getPars());
double prob = this.getPars().getParValueDouble("reachProb");
for (Integer nodeId: ea.getAdjazenzliste().keySet()) {
Knoten node = ea.getAdjazenzliste().get(nodeId);
if (ea.erreichbarVonStart(node.holeName(), prob)) {
if (!node.getInfo().istStartZ()) {
node.getInfo().setAlter(node.getInfo().getAlter() + 1);
}
for (Transition t: node.getInfo().getBeds()) {
if (StaticMethods.condStrength(
t.getCond(),
eas.startSetup.marbBuilder.darstellungsModi.ConstantsDarstellung.STAERKE_ERST,
eas.startSetup.marbBuilder.darstellungsModi.ConstantsDarstellung.STAERKE_ZWEIT)
>= prob) {
t.setAlter(t.getAlter() + 1);
}
}
}
}
getVerhCodes()[this.getAktAutNum()] = ea.generateSequence();
}
}