-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 752a50c
Showing
176 changed files
with
7,480 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<groupId>Genotick</groupId> | ||
<artifactId>Genotick</artifactId> | ||
<version>0.2.0</version> | ||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version> | ||
2.5.1 | ||
</version> | ||
<configuration> | ||
<source>1.7</source> | ||
<target>1.7</target> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-jar-plugin</artifactId> | ||
<version>2.5</version> | ||
<configuration> | ||
<archive> | ||
<manifest> | ||
<addClasspath>true</addClasspath> | ||
<classpathPrefix>lib</classpathPrefix> | ||
<mainClass>com.alphatica.genotick.genotick.Main</mainClass> | ||
</manifest> | ||
</archive> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
17 changes: 17 additions & 0 deletions
17
src/main/java/com/alphatica/genotick/breeder/BreederSettings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.alphatica.genotick.breeder; | ||
|
||
public class BreederSettings { | ||
public final long outcomesBetweenBreeding; | ||
public final double inheritedWeightPercent; | ||
public final long minimumOutcomesToAllowBreeding; | ||
public final double randomPrograms; | ||
public final int dataMaximumOffset; | ||
|
||
public BreederSettings(long timeBetweenChildren, double inheritedWeightPercent, long minimumParentAge, double randomPrograms, int dataMaximumOffset) { | ||
this.outcomesBetweenBreeding = timeBetweenChildren; | ||
this.inheritedWeightPercent = inheritedWeightPercent; | ||
this.minimumOutcomesToAllowBreeding = minimumParentAge; | ||
this.randomPrograms = randomPrograms; | ||
this.dataMaximumOffset = dataMaximumOffset; | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/alphatica/genotick/breeder/ProgramBreeder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.alphatica.genotick.breeder; | ||
|
||
import com.alphatica.genotick.mutator.Mutator; | ||
import com.alphatica.genotick.population.Population; | ||
|
||
public interface ProgramBreeder { | ||
|
||
void breedPopulation(Population population); | ||
|
||
void setSettings(BreederSettings breederSettings, Mutator mutator); | ||
|
||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/com/alphatica/genotick/breeder/ProgramBreederFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.alphatica.genotick.breeder; | ||
|
||
import com.alphatica.genotick.mutator.Mutator; | ||
|
||
public class ProgramBreederFactory { | ||
public static ProgramBreeder getDefaultBreeder(BreederSettings breederSettings, Mutator mutator) { | ||
ProgramBreeder breeder = SimpleBreeder.getInstance(); | ||
breeder.setSettings(breederSettings,mutator); | ||
return breeder; | ||
} | ||
} |
189 changes: 189 additions & 0 deletions
189
src/main/java/com/alphatica/genotick/breeder/SimpleBreeder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
package com.alphatica.genotick.breeder; | ||
|
||
import com.alphatica.genotick.genotick.Debug; | ||
import com.alphatica.genotick.instructions.Instruction; | ||
import com.alphatica.genotick.instructions.InstructionList; | ||
import com.alphatica.genotick.mutator.Mutator; | ||
import com.alphatica.genotick.population.Population; | ||
import com.alphatica.genotick.population.Program; | ||
import com.alphatica.genotick.population.ProgramInfo; | ||
|
||
import java.util.Collections; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
|
||
public class SimpleBreeder implements ProgramBreeder { | ||
private BreederSettings settings; | ||
private Mutator mutator; | ||
|
||
public static ProgramBreeder getInstance() { | ||
return new SimpleBreeder(); | ||
} | ||
|
||
@Override | ||
public void breedPopulation(Population population) { | ||
Debug.d("Breeding population"); | ||
Debug.d("Current population size", population.getSize()); | ||
addRequiredRandomPrograms(population); | ||
if(population.haveSpaceToBreed()) { | ||
breedPopulationFromParents(population); | ||
addOptionalRandomPrograms(population); | ||
} | ||
Debug.d("Breeder exiting"); | ||
Debug.d("Current population size", population.getSize()); | ||
} | ||
|
||
private void addOptionalRandomPrograms(Population population) { | ||
int count = population.getDesiredSize() - population.getSize(); | ||
if(count > 0) { | ||
fillWithPrograms(count, population); | ||
} | ||
} | ||
|
||
private void addRequiredRandomPrograms(Population population) { | ||
if(settings.randomPrograms > 0) { | ||
int count = (int)Math.round(settings.randomPrograms * population.getDesiredSize()); | ||
fillWithPrograms(count,population); | ||
} | ||
} | ||
|
||
private void fillWithPrograms(int count, Population population) { | ||
for(int i = 0; i < count; i++) { | ||
createNewProgram(population); | ||
} | ||
} | ||
|
||
private void createNewProgram(Population population) { | ||
Program program = Program.createEmptyProgram(settings.dataMaximumOffset); | ||
int instructionsCount = mutator.getNextInt() % 1024; | ||
InstructionList main = program.getMainFunction(); | ||
while(instructionsCount-- > 0) { | ||
addInstructionToMain(main, mutator); | ||
} | ||
population.saveProgram(program); | ||
} | ||
|
||
private void addInstructionToMain(InstructionList main, Mutator mutator) { | ||
Instruction instruction = mutator.getRandomInstruction(); | ||
instruction.mutate(mutator); | ||
main.addInstruction(instruction); | ||
} | ||
private void breedPopulationFromParents(Population population) { | ||
List<ProgramInfo> programInfoList = population.getProgramInfoList(); | ||
removeNotAllowedPrograms(programInfoList); | ||
Collections.sort(programInfoList, ProgramInfo.comparatorByAbsoluteWeight); | ||
breedPopulation(population, programInfoList); | ||
} | ||
|
||
private void removeNotAllowedPrograms(List<ProgramInfo> programInfoList) { | ||
Iterator<ProgramInfo> iterator = programInfoList.iterator(); | ||
while(iterator.hasNext()) { | ||
ProgramInfo programInfo = iterator.next(); | ||
if(!programInfo.canBeParent(settings.minimumOutcomesToAllowBreeding, settings.outcomesBetweenBreeding)) | ||
iterator.remove(); | ||
} | ||
} | ||
|
||
private void breedPopulation(Population population, List<ProgramInfo> list) { | ||
while(population.haveSpaceToBreed()) { | ||
Program parent1 = getPossibleParent(population,list); | ||
Program parent2 = getPossibleParent(population,list); | ||
if(parent1 == null || parent2 == null) | ||
break; | ||
Program child = Program.createEmptyProgram(settings.dataMaximumOffset); | ||
makeChild(parent1,parent2,child); | ||
population.saveProgram(child); | ||
parent1.increaseChildren(); | ||
population.saveProgram(parent1); | ||
parent2.increaseChildren(); | ||
population.saveProgram(parent2); | ||
} | ||
} | ||
|
||
private void makeChild(Program parent1, Program parent2, Program child) { | ||
double weight = getParentsWeight(parent1, parent2); | ||
child.setInheritedWeight(weight); | ||
InstructionList instructionList = mixMainInstructionLists(parent1,parent2); | ||
child.setMainInstructionList(instructionList); | ||
} | ||
|
||
private double getParentsWeight(Program parent1, Program parent2) { | ||
return settings.inheritedWeightPercent * (parent1.getWeight() + parent2.getWeight()) / 2; | ||
} | ||
|
||
private InstructionList mixMainInstructionLists(Program parent1, Program parent2) { | ||
InstructionList source1 = parent1.getMainFunction(); | ||
InstructionList source2 = parent2.getMainFunction(); | ||
return blendInstructionLists(source1,source2); | ||
} | ||
|
||
/* | ||
This potentially will make programs gradually shorter. | ||
Let's say that list1.size == 4 and list2.size == 2. Average length is 3. | ||
Then, break1 will be between <0,3> and break2 <0,1> | ||
All possible lengths for new InstructionList will be: 0,1,2,3,1,2,3,4 with equal probability. | ||
Average length is 2. | ||
For higher numbers this change isn't so dramatic but may add up after many populations. | ||
*/ | ||
private InstructionList blendInstructionLists(InstructionList list1, InstructionList list2) { | ||
InstructionList instructionList = InstructionList.createInstructionList(); | ||
int break1 = Math.abs(mutator.getNextInt()) % list1.getSize(); | ||
int break2 = Math.abs(mutator.getNextInt()) % list2.getSize(); | ||
copyBlock(instructionList, list1,0,break1); | ||
copyBlock(instructionList, list2,break2, list2.getSize()); | ||
return instructionList; | ||
} | ||
|
||
private void copyBlock(InstructionList destination, InstructionList source, int start, int stop) { | ||
assert start <= stop: "start > stop " + String.format("%d %d", start,stop); | ||
for(int i = start; i <= stop; i++) { | ||
Instruction instruction = source.getInstruction(i).copy(); | ||
addInstructionToInstructionList(instruction,destination); | ||
} | ||
} | ||
|
||
private void addInstructionToInstructionList(Instruction instruction, InstructionList instructionList) { | ||
if(!mutator.skipNextInstruction()) { | ||
if (mutator.getAllowNewInstruction()) { | ||
instruction = mutator.getRandomInstruction(); | ||
instructionList.addInstruction(instruction); | ||
} | ||
if (mutator.getAllowInstructionMutation()) { | ||
instruction.mutate(mutator); | ||
} | ||
instructionList.addInstruction(instruction); | ||
} | ||
} | ||
|
||
private Program getPossibleParent(Population population, List<ProgramInfo> list) { | ||
double totalWeight = sumTotalWeight(list); | ||
double target = totalWeight * mutator.getNextDouble(); | ||
double weightSoFar = 0; | ||
Program parent = null; | ||
Iterator<ProgramInfo> iterator = list.iterator(); | ||
while(iterator.hasNext()) { | ||
ProgramInfo programInfo = iterator.next(); | ||
weightSoFar += Math.abs(programInfo.getWeight()); | ||
if(weightSoFar >= target) { | ||
parent = population.getProgram(programInfo.getName()); | ||
iterator.remove(); | ||
break; | ||
} | ||
} | ||
return parent; | ||
} | ||
|
||
private double sumTotalWeight(List<ProgramInfo> list) { | ||
double weight = 0; | ||
for(ProgramInfo programInfo: list) { | ||
weight += Math.abs(programInfo.getWeight()); | ||
} | ||
return weight; | ||
} | ||
|
||
@Override | ||
public void setSettings(BreederSettings breederSettings, Mutator mutator) { | ||
this.settings = breederSettings; | ||
this.mutator = mutator; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.alphatica.genotick.data; | ||
|
||
class DataException extends RuntimeException { | ||
|
||
public DataException(String s) { | ||
super(s); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.alphatica.genotick.data; | ||
|
||
public class DataFactory { | ||
public static DataLoader getDefaultLoader(String args) { | ||
return new FileSystemDataLoader(args); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.alphatica.genotick.data; | ||
|
||
public interface DataLoader { | ||
MainAppData createProgramData(); | ||
} |
Oops, something went wrong.