Package fmg.fmg8.umgebung2D

Source Code of fmg.fmg8.umgebung2D.Simulation

/*
* Datei: Simulation.java
* Autor(en):        Lukas K�nig
* Java-Version:     6.0
* Erstellt (vor): 08.05.2008
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/

package fmg.fmg8.umgebung2D;

import fmg.fmg8.endlAutomat.OpsFactory;
import fmg.fmg8.endlAutomat.RobCode;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.endlAutomat.rekombination.RekVerfahren;
import fmg.fmg8.gif.SimpleGIF;
import fmg.fmg8.graphVis.Vis;
import fmg.fmg8.sonstiges.DateiFilter;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.statistik.Aufnahme;
import fmg.fmg8.statistik.Parametersatz;
import fmg.fmg8.statistik.PopSnapshot;
import fmg.fmg8.umgebung2D.dynWaende.Dynamik;

import java.awt.Image;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;
import java.util.Random;


/**
* Implementiert eine Simulation als initiale Zuordnung einer Menge von
* Robotern zu einer Umgebung und einer anschlie�enden iterierten Ausf�hrung
* von Zustandswechseln der Roboter und evolution�ren Operatoren.
*
* @author Lukas K�nig
*/
public class Simulation implements Observer {

    /**
     * Abfolge von Bildern des Simulationsfeldes.
     */
    private LinkedList<Image> bilder;
   
    /**
     * Die Nummer der aktuellen GIF-Datei.
     */
    private int gifNum = 0;
   
    /**
     * Liste von Robotern (im VisMantel), die verwaltet werden.
     */
    private ArrayList<VisMantel> graphen;

    /**
     * Der Zufallsgenerator.
     */
    private Random rand;
   
    /**
     * Das Rekombinationsverfahren.
     */
    private RekVerfahren rekombArt;

    /**
     * Die Umgebung, die durch <code>this</code> dargestellt wird.
     */
    private Umgebung umgebung;

    /**
     * Die Anzahl der Zustandswechsel seit der letzten Rekombination.
     */
    private int rekZustandswechsel;
   
    /**
     * Ob evolviert wird.
     */
    private boolean evolution;

    /**
     * Die Parameter.
     */
    private Parametersatz pars;
   
    /**
     * Die Aufnahme dieses Evolutionslaufs.
     */
    private Aufnahme aufnahme;
   
    /**
     * Anzahl der Zyklen seit dem letzten Schnappschuss.
     */
    private long schnappZyklen;

    /**
     * Anzahl der Zyklen seit dem letzten GIF-Schnappschuss.
     */
    private long schnappGIFZyklen;
   
    /**
     * Die Simulationszyklen.
     */
    private long simZyklen;
   
    /**
     * Der Observer f�r die Umgebung.
     */
    private Observer observer;
   
    /**
     * Liste von graphischen Observern der Automaten der Simulation.
     */
    private Vis[] visObserver;
   
    /**
     * Konstruktor, der die Attribute initialisiert.
     *
     * @param params   Die Parameter.
     * @param obs      Ein m�glicher Observer f�r die Umgebung.
     * @param visObs   Die Vis-Observer.
     * @param wandDyn  Die Wanddynamik f�r diese Umgebung.
     */
    public Simulation(final Parametersatz params,
                      final Observer      obs,
                      final Vis[]         visObs,
                      final Dynamik       wandDyn) {
       
        GlobaleVariablen.setCollCount(0);
       
        this.pars = params;
        this.observer = obs;
        this.visObserver = visObs;

        this.aufnahme = new Aufnahme(this.pars);
        this.schnappZyklen = this.pars.getSchnInt().longValue();
        this.schnappGIFZyklen = this.pars.getSchnappGIF();
        this.rand = new Random(this.pars.getSeed().longValue());
        this.rekombArt = OpsFactory.getKonstRek(
                this.pars.getRekombVerfahren(),
                this.pars,
                this.rand);
       
        this.umgebung = new Umgebung(this.rand,
                                     this.pars,
                                     this.observer,
                                     this,
                                     wandDyn);
        this.graphen = new ArrayList<VisMantel>();
        this.ladeGraphen();
       
        this.rekZustandswechsel = 0;
        this.simZyklen = 0;
        this.evolution = this.pars.getEvol().booleanValue();
        this.platziereRoboter();
        this.bilder = new LinkedList<Image>();

        SonstMeth.log(
                SonstMeth.LOG_INFO,
                "Roboter in Simulation: "
                    + this.getUm().getAkteure().size(),
                this.pars);
       
        if (this.pars.getZufallsGenLen() >= 0) {
            this.setzeVerhGenZuf(this.pars.getZufallsGenLen());
            SonstMeth.log(
                    SonstMeth.LOG_INFO,
                    "Verhaltensgenome mit Zufallsgenomen der L�nge "
                        + this.pars.getZufallsGenLen() + " �berschrieben.",
                    this.pars);
        }
    }
   
