Package eas.simulation.spatial.sim2D.marbSimulation

Source Code of eas.simulation.spatial.sim2D.marbSimulation.RobEA

/*
* 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();
    }
}
TOP

Related Classes of eas.simulation.spatial.sim2D.marbSimulation.RobEA

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.