double portionSparseNet = params.getParValueDouble("portionSparseNet");
double portionBody = params.getParValueDouble("portionBody");
double portionSum = portionSparseNet + portionBody;
EvolvableBoxAgent3DGenome newGenome = null;
Vector3f newAgentSize = new Vector3f(genomeToBeMutated.getAgentSize());
EvoBoxSparseNet newSparseNet = genomeToBeMutated.getSparseNet().createOffspring(0);
// Make an exact copy of the old genome's appendices info.
LinkedList<EvolvableBoxAgent3DAppendixInfo> newAppendixInfoList = new LinkedList<EvolvableBoxAgent3DAppendixInfo>();
Iterator<EvolvableBoxAgent3DAppendixInfo> iterGenomeToBeMutated = genomeToBeMutated
.getAppendixInfoList().iterator();
while (iterGenomeToBeMutated.hasNext()) {
EvolvableBoxAgent3DAppendixInfo ainfoOld = iterGenomeToBeMutated
.next();
EvolvableBoxAgent3DAppendixInfo ainfoNew = new EvolvableBoxAgent3DAppendixInfo(
ainfoOld.getAppendixId(), ainfoOld.getPredecessorId(),
ainfoOld.getSize(), ainfoOld.getPositionOnPredecessor(),
ainfoOld.getFreeAxis());
newAppendixInfoList.add(ainfoNew);
}
//float typeOfMutation = random.nextFloat();
//if (typeOfMutation < .95) {
if (random.nextDouble()*portionSum < portionSparseNet) {
//System.out.println("Mutate the brain!");
newSparseNet.mutate(params, random);
}
else {
//System.out.println("Mutate the body!");
// Define type of mutation.
// 0: change box size, 1: change position on
// predecessor, 2: change free axis,
// 3: add new appendix, 4: delete one appendix
//int pos = neurons.size() - outputs + outputNr;
int typeOfBodyMutation = random.nextInt(5);
//System.out.println("Type of mutation: " + typeOfBodyMutation);
switch (typeOfBodyMutation) {
// //////////////////////
// Mutate the box size.
case 0: {
int numberOfBoxToChange = random
.nextInt(newAppendixInfoList.size() + 1);
// Mutate the core.
if (numberOfBoxToChange == 0) {
newAgentSize = mutateVector3fKeepPositive(newAgentSize, random);
}
// Mutate one of the appendices.
else {
EvolvableBoxAgent3DAppendixInfo ainfoOld = newAppendixInfoList
.remove(numberOfBoxToChange - 1);
Vector3f newBoxSize = mutateVector3fKeepPositive(ainfoOld
.getSize(), random);
EvolvableBoxAgent3DAppendixInfo ainfoNew = new EvolvableBoxAgent3DAppendixInfo(
ainfoOld.getAppendixId(),
ainfoOld.getPredecessorId(), new Vector3f(
newBoxSize),
ainfoOld.getPositionOnPredecessor(),
ainfoOld.getFreeAxis());
newAppendixInfoList.add(numberOfBoxToChange - 1, ainfoNew);
}
//System.out.println("Box size mutated.");
break;
}
// /////////////
// Mutate position on predecessor
case 1: {
int numberOfAppendixToChange = random.nextInt(newAppendixInfoList
.size());
EvolvableBoxAgent3DAppendixInfo ainfoOld = newAppendixInfoList
.remove(numberOfAppendixToChange);
Vector3f newPositionOnPredecessor = mutateVector3fAllowNegative(ainfoOld
.getPositionOnPredecessor(), random);
EvolvableBoxAgent3DAppendixInfo ainfoNew = new EvolvableBoxAgent3DAppendixInfo(
ainfoOld.getAppendixId(), ainfoOld.getPredecessorId(),
ainfoOld.getSize(), new Vector3f(
newPositionOnPredecessor),
ainfoOld.getFreeAxis());
newAppendixInfoList.add(numberOfAppendixToChange, ainfoNew);
//System.out.println("Position on predecessor mutated.");
break;
}
// /////////////
// Change freeAxis
case 2: {
int numberOfAppendixToChange = random.nextInt(newAppendixInfoList
.size());
EvolvableBoxAgent3DAppendixInfo ainfoOld = newAppendixInfoList
.remove(numberOfAppendixToChange);
int newFreeAxis = random.nextInt(3);
int oldFreeAxis = ainfoOld.getFreeAxis();
// AVOID THE BUGGY y-AXIS!!! FIX THIS LATER!
while ((newFreeAxis == 1) || newFreeAxis == oldFreeAxis) {
newFreeAxis = random.nextInt(3);
}
EvolvableBoxAgent3DAppendixInfo ainfoNew = new EvolvableBoxAgent3DAppendixInfo(
ainfoOld.getAppendixId(), ainfoOld.getPredecessorId(),
ainfoOld.getSize(),
ainfoOld.getPositionOnPredecessor(), newFreeAxis);
newAppendixInfoList.add(numberOfAppendixToChange, ainfoNew);
//System.out.println("FreeAxis mutated");
break;
}
// ///////////////////
// Add new appendix.
case 3: {
// DEFINE UPPER LIMIT
if (newAppendixInfoList.size() >= 9) {
//System.out.println("Already 10 boxes, no boxes were added.");
//break;
}
int newAppendixId = newAppendixInfoList.size() + 1;
int newPredecessorId = random.nextInt(newAppendixInfoList.size());
Vector3f newSize = new Vector3f();
newSize.x = .5f + (float) Math.abs(random.nextGaussian());
newSize.y = .5f + (float) Math.abs(random.nextGaussian());
newSize.z = .5f + (float) Math.abs(random.nextGaussian());
Vector3f newPositionOnPredecessor = new Vector3f();
newPositionOnPredecessor.x = (float) random.nextGaussian();
newPositionOnPredecessor.y = (float) random.nextGaussian();
newPositionOnPredecessor.z = (float) random.nextGaussian();
// Defines free axis. 0: x, 1: y, 2: z. All others are locked.
int newFreeAxis = random.nextInt(3);
// BUG IN JBULLET?! Wenn die y-Achse (1) benutzt wird, kommt es
// zu
// Sprüngen
// und Aussetzern. So ein $§&%$§&)$%&§$=!!!!!
//if (Math.random() > .5) {
//newFreeAxis = 0;
//} else {
//newFreeAxis = 2;
//}
EvolvableBoxAgent3DAppendixInfo ainfoNew = new EvolvableBoxAgent3DAppendixInfo(
newAppendixId, newPredecessorId, newSize,
newPositionOnPredecessor, newFreeAxis);
//System.out.println("2222222222222222222appendix list old: " + genomeToBeMutated.getAppendixInfoList().size() + " and new: " + newAppendixInfoList.size());
newAppendixInfoList.add(ainfoNew);
//System.out.println("3333333333333appendix list old: " + genomeToBeMutated.getAppendixInfoList().size() + " and new: " + newAppendixInfoList.size());
newSparseNet = newSparseNet.createOffspring(0);
newSparseNet.insertInputNeuron(newAppendixId-1);
newSparseNet.insertOutputNeuron(newAppendixId-1);
//System.out.println("Appendix added. newAppendixInfoList.size: " +newAppendixInfoList.size());
//System.out.println("\n\nDEBUG:" + newSparseNet.generateGenome(new EvoBoxBrainEncoding()) + "\n\n");
//newSparseNet.dump();
//System.out.println("\n\n-----------------------\n\n");
break;
}
// ////////////////
// Remove one appendix
case 4: {
if (newAppendixInfoList.size() == 1) {
//System.out.println("Nothing removed because only 2 boxes are left.");
break;
}
int idOfAppendixToBeRemoved = random.nextInt(genomeToBeMutated
.getAppendixInfoList().size() - 1) + 1;
EvolvableBoxAgent3DAppendixInfo appendixToBeRemoved = genomeToBeMutated
.getAppendixInfoList().get(idOfAppendixToBeRemoved - 1);
int predecessorIdOfAppendixToBeRemoved = appendixToBeRemoved
.getPredecessorId();
newAppendixInfoList.remove(idOfAppendixToBeRemoved - 1);
for (int currentId = 0; currentId < genomeToBeMutated
.getAppendixInfoList().size() - 1; currentId++) {
EvolvableBoxAgent3DAppendixInfo ainfoOld = genomeToBeMutated
.getAppendixInfoList().get(currentId);
int newPredecessorId;
if (ainfoOld.getPredecessorId() == idOfAppendixToBeRemoved) {
newPredecessorId = predecessorIdOfAppendixToBeRemoved;
} else {
newPredecessorId = ainfoOld.getPredecessorId();
}
EvolvableBoxAgent3DAppendixInfo ainfoNew = new EvolvableBoxAgent3DAppendixInfo(
currentId + 1, newPredecessorId,
ainfoOld.getSize(),
ainfoOld.getPositionOnPredecessor(),
ainfoOld.getFreeAxis());
newAppendixInfoList.remove(currentId);
newAppendixInfoList.add(currentId, ainfoNew);
}
newSparseNet.deleteInputNeuron(idOfAppendixToBeRemoved-1);
newSparseNet.deleteOutputNeuron(idOfAppendixToBeRemoved-1);
//System.out.println("Appendix removed");
break;
}
}
}
newGenome = new EvolvableBoxAgent3DGenome(newAgentSize);
newGenome.setAppendices(newAppendixInfoList);
newGenome.setSparseNet(newSparseNet);
//System.out.println("Old sparsenet: " + genomeToBeMutated.getSparseNet().createOffspring(0).generateGenome(new EvoBoxBrainEncoding()));
//System.out.println("New sparsenet: " + newGenome.getSparseNet().generateGenome(new EvoBoxBrainEncoding()));
return newGenome;
}