/*
* Dateiname: SimulationsZeit.java
* Autor(en): Lukas K�nig
* Java-Version: 6
* Erstellt (vor): 14.05.2009
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/
package fmg.fmg8.umgebung2D;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.graphVis.GuiSimulation;
import fmg.fmg8.graphVis.Vis;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.statistik.Parametersatz;
import fmg.fmg8.statistik.TraceBetrachter;
import fmg.fmg8.umgebung2D.dynWaende.DynFactory;
import fmg.fmg8.umgebung2D.dynWaende.Dynamik;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Random;
/**
* @author Lukas K�nig
*/
public class SimulationsZeit extends Observable
implements Runnable {
/**
* Die observierende Simulation.
*/
private Simulation sim;
/**
* Die Parameter.
*/
private Parametersatz pars;
/**
* Anzahl der bisher erfolgten Simulationsschritte.
*/
private long simZyklen;
/**
* Ob die Simulation zum n�chstm�glichen Zeitpunkt gestoppt werden soll.
*/
private boolean stoppen;
/**
* Ein Observer f�r die Umgebung im Zeitablauf.
*/
private GuiSimulation guiSim;
/**
* Die Visobserver.
*/
private Vis[] visObserver;
/**
* Ob die Betrachtung oder die Simulation aktiviert ist.
*/
private boolean betrachtung;
/**
* Die Automaten.
*/
private String[][] automata;
/**
* Die Bedingungen, die zu den Automaten geh�ren.
*/
private Condition[][] condCollection;
/**
* Die IDs.
*/
private int[] identities;
/**
* Objekt zur Ver�nderung der dynamischen W�nde.
*/
private Dynamik dyn;
/**
* Startet eine Simulation mit �bergebenen Automaten, anstatt die
* Roboter von der Festplatte zu laden. Benutzt von TraceBetrachter.
* (Die dynamischen W�nde werden nicht direkt ver�ndert.)
*
* @param params Die Parameter.
* @param obs Ein Observer f�r die Umgebung.
* @param visObs Die Vis-Observer.
* @param automaten Die zugeh�rigen Automaten.
* @param condColl Die Bedingungen.
* @param ids Die zugeh�rigen ids.
*/
public SimulationsZeit(final Parametersatz params,
final GuiSimulation obs,
final Vis[] visObs,
final String[][] automaten,
final Condition[][] condColl,
final int[] ids) {
this.pars = params;
this.guiSim = obs;
this.visObserver = visObs;
this.betrachtung = true;
this.automata = automaten;
this.condCollection = condColl;
this.identities = ids;
this.reset();
this.addObserver(this.sim);
}
/**
* Konstruktor, benutzt von SteuerFenster.
*
* @param params Die Parameter f�r den Lauf.
* @param obs Ein Observer f�r die Umgebung im Zeitablauf.
* @param visObs Die Visobserver.
* @param wandDyn Ein Objekt zur Ver�nderung der W�nde in jedem Zyklus.
*/
public SimulationsZeit(final Parametersatz params,
final GuiSimulation obs,
final Vis[] visObs,
final Dynamik wandDyn) {
this.pars = params;
this.guiSim = obs;
this.visObserver = visObs;
this.betrachtung = false;
this.dyn = wandDyn;
this.reset();
this.addObserver(this.sim);
}
/**
* Setzt den Zeitablauf auf den Anfang.
*/
private void reset() {
if (this.betrachtung) {
this.sim = new Simulation(this.pars,
this.guiSim,
this.visObserver,
this.automata,
this.condCollection,
this.identities,
this.dyn);
} else {
this.sim = new Simulation(this.pars,
this.guiSim,
this.visObserver,
this.dyn);
}
this.stoppen = false;
this.simZyklen = 0;
this.sim.setEvolution(this.pars.getEvol());
SonstMeth.log(
SonstMeth.LOG_INFO,
"Simulationszeit zurueckgesetzt.",
this.pars);
}
/**
* F�hrt den gesamten Zeitablauf aus.
*/
public void run() {
SonstMeth.log(2,
"Automatischer Zeitablauf gestartet. ",
this.pars);
boolean fortsetzen = this.step();
while (fortsetzen) {
fortsetzen = this.step();
}
SonstMeth.log(2, "Automatischer Zeitablauf beendet.", this.pars);
}
/**
* F�hrt einen Zeitschritt aus.
*
* @return Ob ein Zeitschritt ausgef�hrt werden konnte oder der Zeitablauf
* beendet wurde.
*/
public boolean step() {
if (!stoppen && (this.simZyklen < this.pars.getExpLen().longValue()
|| this.pars.getEndlos().booleanValue())) {
if (this.simZyklen < this.pars.getUmschInSim()) {
this.dyn.verschVorUm(
this.sim.getUm(),
this.simZyklen,
this.pars);
} else { // Umschalten in reine Simulation.
if (this.sim.isEvolution()) {
this.sim.setEvolution(false);
this.sim.getUm().resetRobs();
SonstMeth.log(
SonstMeth.LOG_INFO,
"Evolution wurde abgschaltet im "
+ this.simZyklen
+ ". Zyklus.",
this.pars);
}
this.dyn.verschNachUm(
this.sim.getUm(),
this.simZyklen,
this.pars);
}
if (this.simZyklen % 100 == 0) {
ArrayList<Long> counters = new ArrayList<Long>(2);
counters.add(GlobaleVariablen.getCollCount());
counters.add(GlobaleVariablen.getGateCount());
SonstMeth.log(1,
"Zeitzyklus: "
+ this.simZyklen
+ " / "
+ this.pars.getExpLen()
+ " (#Fitness: "
+ this.sim.getUm().getDurchFit()
+ ", Koll.: "
+ GlobaleVariablen.getCollCount()
+ ", Gate: "
+ GlobaleVariablen.getGateCount()
+ ")",
this.pars,
"",
counters);
GlobaleVariablen.setCollCount(0);
GlobaleVariablen.setGateCount(0);
}
if (this.simZyklen != 0 && this.pars.getZwischSp() != 0
&& this.simZyklen % this.pars.getZwischSp() == 0) {
this.sim.aufnahmeSpeichern();
}
this.simZyklen++;
this.setChanged();
this.notifyObservers();
return true;
} else {
//this.sim.simulationEnde();
this.zeitBeenden();
return false;
}
}
/**
* Startet den Zeitablauf mit automatischem Weiterlaufen.
*/
public void zeitStarten() {
Thread simThread = new Thread(this);
simThread.start();
}
/**
* Beendet den Zeitablauf.
*/
public void zeitBeenden() {
this.sim.simulationEnde();
if (guiSim != null) {
this.guiSim.setWeiterlaufen(false);
}
this.reset();
if (this.pars.getExtraktNachSim()) {
// Fitnesswerte etc. extrahieren.
String[] argumente = new String[2];
argumente[0] = this.pars.getStdPfad();
argumente[1] = "allefitnesswerte";
TraceBetrachter.main(argumente);
}
}
/**
* Startet einen Zeitablauf mit Simulation ohne GUI.
*
* @param args Die Parameter.
*/
public static void main(final String[] args) {
Parametersatz params = new Parametersatz(args);
params.ergaenze();
params.setGraphisch(false);
if (params.getGraphisch().booleanValue()) {
throw new RuntimeException("Nur Kommandozeilenmodus erlaubt.");
}
SonstMeth.log(
SonstMeth.LOG_DEBUG,
params.toString(),
params,
"plain",
null);
SimulationsZeit simT = new SimulationsZeit(
params,
null,
null,
DynFactory.getKonstDyn(
params.getDynArt(),
params,
new Random(params.getSeed())));
// TODO: Random?
simT.zeitStarten();
}
/**
* @return Returns the dyn.
*/
public Dynamik getDyn() {
return this.dyn;
}
}