Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

67
Passion for Technology [email protected] @BWKnopper EVOLUTIONARY ALGORITHMS The key to solving complex Java puzzles JavaOne [BOF2913] #javaone #EvolutionaryAlgorithms @

description

JavaOne presentation on Evolutionary Algorithms. The abstract of the presentation: 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 with conventional approaches. Discover how evolutionary algorithms can be applied to solve such complex puzzles. This 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 how to code evolutionary algorithms by using plain Java—although existing Java frameworks such as JGAP are also addressed. The session concludes with a checklist for determining whether evolutionary algorithms are a good fit for any particular problem. With this checklist, the decision has never been easier!

Transcript of Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Page 1: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

EVOLUTIONARY ALGORITHMSThe key to solving complex Java puzzles

JavaOne [BOF2913]

#javaone #EvolutionaryAlgorithms @BWKnopper

Page 2: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Let me introduce myself…

• Bas W. Knopper• Dutch• Java Developer • NCIM (IT Services Company)• 9 years Java exp

• AI enthousiast• Soft spot for Evolutionary Algorithms

Slide 2 of 68

Page 3: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 3 of 68

Page 4: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

What I would like to accomplish…

• Interest• Understanding• How & when• Add to toolbox

Slide 4 of 68

Page 5: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

NASA

• Space Technology 5 mission• launched March 22, 2006, and completed June 20, 2006

• Three full service 25-kilogram-class spacecraft

Slide 5 of 68

Page 6: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 6 of 68

Page 7: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Slide 7 of 68

Page 8: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Recap

• Powerful example• Evolving object• First evolved object to fly in space

• How?

Slide 8 of 68

Page 9: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Evolution - “Survival of the fittest”

Finite Resources

Lifeforms with a basic

instinct towards

Reproduction

Natural Selection

Slide 9 of 68

Page 10: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Recombination

Mutation

Slide 10 of 68

Page 11: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Recombination

Mutation

Slide 11 of 68

Page 12: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

From evolution to problem solvingEnvironment Problem

Individual Candidate Solution

Slide 12 of 68

Page 13: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Puzzle solving time!

• More down to earth example• Travelling Salesman Problem

Slide 13 of 68

Page 14: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 14 of 68

Page 15: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Puzzle solving time!

• More down to earth example• Travelling Salesman Problem

• Use case to show you• Evolutionary Algorithm Design• Plain Java Code• Demo

Slide 15 of 68

Page 16: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Different EA’s

• Genetic Algorithms (GA’s)• Evolution Strategies (ES’s)• Evolutionary Programming (EP)• Genetic Programming (GP)

• All have the same basis

Slide 16 of 68

Page 17: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 17 of 68

Page 18: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 18 of 68

Page 19: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Candidate Solution - Representation

• n = 6• And base city 1

• Label cities 1,2,3,4,5,6

• Candidate Solution • Signifying the route

• for n = 10

1563421

110947356821

Slide 19 of 68

Page 20: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Recombination

Mutation

1653421 1653421

1653421

1653421

1653421

Slide 20 of 68

Page 21: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 21 of 68

Page 22: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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

Page 23: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Evaluation Function (Fitness Function)

• Summed distance:• d1,2 + d2,4 + … + d5,1

• Minimize!

1563421

Slide 23 of 68

Page 24: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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 24 of 68

Page 25: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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

Page 26: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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 26 of 68

Page 27: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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 27 of 68

Page 28: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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 28 of 68

Page 29: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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 29 of 68

Page 30: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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 30 of 68

Page 31: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 31 of 68

Page 32: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Termination Condition

• EA’s are stochastic• May never find optimum

• Combination • Max number of runs (generations)• Sure to terminate

• Either: • Fitness threshold• Fitness improvement remains under a threshold over runs• Population diversity drops under a certain threshold

Slide 32 of 68

Page 33: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 33 of 68

Page 34: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 34 of 68

Page 35: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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 35 of 68

Page 36: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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 36 of 68

Page 37: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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

Page 38: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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

Page 39: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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

Page 40: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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

Page 41: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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 41 of 68

Page 42: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

private List<CandidateSolution> parentSelection() {

List<CandidateSolution> tempPopulation = new ArrayList<CandidateSolution>(population); List<CandidateSolution> randomCandidates = new ArrayList<CandidateSolution>();

/* 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

Page 43: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 43 of 68

Page 44: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Recombination

• In our example: • half-half does not work• “Cut-and-crossfill”

1653421

1421

1245631

15421 135421 1635421 1425631

1245631 1245631 1245631

Slide 44 of 68

Page 45: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 45 of 68

Page 46: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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

Page 47: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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

Page 48: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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

Page 49: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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

Page 50: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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

Page 51: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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)) { childRoute.add(nextCityOnRoute); } }}

1425631

1425631

Slide 51 of 68

Page 52: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 52 of 68

Page 53: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

1653421

Mutation

• Change of nr won’t work • Infeasible candidate solution

• Swap to the rescue!

1653421 1253461

Slide 53 of 68

Page 54: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * Mutates the current individual by swapping two random cities in its * route. */public void mutate() { 1653421

1653421

1253461

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) { indexSecondCity = random.nextInt(route.size()); }

/* 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 54 of 68

Page 55: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 55 of 68

Page 56: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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

Page 57: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Survivor Selection

• Replacement Strategy• Replace Worst

Slide 57 of 68

Page 58: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

/** * 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 58 of 68

Page 59: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Tuning…

• Mutation probability• Population size• Nr of offspring• Termination condition (# runs or fitness)• Parent selection• Survival selection• Initialisation• Random

Slide 59 of 68

Page 60: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

EA Behavior

Figures from “Introduction to Evolutionary Computing” by A.E. Eiben & J.E. Smith (Springer)

Slide 60 of 68

Page 61: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Demo!

• Used NASA World Wind to map route on

• https://github.com/ncim-tsp/JavaOneTSP.git

Slide 61 of 68

Page 62: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Java Frameworks & API’s

http://jgap.sourceforge.net/http://watchmaker.uncommons.org

Slide 62 of 68

Page 63: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Java Frameworks & API’s

• ECJ• http://cs.gmu.edu/~eclab/projects/ecj/

• MOEA Framework• http://www.moeaframework.org

• JEAF• https://github.com/GII/JEAF

• …

Slide 63 of 68

Page 64: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

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 64 of 68

Page 65: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

than a fool can learn from a wise answer”

– Bruce Lee

“A wise man can learn more from a foolish question

Slide 65 of 68

Page 66: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Additional questions?

• Contact me on @BWKnopper• Google it!• There’s lots to find…• Papers• Demo’s• Aforementioned Frameworks/API’s

Slide 66 of 68

Page 67: Evolutionary Algorithms: The Key to Solving Complex Java Puzzles

Passion for [email protected] @BWKnopper

Have a great week @JavaOne

That’s all folks!

Thank you.

Slide 67 of 68