    /**
     * Konstruktor, der die Attribute initialisiert.
     *
     * @param params     Die Parameter.
     * @param obs        Ein m�glicher Observer f�r die Umgebung.
     * @param visObs     Die Vis-Observer.
     * @param automaten  Die Initialautomaten f�r die simulierten Roboter.
     * @param condColl   Die Bedingungen.
     * @param ids        Die Identit�tsnummern der Roboter.
     * @param wandDyn  Die Wanddynamik f�r diese Umgebung.
     */
    public Simulation(final Parametersatz params,
                      final Observer      obs,
                      final Vis[]         visObs,
                      final String[][]    automaten,
                      final Condition[][] condColl,
                      final int[]         ids,
                      final Dynamik       wandDyn) {
        this.pars = params;
        this.observer = obs;
        this.visObserver = visObs;

        this.aufnahme = new Aufnahme(this.pars);
        this.schnappZyklen = this.pars.getSchnInt().longValue();
        this.schnappGIFZyklen = this.pars.getSchnappGIF();
        this.rand = new Random(this.pars.getSeed().longValue());
        this.rekombArt = OpsFactory.getKonstRek(
                this.pars.getRekombVerfahren(),
                this.pars,
                this.rand);
       
        this.umgebung = new Umgebung(this.rand,
                                     this.pars,
                                     this.observer,
                                     this,
                                     wandDyn);
        this.graphen = new ArrayList<VisMantel>();
       
        this.zuordnen(visObs, automaten, condColl, ids);
       
        this.rekZustandswechsel = 0;
        this.simZyklen = 0;
        this.evolution = this.pars.getEvol().booleanValue();
        this.platziereRoboter();
        this.bilder = new LinkedList<Image>();
    }

    /**
     * Setzt die Verhaltensgenome auf zuf�llige Sequenzen anzugebender L�nge.
     *
     * @param laenge Die L�nge der Genome.
     */
    @SuppressWarnings("unchecked")
    private void setzeVerhGenZuf(final int laenge) {
        LinkedList<Integer>[] sequenzen;
       
        for (Roboter r : this.getUm().getAkteure()) {
            sequenzen = new LinkedList[r.getVAut().length];
           
            for (int i = 0; i < r.getVAut().length; i++) {
                sequenzen[i] = this.zufallsSequenz(laenge);
            }
           
            r.setVerhCodes(sequenzen);
        }
    }
   
    /**
     * Erzeugt eine Zufallssequenz.
     *
     * @param laenge  Die L�nge der Sequenz.
     *
     * @return  Die Zufallssequenz.
     */
    private LinkedList<Integer> zufallsSequenz(final int laenge) {
        LinkedList<Integer> sequenz = new LinkedList<Integer>();
        final int maxNum = 255;
        double gauss;
       
        for (int i = 0; i < laenge; i++) {
            gauss = Math.min(Math.abs(this.rand.nextGaussian() * 10), maxNum);
            sequenz.add((int) gauss);
        }

        return sequenz;
    }
   
