/*
* File name: EvolutionPlugin.java (package eas.simulation.users.students.dominikColling.rocket)
* Author(s): aifb
* Java version: 6.0
* Generation date: 02.05.2011 (18:13:18)
*
* (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.users.students.dominikColling.rocket;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import eas.math.geometry.Vector2D;
import eas.plugins.AbstractDefaultPlugin;
import eas.simulation.Wink;
import eas.simulation.event.EASEvent;
import eas.startSetup.ParCollection;
import eas.startSetup.SingleParameter;
import eas.users.students.dominikColling.rocket.brain.DomPhysNeuroBrain;
import eas.users.students.dominikColling.rocket.brain.DomPhysSparseNet;
import eas.users.students.dominikColling.rocket.brain.DominikEncoding1;
/**
* @author Dominik Colling
*
*/
@SuppressWarnings("unused")
public class EvolutionPlugin extends AbstractDefaultPlugin<DomPhysEnv> {
private static final long serialVersionUID = -3346371752984422436L;
int saveLoad; // 0 nichts 1 Speichern 2 Lesen
int i = 1; // Zähler für Agenten
private int drehung = 1; // 0 normal 1 90Grad gedreht
private Random rand;
private DomPhysNetPopulation netPop;
private int popSize;
private int zaehlerStartPositionen;
private List<DomPhysSparseNet> netze;
private int zaehler = 0;
//private List<Integer> amLeben;
private List<Vector2D> startPositionen;
DomPhysAgentenPop agenten;
@Override
public List<String> getRequiredPlugins() {
return null;
}
@Override
public List<SingleParameter> getParameters() {
return null;
}
@Override
public String id() {
return "EvolutionPlugin";
}
@Override
public void runBeforeSimulation(DomPhysEnv env, ParCollection params) {
// Plugin<?> plug = env.getSimTime().getPluginObject("SaveLoadPlugin");
// plug.getClass();
netPop = env.getNetPop();
popSize = netPop.getMaxSize();
rand = env.getRand();
saveLoad = env.getSaveLoad();
netze = new ArrayList<DomPhysSparseNet>();
zaehler = 0;
this.generiereStartPositionen(env, netPop.getMaxSize(), env.getAbstand());
//zaehlerStartPositionen = 0;
//amLeben = new ArrayList<Integer>();
agenten = new DomPhysAgentenPop(netPop.getMaxSize(), env, params, 0);
for (int l = 0; l < popSize; l++) {
DomPhysAgent agent = agenten.getAgent(l);
//if(saveLoad == 0 || saveLoad == 1) {
DomPhysNeuroBrain hirn = new DomPhysNeuroBrain(agent, i, env.getRand(), params);
agent.implantBrain(hirn);
i++;
//}
Vector2D startPosition = startPositionen.get(l);
double startWinkel = this.generiereStartWinkel(startPosition);
env.addAgent(agent, startPosition, startWinkel);
agent.setAmLeben(true);
// für Versuch 110707.4
/*float y = (float) Math.cos(startWinkel) * -50;
float x = (float) Math.sin(startWinkel) * 50; */
// für Versuch 110707.5
//float x = (float)startPosition.x / 10;
//float y = (float)startPosition.y / 10;
//agent.adjustVelocity(new Vector2f(x,y));
}
}
@Override
public void runAfterSimulation(DomPhysEnv env, ParCollection params) {
if (saveLoad == 0 || saveLoad == 1) {
//speichern der noch lebenden
for (int l = 0; l < netPop.getSize(); l++) {
DomPhysAgent agent = (DomPhysAgent) env.getAgent(l +1);
DomPhysSparseNet hirn = agent.getBrain().getNet();
int fitness = agent.getEvaluationInt();
double minAbstand = agent.getMinAbstand();
double maxAbstand = agent.getMaxAbstand();
int geburt = agent.getGeburt();
netPop.addZwischen(hirn, fitness, minAbstand, maxAbstand, geburt);
}
}
DomPhysSparseNet hirn9 = netPop.getBestesNetz();
System.out.println("BESTES AM SCHLUSS: \n" + new DominikEncoding1().encode(hirn9));
}
@Override
public void runDuringSimulation(DomPhysEnv env, Wink simZyk, ParCollection params) {
if (saveLoad == 2) {
if(simZyk.getCurrentTime() == 1) {
netPop = env.getNetPop();
System.out.println("GROESSE: " + netPop.getSize());
for (int l = 1; l < popSize; l++) {
DomPhysAgent agent = agenten.getAgent(l);
DomPhysNeuroBrain hirn = new DomPhysNeuroBrain(agent, netPop.getNet(l).getId(), env.getRand(), netPop.getNet(l));
agent.implantBrain(hirn);
}
DomPhysAgent agent = agenten.getAgent(0);
DomPhysNeuroBrain hirn = new DomPhysNeuroBrain(agent, netPop.getNet(netPop.getIndexBestesNetz()).getId(), env.getRand(), netPop.getBestesNetz());
agent.implantBrain(hirn);
System.out.println("GELADEN: " + hirn.getNet().generateGenome(new DominikEncoding1()) + " Fitness: " + netPop.getFitness(netPop.getIndexBestesNetz()) + " ID: " + hirn.getNet().getId());
for (int l = 1; l < popSize; l++) {
agent = agenten.getAgent(l);
env.removeAgent(l + 1);
}
}
/*if(simZyk.getCurrentTime() == 100) {
DomPhysAgent agent = agenten.getAgent(0);
agent.setAgentShapeBIG();
}*/
//TEST
/*if(simZyk.getCurrentTime() == 20000) {
DomPhysAgent agent = agenten.getAgent(0);
float x = 10;
float y = 10;
agent.adjustVelocity(new Vector2f(x,y));
}
if(simZyk.getCurrentTime() == 6000) {
DomPhysAgent agent = agenten.getAgent(0);
float x = 10;
float y = 10;
agent.adjustVelocity(new Vector2f(x,y));
}
if(simZyk.getCurrentTime() == 10000) {
DomPhysAgent agent = agenten.getAgent(0);
float x = 10;
float y = 10;
agent.adjustVelocity(new Vector2f(x,y));
} */
}
/*if (saveLoad == 2) {
for (int l = 1; l < popSize; l++) {
DomPhysAgent agent = agenten.getAgent(l);
agent.evaluate(simZyk);
} */
DomPhysAgent agent2 = agenten.getAgent(0);
agent2.evaluate(simZyk);
if(simZyk.getCurrentTime() % 50 == 0) {
//System.out.println("FITNESS: " + agent2.getEvaluation() + " TICK: " + simZyk.getCurrentTime());
}//System.out.println("Inputs: " + hirn.getNet().getInputs() + " Outputs: " + hirn.getNet().getOutputs());
if (saveLoad == 0 || saveLoad == 1) {
// Evaluierung jede Runde
for (int l = 1; l < popSize + 1; l++) {
DomPhysAgent agent = (DomPhysAgent) env.getAgent(l);
if (saveLoad == 0 || saveLoad == 1) {
//System.out.println(agent.getID() + "amLeben?: " + agent.getAmLeben() + "HIRN: " + agent.getBrain().getNet().getId());
agent.evaluate(simZyk);
}
// Speichern und entfernen von toten Agenten
int fitness = agent.getEvaluationInt();
Color farbe = agent.getAgentColor();
boolean lebend = agent.getAmLeben();
/*if(l == 37) {
System.out.println("Antrieb: " + agent.getActuatorWerte()[0] *80 + " / Drehung: " + agent.getActuatorWerte()[1] * 0.3);
}*/
if(!lebend) {
DomPhysSparseNet netAlt = agent.getBrain().getNet();
double minAbstand = agent.getMinAbstand();
double maxAbstand = agent.getMaxAbstand();
int geburt = agent.getGeburt();
netPop.add(netAlt, fitness, minAbstand, maxAbstand, geburt);
//System.out.println("Jetzt hinzufuegen: " + new DominikEncoding1().encode(hirn));
env.removeAgent(l);
// mutiertes Hirn
DomPhysSparseNet netNeu = (DomPhysSparseNet) this.randVerteilung(netPop.getNetze(), netPop.getFitnesswerte(), env.getRand());
DomPhysSparseNet mutNetNeu = netNeu.createMutatedOffspring(i, rand);
DomPhysNeuroBrain hirnNeu = new DomPhysNeuroBrain(agent, i, env.getRand(), mutNetNeu);
agent.implantBrain(hirnNeu);
//Erkennung
//if(i == 1131) {
//agent.setAgentShapeBIG();
//System.out.println(l);
//}
/*if(l == 37) {
System.out.println("1. X: " + agent.getForce().getX() + "Y: " + agent.getForce().getY() +" ROTATION: " +agent.getRotation()+ " Antrieb: " + agent.getActuatorWerte()[0] + " Drehung: " + agent.getActuatorWerte()[1]);
System.out.println("2. X: " + agent.getVelocity().getX() + "Y: " + agent.getVelocity().getY()+ "WINKELGESCHW: " + agent.getAngularVelocity() + "ID: " + agent.getID());
}*/
int runde = ((int) simZyk.getCurrentTime());
agent.reset(runde);
i++;
Vector2D startPosition = startPositionen.get(l - 1);
double startWinkel = this.generiereStartWinkel(startPosition);
env.addAgent(agent, startPosition, startWinkel);
// für Versuch 110707.4
float y = (float) Math.cos(startWinkel) * -50;
float x = (float) Math.sin(startWinkel) * 50;
//agent.adjustVelocity(new Vector2f(x,y));
/*if(l == 37) {
System.out.println("3. X: " + agent.getForce().getX() + "Y: " + agent.getForce().getY() +" ROTATION: " +agent.getRotation()+ " Antrieb: " + agent.getActuatorWerte()[0] + " Drehung: " + agent.getActuatorWerte()[1]);
System.out.println("4. X: " + agent.getVelocity().getX() + "Y: " + agent.getVelocity().getY()+ "WINKELGESCHW: " + agent.getAngularVelocity() + "ID: " + agent.getID());
System.out.println("Antrieb: " + agent.getActuatorWerte()[0] *80);
System.out.println("Drehung: " + agent.getActuatorWerte()[1] * 0.3);
}*/
}
}
if((simZyk.getCurrentTime() % 1000 == 0)) {
//Zwischenspeichern noch lebenden
for (int l = 1; l < popSize + 1; l++) {
DomPhysAgent agent = (DomPhysAgent) env.getAgent(l);
DomPhysSparseNet hirn = agent.getBrain().getNet();
int fitness = agent.getEvaluationInt();
double minAbstand = agent.getMinAbstand();
double maxAbstand = agent.getMaxAbstand();
int geburt = agent.getGeburt();
netPop.addZwischen(hirn, fitness, minAbstand, maxAbstand, geburt);
}
}
}
}
/* if (pop.getSize() >= pop.getMaxSize()) {
DomPhysNeuroBrain hirn2;
switch(selektion) {
case 1:
hirn2 = pop.turnier(10);
break;
case 2:
hirn2 = pop.roulette();
break;
default:
hirn2 = pop.turnier(10);
break;
}
*/
@Override
public void handleEvent(EASEvent e, DomPhysEnv env, Wink lastTimeStep,
ParCollection params) {
// TODO Comment.
}
public void generiereStartPositionen(DomPhysEnv env, int anzahl, double abstand){
DomPhysMond mond = (DomPhysMond) env.getAgent(0);
double radius = mond.getRadius() + abstand;
double anzahl2 = anzahl;
startPositionen = new ArrayList<Vector2D>();
for (double d = 0; d < Math.PI * 2; d += Math.PI * 2 / anzahl2) {
this.startPositionen.add(new Vector2D(Math.sin(d) * radius, Math.cos(d) * radius));
}
}
public double generiereStartWinkel(Vector2D startPosition){
double startWinkelBM = Math.atan(startPosition.y / startPosition.x);
//double startWinkelBM = startPosition.winkel(new Vector2D(0,-1));
//normalerweise
double startWinkel = startWinkelBM * 180 / (Math.PI) - 90;
//für Versuch 110707.4
if (drehung == 1) {
startWinkel = startWinkelBM * 180 / (Math.PI);
}
if (startPosition.x < 0){
startWinkel = startWinkel - 180;
}
return startWinkel;
}
/* AUS MATH-METH */
public Object randVerteilung(
final List<?> obj,
final List<Integer> vert,
final Random rand) {
Object[] list = new Object[obj.size()];
for (int i = 0; i < obj.size(); i++) {
list[i] = obj.get(i);
}
return randVerteilung(list, vert, rand);
}
public Object randVerteilung(final Object[] obj,
final List<Integer> vert,
final Random rand) {
if (obj.length != vert.size()) {
throw new RuntimeException("Listen haben ungleiche Laenge.");
}
long summe = 0;
long zufall;
long akt;
int i;
Iterator<Integer> it = vert.iterator();
while (it.hasNext()) {
akt = it.next().longValue();
if (akt < 0) {
throw new RuntimeException("Negative Wahrscheinlichkeit: "
+ akt);
} else {
summe += akt;
}
}
if (summe > 0) {
long randNum = Math.abs(rand.nextLong());
zufall = randNum % summe + 1;
summe = 0;
i = -1;
it = vert.iterator();
while (summe < zufall) {
summe += it.next().longValue();
i++;
}
} else {
i = rand.nextInt(obj.length);
}
return obj[i];
}
/* ENDE MATH-METH */
/* (non-Javadoc)
* @see eas.plugins.Plugin#getSupportedPlugins()
*/
@Override
public List<String> getSupportedPlugins() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onSimulationResumed(DomPhysEnv env, Wink resumeTime,
ParCollection params) {
}
}