/*
* Datei: Simulation.java
* Autor(en): Lukas K�nig
* Java-Version: 1.4
* 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.RobCode;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.endlAutomat.mutation.MutationSEQ;
import fmg.fmg8.endlAutomat.mutation.mutSeq.EinzelMutAdd;
import fmg.fmg8.endlAutomat.mutation.mutSeq.MutSeqVerf;
import fmg.fmg8.endlAutomat.mutation.mutSeq.MutationKlWkeit;
import fmg.fmg8.endlAutomat.rekombination.RekTrivial;
import fmg.fmg8.endlAutomat.rekombination.RekVerfahren;
import fmg.fmg8.graphVis.Vis;
import fmg.fmg8.sonstiges.DateiFilter;
import fmg.fmg8.statistik.Aufnahme;
import fmg.fmg8.statistik.Parametersatz;
import fmg.fmg8.statistik.PopSnapshot;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
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 {
/**
* 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;
/**
* 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.
*/
public Simulation(final Parametersatz params,
final Observer obs,
final Vis[] visObs) {
GlobaleVariablen.collCount = 0;
this.pars = params;
this.observer = obs;
this.visObserver = visObs;
this.aufnahme = new Aufnahme(this.pars);
this.schnappZyklen = this.pars.getSchnInt().longValue();
this.rand = new Random(this.pars.getSeed().longValue());
this.rekombArt = new RekTrivial(
this.pars.getRekAnzEltern(),
this.pars.getRekAnzKinder(),
this.pars.getRekNormiert(),
this.pars.getRekMaxPopSize(),
this.rand);
this.umgebung = new Umgebung(this.rand,
this.pars,
this.observer);
this.graphen = new ArrayList<VisMantel>();
this.ladeGraphen();
this.rekZustandswechsel = 0;
this.simZyklen = 0;
this.evolution = this.pars.getEvol().booleanValue();
this.platziereRoboter();
}
/**
* 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.
*/
public Simulation(final Parametersatz params,
final Observer obs,
final Vis[] visObs,
final String[][] automaten,
final Condition[][] condColl,
final int[] ids) {
this.pars = params;
this.observer = obs;
this.visObserver = visObs;
this.aufnahme = new Aufnahme(this.pars);
this.schnappZyklen = this.pars.getSchnInt().longValue();
this.rand = new Random(this.pars.getSeed().longValue());
this.rekombArt = new RekTrivial(
this.pars.getRekAnzEltern(),
this.pars.getRekAnzKinder(),
this.pars.getRekNormiert(),
this.pars.getRekMaxPopSize(),
this.rand);
this.umgebung = new Umgebung(this.rand,
this.pars,
this.observer);
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();
}
/**
* 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;
}
}
}
MutSeqVerf mutSeqVerh = new MutationKlWkeit(
new EinzelMutAdd(
this.rand,
this.pars.getMutVerhStdAbw()),
this.pars.getMutVerhWkeit(),
this.pars.getMutMinFaktorVerh(),
this.pars.getMutMaxFaktorVerh(),
this.pars.getMutSeqLenKonstVerh(),
this.rand);
MutSeqVerf mutSeqTrans = new MutationKlWkeit(
new EinzelMutAdd(
this.rand,
this.pars.getMutTransStdAbw()),
this.pars.getMutTransWkeit(),
this.pars.getMutMinFaktorTrans(),
this.pars.getMutMaxFaktorTrans(),
this.pars.getMutSeqLenKonstTrans(),
this.rand);
visRob = new VisMantel(grNam,
this.umgebung,
new MutationSEQ(mutSeqVerh, true, false),
new MutationSEQ(mutSeqTrans, false, true),
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.
*/
public void step() {
ArrayList<Roboter> akteure;
Iterator<Roboter> it;
ArrayList<RobCode> kindAkteure;
boolean automatSp;
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()
&& this.pars.getAufnSp().booleanValue()) {
if (this.schnappAuts % this.pars.getSchnappAut() == 0) {
automatSp = true;
} else {
automatSp = false;
}
this.schnappAuts++;
this.schnappZyklen = 0;
this.aufnahme.addPopSn(new PopSnapshot(
this.umgebung.getAkteure(),
this.umgebung.getGegVerschieb(),
this.simZyklen,
automatSp));
}
this.schnappZyklen++;
this.simZyklen++;
this.umgebung.beendeZeichenSession();
}
/**
* 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();
}
}
}
/**
* Speichert die Aufnahme.
*/
public void aufnahmeSpeichern() {
this.aufnahme.speichern();
}
/**
* 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;
}
}