Java Developers sometimes face programming challenges, such as creating a school roster or determining a salesperson’s optimal route, that are extremely difficult to crack using conventional approaches. Discover how Evolutionary Algorithms can be applied to solve these complex puzzles. The session starts with a success story from the NASA space archives to explain the concepts. Once the stage is set, it’s puzzle solving time! Learn to code Evolutionary Algorithms using plain Java - although existing Java frameworks such as JGAP are also addressed. The session concludes with a checklist that can be used to determine whether Evolutionary Algorithms are a good fit to the problem. With this checklist, the decision has never been easier!
5. Let me introduce myself…
• Bas W. Knopper
• Dutch
• Java Developer
• NCIM (IT Services Company)
• 10 years Java exp
• JavaOne 2013 Speaker
• AI enthousiast
• Soft spot for Evolutionary Algorithms
Slide 5 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
6. Questions
• A lot of ground to cover in 45 mins.
• Ask questions anytime!
• But don’t take it personal if I have to move on…
• We’ll discuss it over a <insert beverage of choice>!
• If time permits it
• Question round at the end as well
Slide 6 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
7. What I would like to accomplish…
• Interest
• Understanding
• How & when
• Add to toolbox
• Attention
#jfall #EvolutionaryAlgorithms @BWKnopper
Slide 7 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
8. NASA
• Space Technology 5 mission
• launched March 22, 2006, and completed June 20, 2006
• Three full service 25-kilogram-class spacecraft
Slide 8 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
9. NASA Continued
• Needs even smaller antenna
• That still functions according to spec
• Need for solution that’s not easy to engineer
• So they used an EA that made these:
Slide 9 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
10. Slide 10 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
11. Recap
• Powerful example
• Evolving object
• First evolved object to travel through space
• How?
Slide 11 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
12. Evolution - “Survival of the fittest”
Finite
Resources
Lifeforms
with a basic
instinct
towards
Reproduction
Natural
Selection
Slide 12 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
15. From evolution to problem solving
Environment Problem
Individual
Slide 15 of 68
Candidate Solution
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
16. Puzzle solving time!
• More down to earth example
• Travelling Salesman Problem
Slide 16 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
17. Travelling Salesman Problem
• Given n cities
• n = number of cities to visit
• Find (optimal) route for visiting all cities
• Visit every city only once
• Return to origin city
• Search space is huge
• For 30 cities there are 30! 10^32 possible routes
That’s 100.000.000.000.000.000.000.000.000.000.000 possible routes!
Brute force might not be the best solution…
Slide 17 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
18. Puzzle solving time!
• More down to earth example
• Travelling Salesman Problem
• Use case to show you
• Evolutionary Algorithm Design
• Plain Java Code
• Demo
Slide 18 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
19. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 19 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
20. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 20 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
21. Candidate Solution - Representation
• n = 6
• Label cities 1,2,3,4,5,6
• And base city 1
• Candidate Solution
• Signifying the route
• for n = 10
• Enables
1 2 4 3 6 5 1
1 2 8 6 5 3 7 4 9 10 1
• Calculating distance (fitness function)
• Mutation
• Recombination
Slide 21 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
22. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 22 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
23. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 23 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
25. /**
* Calculates the total distance of the whole route and stores it as this
* candidate solution's fitness
*/
private void calculateFitness() {
/* initialize total distance */
double totalDistance = 0;
/*
* For all Cities in the route (except the last one) get the distance between this
* City and the next and add it to the totalDistance
*/
for (int i = 0; i < route.size() - 1; i++) {
City city = route.get(i);
City nextCity = route.get(i + 1);
totalDistance += city.calculateDistance(nextCity);
}
/* store totalDistance as this candidate solution's fitness */
this.fitness = totalDistance;
}
Slide 25 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
26. /**
* Calculates the total distance of the whole route and stores it as this
* candidate solution's fitness
*/
private void calculateFitness() {
/* initialize total distance */
double totalDistance = 0;
/*
* For all Cities in the route (except the last one) get the distance between this
* City and the next and add it to the totalDistance
*/
for (int i = 0; i < route.size() - 1; i++) {
}
/* store totalDistance as this candidate solution's fitness */
this.fitness = totalDistance;
}
Slide 26 of 68
City city = route.get(i);
City nextCity = route.get(i + 1);
totalDistance += city.calculateDistance(nextCity);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
27. /**
* Calculates the total distance of the whole route and stores it as this
* candidate solution's fitness
*/
private void calculateFitness() {
/* initialize total distance */
double totalDistance = 0;
/*
* For all Cities in the route (except the last one) get the distance between this
* City and the next and add it to the totalDistance
*/
for (int i = 0; i < route.size() - 1; i++) {
}
/* store totalDistance as this candidate solution's fitness */
this.fitness = totalDistance;
}
Slide 27 of 68
City city = route.get(i);
City nextCity = route.get(i + 1);
totalDistance += city.calculateDistance(nextCity);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
28. /**
* Calculates the total distance of the whole route and stores it as this
* candidate solution's fitness
*/
private void calculateFitness() {
/* initialize total distance */
double totalDistance = 0;
/*
* For all Cities in the route (except the last one) get the distance between this
* City and the next and add it to the totalDistance
*/
for (int i = 0; i < route.size() - 1; i++) {
}
/* store totalDistance as this candidate solution's fitness */
this.fitness = totalDistance;
}
Slide 28 of 68
City city = route.get(i);
City nextCity = route.get(i + 1);
totalDistance += city.calculateDistance(nextCity);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
29. /**
* Calculates the total distance of the whole route and stores it as this
* candidate solution's fitness
*/
private void calculateFitness() {
/* initialize total distance */
double totalDistance = 0;
/*
* For all Cities in the route (except the last one) get the distance between this
* City and the next and add it to the totalDistance
*/
for (int i = 0; i < route.size() - 1; i++) {
}
/* store totalDistance as this candidate solution's fitness */
this.fitness = totalDistance;
}
Slide 29 of 68
City city = route.get(i);
City nextCity = route.get(i + 1);
totalDistance += city.calculateDistance(nextCity);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
30. /**
* Calculates the total distance of the whole route and stores it as this
* candidate solution's fitness
*/
private void calculateFitness() {
/* initialize total distance */
double totalDistance = 0;
/*
* For all Cities in the route (except the last one) get the distance between this
* City and the next and add it to the totalDistance
*/
for (int i = 0; i < route.size() - 1; i++) {
}
/* store totalDistance as this candidate solution's fitness */
this.fitness = totalDistance;
}
Slide 30 of 68
City city = route.get(i);
City nextCity = route.get(i + 1);
totalDistance += city.calculateDistance(nextCity);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
31. /**
* Calculates the total distance of the whole route and stores it as this
* candidate solution's fitness
*/
private void calculateFitness() {
/* initialize total distance */
double totalDistance = 0;
/*
* For all Cities in the route (except the last one) get the distance between this
* City and the next and add it to the totalDistance
*/
for (int i = 0; i < route.size() - 1; i++) {
}
/* store totalDistance as this candidate solution's fitness */
this.fitness = totalDistance;
}
Slide 31 of 68
City city = route.get(i);
City nextCity = route.get(i + 1);
totalDistance += city.calculateDistance(nextCity);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
32. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 32 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
33. Termination Condition
• EA’s are stochastic
• May never find optimum
• Combination
• Time
• Max number of runs (generations)
• Sure to terminate
• Either:
• Fitness threshold
• Fitness improvement remains under a threshold over runs
Slide 33 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
34. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 34 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
35. Parent Selection
• Where x is the number of parents:
• Pick x best
• Random x
• Best x out of random y
• In our example:
• Best x out of random y
Slide 35 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
36. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
Slide 36 of 68
37. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
Slide 37 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
38. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
Slide 38 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
39. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
Slide 39 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
40. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
Slide 40 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
41. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
Slide 41 of 68
42. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
Slide 42 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
43. private List<CandidateSolution> parentSelection() {
List<CandidateSolution> tempPopulation = new ArrayList<>(population);
List<CandidateSolution> randomCandidates = new ArrayList<>();
/* create parent pool */
for(int i = 0; i < parentPoolSize; i++)
{
/* select a random candidate solution from the temp population */
int randomlySelectedIndex = random.nextInt(tempPopulation.size());
CandidateSolution randomSelection = tempPopulation.get(randomlySelectedIndex);
randomCandidates.add(randomSelection);
/* delete the candidate from the temp population, so we can't pick it again */
tempPopulation.remove(randomlySelectedIndex);
}
/* Sort the population so that the best candidates are up front */
Collections.sort(randomCandidates);
/* return a list with size parentSelectionSize with the best CandidateSolutions */
return randomCandidates.subList(0, parentSelectionSize);
Slide 43 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
44. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 44 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
45. Recombination
• In our example:
• half-half does not work
• “Cut-and-crossfill”
1 2 4 3 5 6 1
1 3 6 5 4 2 1
1 2 4 5 3 6 1
1 3 6 5 2 4 1
Slide 45 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
46. public List<CandidateSolution> recombine(CandidateSolution otherParent) {
/* get routes of both parents */
List<City> parentRoute1 = getRoute();
List<City> parentRoute2 = otherParent.getRoute();
/* initialize the routes for the children */
List<City> childRoute1 = new ArrayList<City>();
List<City> childRoute2 = new ArrayList<City>();
/* randomize cutIndex for "cross-and-fill point" */
int cutIndex = new Random().nextInt(parentRoute1.size());
/* copy the first part of the parents cut into the children */
childRoute1.addAll(parentRoute1.subList(0, cutIndex));
childRoute2.addAll(parentRoute2.subList(0, cutIndex));
/* perform crossfill for both children */
crossFill(childRoute1, parentRoute2, cutIndex);
crossFill(childRoute2, parentRoute1, cutIndex);
/* create new children using the new children routes */
CandidateSolution child1 = new CandidateSolution(childRoute1);
CandidateSolution child2 = new CandidateSolution(childRoute2);
/* put the children in a list and return it (omitted for layout reasons) */
}
Slide 46 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
47. public List<CandidateSolution> recombine(CandidateSolution otherParent) {
/* get routes of both parents */
List<City> parentRoute1 = getRoute();
List<City> parentRoute2 = otherParent.getRoute();
/* initialize the routes for the children */
List<City> childRoute1 = new ArrayList<City>();
List<City> childRoute2 = new ArrayList<City>();
/* randomize cutIndex for "cross-and-fill point" */
int cutIndex = new Random().nextInt(parentRoute1.size());
/* copy the first part of the parents cut into the children */
childRoute1.addAll(parentRoute1.subList(0, cutIndex));
childRoute2.addAll(parentRoute2.subList(0, cutIndex));
/* perform crossfill for both children */
crossFill(childRoute1, parentRoute2, cutIndex);
crossFill(childRoute2, parentRoute1, cutIndex);
/* create new children using the new children routes */
CandidateSolution child1 = new CandidateSolution(childRoute1);
CandidateSolution child2 = new CandidateSolution(childRoute2);
/* put the children in a list and return it (omitted for layout reasons) */
}
Slide 47 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
48. public List<CandidateSolution> recombine(CandidateSolution otherParent) {
/* get routes of both parents */
List<City> parentRoute1 = getRoute();
List<City> parentRoute2 = otherParent.getRoute();
/* initialize the routes for the children */
List<City> childRoute1 = new ArrayList<City>();
List<City> childRoute2 = new ArrayList<City>();
/* randomize cutIndex for "cross-and-fill point" */
int cutIndex = new Random().nextInt(parentRoute1.size());
/* copy the first part of the parents cut into the children */
childRoute1.addAll(parentRoute1.subList(0, cutIndex));
childRoute2.addAll(parentRoute2.subList(0, cutIndex));
/* perform crossfill for both children */
crossFill(childRoute1, parentRoute2, cutIndex);
crossFill(childRoute2, parentRoute1, cutIndex);
/* create new children using the new children routes */
CandidateSolution child1 = new CandidateSolution(childRoute1);
CandidateSolution child2 = new CandidateSolution(childRoute2);
/* put the children in a list and return it (omitted for layout reasons) */
}
Slide 48 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
49. public List<CandidateSolution> recombine(CandidateSolution otherParent) {
/* get routes of both parents */
List<City> parentRoute1 = getRoute();
List<City> parentRoute2 = otherParent.getRoute();
/* initialize the routes for the children */
List<City> childRoute1 = new ArrayList<City>();
List<City> childRoute2 = new ArrayList<City>();
/* randomize cutIndex for "cross-and-fill point" */
int cutIndex = new Random().nextInt(parentRoute1.size());
/* copy the first part of the parents cut into the children */
childRoute1.addAll(parentRoute1.subList(0, cutIndex));
childRoute2.addAll(parentRoute2.subList(0, cutIndex));
/* perform crossfill for both children */
crossFill(childRoute1, parentRoute2, cutIndex);
crossFill(childRoute2, parentRoute1, cutIndex);
/* create new children using the new children routes */
CandidateSolution child1 = new CandidateSolution(childRoute1);
CandidateSolution child2 = new CandidateSolution(childRoute2);
/* put the children in a list and return it (omitted for layout reasons) */
}
Slide 49 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
50. public List<CandidateSolution> recombine(CandidateSolution otherParent) {
/* get routes of both parents */
List<City> parentRoute1 = getRoute();
List<City> parentRoute2 = otherParent.getRoute();
/* initialize the routes for the children */
List<City> childRoute1 = new ArrayList<City>();
List<City> childRoute2 = new ArrayList<City>();
/* randomize cutIndex for "cross-and-fill point" */
int cutIndex = new Random().nextInt(parentRoute1.size());
/* copy the first part of the parents cut into the children */
childRoute1.addAll(parentRoute1.subList(0, cutIndex));
childRoute2.addAll(parentRoute2.subList(0, cutIndex));
/* perform crossfill for both children */
crossFill(childRoute1, parentRoute2, cutIndex);
crossFill(childRoute2, parentRoute1, cutIndex);
/* create new children using the new children routes */
CandidateSolution child1 = new CandidateSolution(childRoute1);
CandidateSolution child2 = new CandidateSolution(childRoute2);
/* put the children in a list and return it (omitted for layout reasons) */
}
Slide 50 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
51. public List<CandidateSolution> recombine(CandidateSolution otherParent) {
/* get routes of both parents */
List<City> parentRoute1 = getRoute();
List<City> parentRoute2 = otherParent.getRoute();
/* initialize the routes for the children */
List<City> childRoute1 = new ArrayList<City>();
List<City> childRoute2 = new ArrayList<City>();
/* randomize cutIndex for "cross-and-fill point" */
int cutIndex = new Random().nextInt(parentRoute1.size());
/* copy the first part of the parents cut into the children */
childRoute1.addAll(parentRoute1.subList(0, cutIndex));
childRoute2.addAll(parentRoute2.subList(0, cutIndex));
/* perform crossfill for both children */
crossFill(childRoute1, parentRoute2, cutIndex);
crossFill(childRoute2, parentRoute1, cutIndex);
/* create new children using the new children routes */
CandidateSolution child1 = new CandidateSolution(childRoute1);
CandidateSolution child2 = new CandidateSolution(childRoute2);
/* put the children in a list and return it (omitted for layout reasons) */
}
Slide 51 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
52. /**
* Check the rest of the route in the crossing parent and add the cities
* that are not yet in the child (in the order of the route of the crossing
* parent)
*/
private void crossFill(List<City> childRoute, List<City> parentRoute, int cutIndex) {
/* traverse the parent route from the cut index on and add every city not yet in the child to the child */
for (int i = cutIndex; i < parentRoute.size(); i++) {
City nextCityOnRoute = parentRoute.get(i);
if (!childRoute.contains(nextCityOnRoute)) {
childRoute.add(nextCityOnRoute);
}
}
/* traverse the parent route from the start of the route and add every city not yet in the child to the child */
for (int i = 0; i < cutIndex; i++) {
City nextCityOnRoute = parentRoute.get(i);
if (!childRoute.contains(nextCityOnRoute)) {
}
}
Slide 52 of 68
1 3 6 5 2 4 1
1 3 6 5 2 4 1
childRoute.add(nextCityOnRoute);
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
}
53. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 53 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
54. Mutation
• Change of nr won’t work
• Infeasible candidate solution
• Swap to the rescue!
1 26 2 4 3 5 6 26 1
Slide 54 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
55. /**
* Mutates the current individual by swapping two random cities in its
* route.
*/
public void mutate() { 1 2 4 3 5 6 1
Random random = new Random();
/* randomly select two indices in the route */
int indexFirstCity = random.nextInt(route.size());
int indexSecondCity = random.nextInt(route.size());
/* Make sure they are different */
while (indexFirstCity == indexSecondCity) {
}
/* retrieve the Cities on the given indices */
City firstCity = route.get(indexFirstCity);
City secondCity = route.get(indexSecondCity);
/* Changer! */
route.set(indexFirstCity, secondCity);
route.set(indexSecondCity, firstCity);
}
Slide 55 of 68
1 2 4 3 5 6 1
1 6 4 3 5 2 1
indexSecondCity = random.nextInt(route.size());
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
56. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 56 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
57. EA Algorithm (Pseudocode)
INITIALISE population with random candidate solutions;
EVALUATE each candidate;
WHILE ( TERMINATION CONDITION is not satisfied ) {
1 SELECT parents;
2 RECOMBINE pairs of parents;
3 MUTATE the resulting offspring;
4 EVALUATE new candidates;
5 SELECT individuals for the next generation;
}
Slide 57 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
58. Survivor Selection
• Replacement Strategy
• ReplaceWorst
Slide 58 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
59. /**
* Selects the survivors by removing the worst candidate
* solutions from the list, so we have the original
* population size again
*/
private void selectSurvivors() {
Collections.sort(population);
population = population.subList(0, populationSize);
}
Slide 59 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
60. Tuning…
• Mutation probability
• Population size
• Nr of offspring
• Termination condition (# runs or fitness)
• Parent selection
• Survival selection
• Initialisation
• Random
Slide 60 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
61. EA Behavior
Figures from “Introduction to Evolutionary Computing” by A.E. Eiben & J.E. Smith (Springer)
Slide 61 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
62. Demo!
• Used NASA World Wind to map route on
• https://github.com/bknopper/TSPEvolutionaryAlgorithmsDemo.git
Slide 62 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
63. Java Frameworks & API’s
http://watchmaker.uncommons.org http://jgap.sourceforge.net/
Slide 63 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
65. With great power comes great responsibility
• Can I find a solution using a brute-force approach?
• (within a reasonable amount of time)
• Am I facing an optimization or search problem?
• Can I encode a candidate solution to the problem?
• Representation possible?
• Can I determine the fitness of a candidate solution?
Slide 65 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
66. “A wise man can learn more from a foolish question
than a fool can learn from a wise answer”
– Bruce Lee
Slide 66 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
67. Additional questions?
• Contact me on @BWKnopper
• Google it!
• There’s lots to find…
• Papers
• Demo’s
• Aforementioned Frameworks/API’s
Slide 67 of 68
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
68. Thank you.
That’s all folks!
Slide 68 of 68
Have a great day at J-Fall!
b.knopper@ncim.nl @BWKnopper github.com/bknopper Passion for Technology
Editor's Notes
Aan het eind: Imagine this going on for a while. There could be individuals that have a great fitness because of traits we didn’t even know could exist. This is impossible to simulate in real life. A computer though… 10000 generations in a few hours is not so hard… Which brings us to Evolutionary Algorithms
Aan het eind: Imagine this going on for a while. There could be individuals that have a great fitness because of traits we didn’t even know could exist. This is impossible to simulate in real life. A computer though… 10000 generations in a few hours is not so hard… Which brings us to Evolutionary Algorithms