Skip to content

Commit

Permalink
In this commit the solution has evolved to improve the interface:
Browse files Browse the repository at this point in the history
- Added the evolution class
- Added some methods to allow easly building of populations
- Added methods to allow calculating the population fitness
- Added support for selection crossers, selectos and mutators on the Evolution
  • Loading branch information
Mauro J Giamberardino committed Dec 13, 2016
1 parent 0fc87fe commit b21e113
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 59 deletions.
22 changes: 17 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,22 @@

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
13 changes: 0 additions & 13 deletions src/main/java/com/mgiamberardino/jnetic/App.java

This file was deleted.

53 changes: 53 additions & 0 deletions src/main/java/com/mgiamberardino/jnetic/population/Evolution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.mgiamberardino.jnetic.population;

import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

public class Evolution<T, U> {

private Population<T, U> population;
private BiFunction<T, T, List<T>> crosser;
private Function<List<T>, List<T>> selector;
private Function<T, T> mutator;

public static <T, U> Evolution<T, U> of(Population<T,U> population) {
return new Evolution<T, U>(population);
}

Evolution(Population<T, U> population){
this.population = population;
}

public Population<T, U> evolve() {
return Population.of(population);
}

public Evolution<T, U> crosser(BiFunction<T, T, List<T>> crosser) {
this.crosser = crosser;
return this;
}

public BiFunction<T, T, List<T>> crosser() {
return crosser;
}

public Evolution<T, U> selector(Function<List<T>, List<T>> selector) {
this.selector = selector;
return this;
}

public Function<List<T>, List<T>> selector() {
return selector;
}

public Evolution<T, U> mutator(Function<T, T> mutator) {
this.mutator = mutator;
return this;
}

public Function<T,T> mutator() {
return mutator;
}

}
64 changes: 61 additions & 3 deletions src/main/java/com/mgiamberardino/jnetic/population/Population.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,84 @@
package com.mgiamberardino.jnetic.population;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Population<T> {
public class Population<T, U> {

private List<T> members;
private Function<T, U> aptitudeFunction;

public static <T, U> Population<T, U> of(List<T> members, Function<T, U> aptitudeFunction) {
return new Population<T, U>(members);
}

public static <T, U> Population<T, U> generate(Supplier<T> generator, Integer size) {
return new Population<T, U>(
Stream.generate(generator)
.limit(size)
.collect(Collectors.toList()));
}

public static <T, U> Population<T, U> of(Population<T, U> population) {
return new Population<T, U>(population.members()).aptitudeFunction(population.aptitudeFunction());
}

Population(List<T> members){
this.members = members;
this.members = new ArrayList<T>(members);
}

public Integer size() {
return members.size();
}

public Stream<T> stream() {
return (Stream<T>) Stream.of(members.toArray());
return members.stream();
}

public void evolve(Integer iterations) {

}

public U calculateFitness(Function<Stream<U>, U> fitnessFunction, Function<T, U> aptitudeFunction) {
if (null == aptitudeFunction){
throw new IllegalArgumentException("Aptitude function can't be null.");
}
if (null == fitnessFunction){
throw new IllegalArgumentException("Fitness function can't be null.");
}
return fitnessFunction.apply(
members.stream()
.map(aptitudeFunction));
}

public U calculateFitness(Function<Stream<U>, U> fitnessFunction) {
if (null == aptitudeFunction){
throw new IllegalStateException("You need to define the aptitude function to run this method.");
}
return fitnessFunction.apply(
members.stream()
.map(aptitudeFunction));
}

public Evolution<T, U> evolution() {
return new Evolution<T, U>(this);
}

public Population<T,U> aptitudeFunction(Function<T, U> aptitudeFunction) {
this.aptitudeFunction = aptitudeFunction;
return this;
}

public Function<T,U> aptitudeFunction() {
return aptitudeFunction;
}

private List<T> members() {
return members;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.mgiamberardino.jnetic.population;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.junit.Test;

public class EvolutionTest {
private static BiFunction<Integer, Integer, List<Integer>> CROSSER = (i1, i2) -> Arrays.asList(i1, i2);
private static Function<List<Integer>, List<Integer>> SELECTOR = (list) -> new ArrayList<>(list);
private static Function<Integer, Integer> MUTATOR = (i1) -> i1;

@Test
public void testEvolutionCreation() {
Evolution<Integer, Integer> ev = Evolution.of(Population.of(IntStream.range(0,10).boxed().collect(Collectors.toList()),Function.identity()));
assertNotNull(ev);
}

@Test
public void testEvolutionEvolve(){
Evolution<Integer, Integer> ev = Evolution.of(Population.of(IntStream.range(0,10).boxed().collect(Collectors.toList()),Function.identity()));
assertNotNull(ev.evolve());
}

@Test
public void testSetCrosser(){
assertEquals(CROSSER, Evolution.of(Population.of(IntStream.range(0,10).boxed().collect(Collectors.toList()),Function.identity()))
.crosser(CROSSER)
.crosser());
}

@Test
public void testSetSelector(){
assertEquals(SELECTOR, Evolution.of(Population.of(IntStream.range(0,10).boxed().collect(Collectors.toList()),Function.identity()))
.selector(SELECTOR)
.selector());
}

@Test
public void testSetMutator(){
assertEquals(MUTATOR, Evolution.of(Population.of(IntStream.range(0,10).boxed().collect(Collectors.toList()),Function.identity()))
.mutator(MUTATOR)
.mutator());
}

@Test
public void testSetFunctions(){
Evolution<Integer, Integer> ev = Evolution.of(
Population.of(
IntStream.range(0,10)
.boxed()
.collect(Collectors.toList())
,Function.identity()))
.crosser(CROSSER)
.selector(SELECTOR)
.mutator(MUTATOR);
}

}
Original file line number Diff line number Diff line change
@@ -1,47 +1,98 @@
package com.mgiamberardino.jnetic.population;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import com.mgiamberardino.jnetic.population.Population;
import com.mgiamberardino.jnetic.population.Populations;

import junit.framework.TestCase;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class PopulationsTest extends TestCase {
public class PopulationsTest{

private static Random random = new Random(System.currentTimeMillis());
@Rule
public final ExpectedException exception = ExpectedException.none();

@Test
public void testCreateEmptyPopulation() {
Population<Integer> pop = Populations.of(new ArrayList<Integer>());
Population<Integer, Integer> pop = Population.of(new ArrayList<Integer>(), Function.identity());
assertEquals(Integer.valueOf(0), pop.size());
}


@Test
public void testSetAptitudeFunction() {
Population<Integer, Integer> pop = Population.of(new ArrayList<Integer>(), Function.identity())
.aptitudeFunction(Function.identity());
assertEquals(Function.identity(), pop.aptitudeFunction());
}

@Test
public void testCreatePopulationWithSomeMembers() {
Population<Integer> pop = Populations.of(IntStream.of(1, 2, 3, 4).boxed().collect(Collectors.toList()));
Population<Integer, Integer> pop = Population.of(IntStream.of(1, 2, 3, 4).boxed().collect(Collectors.toList()), Function.identity());
assertEquals(Integer.valueOf(4), pop.size());
}


@Test
public void testPopulationGenerator() {
Population<Integer> pop = Populations.generate(() -> new Integer(0), 10);
Population<Integer, Integer> pop = Population.generate(() -> new Integer(0), 10);
assertEquals(Integer.valueOf(10), pop.size());
}


@Test
public void testPopulationGenerateIndivuals() {
Population<ArrayList<Integer>> pop = Populations.generate(PopulationsTest::individualGenerator, 10);
Population<ArrayList<Integer>, Integer> pop = Population.generate(PopulationsTest::individualGenerator, 10);
assertEquals(Integer.valueOf(10), pop.size());
if (! pop.stream().allMatch(i -> null != i)){
fail();
}
}

private static ArrayList<Integer> individualGenerator() {
return IntStream.range(0, 10)
.boxed()
return getRandomStream(10,0,100)
.boxed()
.collect(Collectors.toCollection(ArrayList::new));
}

private static IntStream getRandomStream(int size, int from, int to) {
return random.ints(size, from, to);
}

@Test
public void testSummarizing(){
Population<Integer, Integer> pop = Population.of(IntStream.of(1, 2, 3, 4).boxed().collect(Collectors.toList()), Function.identity());
Integer result = pop.calculateFitness((members) -> members.mapToInt(Integer::intValue).sum(), Function.identity());
assertEquals(new Integer(10), result);
}

@Test(expected=IllegalArgumentException.class)
public void testFitnessParametersFitnessFunctionNull(){
Population<Integer, Integer> pop = Population.of(IntStream.of(1, 2, 3, 4).boxed().collect(Collectors.toList()), Function.identity());
pop.calculateFitness(null, Function.identity());
}

@Test(expected=IllegalArgumentException.class)
public void testFitnessParametersAptitudeFunctionNull(){
Population<Integer, Integer> pop = Population.of(IntStream.of(1, 2, 3, 4).boxed().collect(Collectors.toList()), Function.identity());
pop.calculateFitness((members) -> members.mapToInt(Integer::intValue).sum(), null);
}

public void testEvolvingPopulation(){
Population<ArrayList<Integer>> pop = Populations.generate(PopulationsTest::individualGenerator, 10);
pop.evolve(1);
@Test(expected=IllegalStateException.class)
public void testSummarizingThrowingError(){
Population<Integer, Integer> pop = Population.of(IntStream.of(1, 2, 3, 4).boxed().collect(Collectors.toList()), Function.identity());
pop.calculateFitness((members) -> members.mapToInt(Integer::intValue).sum());
}

@Test
public void testEvolutionFromPopulation(){
Evolution<Integer, Integer> ev = Population.of(IntStream.range(0,10).boxed().collect(Collectors.toList()), Function.identity()).evolution();
assertNotNull(ev);
}

}

0 comments on commit b21e113

Please sign in to comment.