    /**
     * L�dt gespeicherte Graphen aus dem im Parameterobjekt angegebenen
     * Verzeichnis.
     */
    private void ladeGraphen() {
        File verz = new File(this.pars.getStdPfad());
        String endung = fmg.fmg8.graphVis.Konstanten.GRAPH_ENDUNG;
        String[] gespGr = verz.list(new DateiFilter(endung));
        String grNam;
        VisMantel visRob = null;
        Vis obs = null;
        boolean sel = false;
       
        if (gespGr != null) {
            for (int i = 0; i < gespGr.length; i++) {
                grNam = gespGr[i].substring(
                                0,
                                gespGr[i].length() - endung.length() - 1);
               
                if (this.pars.getGraphisch().booleanValue()) {
                    for (int j = 0; j < this.visObserver.length; j++) {
                        if (this.visObserver[j].getGraphName().equals(grNam)) {
                            obs = this.visObserver[j];
                            sel = this.visObserver[j].isVisible();
                            break;
                        }
                    }
                }
               
                visRob = new VisMantel(grNam,
                        this.umgebung,
                        OpsFactory.getKonstMut(
                                this.pars.getMutArtVerh(),
                                this.rand,
                                this.pars),
                        OpsFactory.getKonstMut(
                                this.pars.getMutArtTrans(),
                                this.rand,
                                this.pars),
                        this.rand,
                        this.kleinsteFreieID(),
                        this.pars,
                        sel,
                        obs);

                this.graphen.add(visRob);
            }
        }
    }
   
   
    /**
     * Erzeugt aus einer Automatenliste die zugeh�rigen Roboter und
     * ordnet sie den entsprechenden Observern zu.
     *
     * @param visObs     Die Vis-Observer.
     * @param automaten  Die Automaten.
     * @param condColl   Die Bedingungen.
     * @param ids        Die Identit�tsnummern der Automaten.
     */
    private void zuordnen(final Vis[]         visObs,
                          final String[][]    automaten,
                          final Condition[][] condColl,
                          final int[]         ids) {
       
        String[] auts = new String[1];
        Condition[] conds = new Condition[1];
       
        if (visObs.length != automaten.length) {
            throw new RuntimeException("Unterschiedliche Anzahl von Automaten "
                                       + "und Vis-Objekten.");
        }
       
        String grNam;
        VisMantel visRob = null;
        Vis obsVis = null;
        boolean sel = false;
       
        for (int i = 0; i < visObs.length; i++) {
            grNam = visObs[i].getGraphName();
           
            if (this.pars.getGraphisch().booleanValue()) {
                obsVis = this.visObserver[i];
                sel = this.visObserver[i].isVisible();
            }
           
            auts = automaten[i];
            conds = condColl[i];
           
            visRob = new VisMantel(auts,
                                   conds,
                                   grNam,
                                   this.umgebung,
                                   this.rand,
                                   ids[i],
                                   this.pars,
                                   sel,
                                   obsVis);

            this.graphen.add(visRob);
        }
    }

    /**
     * Speichert alle Graphen in der Liste <code>this.graphen</code>.
     */
    public void speichereAlleGraphen() {
        Iterator<VisMantel> it = this.graphen.iterator();
        VisMantel aktGr;

        while (it.hasNext()) {
            aktGr = (VisMantel) it.next();
            aktGr.speichereGraph();
        }
    }

    /**
     * Gibt die kleinste noch nicht von einem der aktuellen Graphen verwendete
     * ID zur�ck.
     *
     * @return  Die kleinste noch nicht verwendete ID.
     */
    public int kleinsteFreieID() {
        int kleinste = 0;
        Iterator<VisMantel> it = this.graphen.iterator();
        VisMantel aktGr;
       
        while (it.hasNext()) {
            aktGr = (VisMantel) it.next();
            if (kleinste <= aktGr.getRob().getId()) {
                kleinste = aktGr.getRob().getId() + 1;
            }
        }
       
        return kleinste;
    }

    /**
     * Endlosz�hler der Schnappsch�sse f�r die Automatenspeicherung.
     */
    private long schnappAuts = 0;
   
