-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
In this commit the solution has evolved to improve the interface:
- 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
Showing
7 changed files
with
266 additions
and
59 deletions.
There are no files selected for viewing
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
This file was deleted.
Oops, something went wrong.
53 changes: 53 additions & 0 deletions
53
src/main/java/com/mgiamberardino/jnetic/population/Evolution.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,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
64
src/main/java/com/mgiamberardino/jnetic/population/Population.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 |
---|---|---|
@@ -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; | ||
} | ||
} |
21 changes: 0 additions & 21 deletions
21
src/main/java/com/mgiamberardino/jnetic/population/Populations.java
This file was deleted.
Oops, something went wrong.
67 changes: 67 additions & 0 deletions
67
src/test/java/com/mgiamberardino/jnetic/population/EvolutionTest.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,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); | ||
} | ||
|
||
} |
85 changes: 68 additions & 17 deletions
85
src/test/java/com/mgiamberardino/jnetic/population/PopulationsTest.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 |
---|---|---|
@@ -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); | ||
} | ||
|
||
} |