    /**
     * F�hrt einen einzelnen Simulationsschritt aus, der einem Zeitzyklus
     * entspricht.
     */
    private void step() {
        ArrayList<Roboter> akteure;
        Iterator<Roboter> it;
        ArrayList<RobCode> kindAkteure;
        boolean automatSp;
        String[] infos;
       
        this.rekZustandswechsel++;
        akteure = this.umgebung.getAkteure();

        it = akteure.iterator();
        while (it.hasNext()) {
            it.next().naechsterZustand();
        }

        if (this.evolution
            && this.rekZustandswechsel
               >= this.pars.getRekZyklen().longValue()) {
            kindAkteure = this.rekombArt.rekombiniere(akteure);
            this.umgebung.uebernimmPop(kindAkteure);
            this.rekZustandswechsel = 0;
        }
       
        if (this.schnappZyklen >= this.pars.getSchnInt().longValue()) {
            if (this.pars.getAufnSp().booleanValue()) {
                if (this.schnappAuts % this.pars.getSchnappAut() == 0) {
                    automatSp = true;
                } else {
                    automatSp = false;
                }
   
                this.schnappAuts++;
                this.aufnahme.addPopSn(new PopSnapshot(
                        this.umgebung.getAkteure(),
                        this.umgebung.getGegVerschieb(),
                        this.simZyklen,
                        automatSp,
                        this.umgebung.getAktDynPixel()));
            }
           
            this.schnappZyklen = 0;
        }

        if (this.schnappGIFZyklen >= this.pars.getSchnappGIF()) {
            infos = new String[3];
            infos[0] = "Zyklen: " + this.simZyklen;
            infos[1] = "Koll %: " + GlobaleVariablen.getCollCount();
            infos[2] = "GP %: " + GlobaleVariablen.getGateCount();
            if (this.pars.getGIFDatei() != null) {
                this.bilder.add(this.umgebung.erzeugeBild(infos));
            }
           
            this.schnappGIFZyklen = 0;
        }
       
        this.schnappZyklen++;
        this.schnappGIFZyklen++;
        this.simZyklen++;
        this.umgebung.beendeZeichenSession();
//        System.gc();
    }

    /**
     * Speichert die Bilderfolge der Simulation als GIF-Datei.
     *
     * @param datNam  Der Dateiname.
     */
    private void gifSpeichern(final String datNam) {
        String pfad = this.pars.getStdPfad() + File.separator;
        String datei =
            pfad
            + datNam
            + SonstMeth.normZahl(this.gifNum, 6)
            + ".gif";
        FileOutputStream fs;
        Image[] imgs = new Image[this.bilder.size()];
        int i = 0;
        double bilderProSek
            = (double) 50 / (double) this.pars.getSchnappGIF();
       
        for (Image img : this.bilder) {
            imgs[i] = img;
            i++;
        }
       
        try {
            fs = new FileOutputStream(datei);
            SimpleGIF.writeAnimatedGIF(
                    imgs,
                    "",
                    false,
                    bilderProSek,
                    fs);
        } catch (final Exception e) {
            throw new RuntimeException("GIF nicht gespeichert.");
        }
       
        SonstMeth.log(
                SonstMeth.LOG_INFO,
                "GIF-Datei gespeichert: " + datei,
                this.pars);
    }
   
    /**
     * Beendet die Simulation: speichert die Aufnahme.
     */
    public void simulationEnde() {
        if (this.pars.getAufnSp().booleanValue()) {
            this.umgebung.beendeSimulation();
        }
        this.aufnahmeSpeichern();
       
        if (this.pars.getGraphisch().booleanValue()) {
            Iterator<VisMantel> it = this.graphen.iterator();
            while (it.hasNext()) {
                ((VisMantel) it.next()).getRob().simBeendet();
            }
        }
       
        this.gifNum = 0;
    }
   
    /**
     * Speichert die Aufnahme.
     */
    public void aufnahmeSpeichern() {
        if (this.pars.getAufnSp().booleanValue()) {
            this.aufnahme.speichern();
        }
        if (this.pars.getGIFDatei() != null) {
            this.gifSpeichern(this.pars.getGIFDatei());
            this.bilder.clear();
            this.gifNum++;
        }
    }
   
    /**
     * Platziert die Roboter.
     */
    public void platziereRoboter() {
        Iterator<VisMantel> it;
        Roboter rob;

        it = this.graphen.iterator();
        while (it.hasNext()) {
            rob = ((VisMantel) it.next()).getRob();
            rob.zuruecksetzen();

            this.umgebung.hinzuRobotRand(rob);
        }
    }

    /**
     * Die Update-Methode der beobachtenden Klasse.
     *
     * @param o    Das beobachtete Objekt, von dem die Meldung ausging.
     * @param arg  Argument.
     */
    public void update(final Observable o, final Object arg) {
        this.step();
    }

    /**
     * @return Returns the umgebung.
     */
    public Umgebung getUm() {
        return this.umgebung;
    }

    /**
     * @return Returns the evolution.
     */
    public boolean isEvolution() {
        return this.evolution;
    }

    /**
     * @param evol  The evolution to set.
     */
    public void setEvolution(final boolean evol) {
        this.evolution = evol;
    }
}
TOP

Related Classes of fmg.fmg8.umgebung2D.Simulation

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.