Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Evolutionary Algorithms: How to Go Darwin

Evolutionary Algorithms: How to Go Darwin

Evolutionary Algorithms explained using the Traveling Salesman Problem as a use case, and implemented in Go, with an AngularJs frontend...

Bas W. Knopper

October 08, 2016
Tweet

More Decks by Bas W. Knopper

Other Decks in Technology

Transcript

  1. [email protected] @BWKnopper github.com/bknopper
    Evolutionary Algorithms:
    How to Go Darwin

    View Slide

  2. [email protected] @BWKnopper github.com/bknopper
    2

    View Slide

  3. [email protected] @BWKnopper github.com/bknopper
    3

    View Slide

  4. [email protected] @BWKnopper github.com/bknopper
    4

    View Slide

  5. [email protected] @BWKnopper github.com/bknopper
    Let me introduce myself…
    • Bas W. Knopper
    • Dutch
    • JavaOne, J-Fall, GeeCon, JFokus Speaker
    • AI enthousiast
    • Soft spot for EvolutionaryAlgorithms
    • (Java) Developer
    • Managing Partner @ JCore

    View Slide

  6. [email protected] @BWKnopper github.com/bknopper
    By Developers. For Developers.
    De missie van JCore is om ambitieuze Java Developers een traject te
    bieden waarmee ze sneller en beter Senior Java Developers kunnen
    worden.
    Wat
    (Java Consultancy) ->
    We helpen klanten met het realiseren van
    complexe IT projecten.
    Hoe
    Met ambitieuze en enthousiaste Java
    Consultants die een bijdrage leveren bij de
    klant.
    Waarom
    Vanuit een passie voor IT en het oplossen
    van complexe problemen.

    View Slide

  7. [email protected] @BWKnopper github.com/bknopper
    What I would like to accomplish…
    • Interest
    • Understanding
    • How & when
    • Add to toolbox
    • Attention
    @DevFestNL #EvolutionaryAlgorithms #golang @BWKnopper

    View Slide

  8. [email protected] @BWKnopper github.com/bknopper
    Agenda
    • Introduction
    • NASA
    • Evolution Concepts
    • Puzzle Solving Time: Traveling Salesman Problem
    • Evolutionary Algorithm Design
    • Go Code
    • Demo!
    • Frameworks
    • Checklist

    View Slide

  9. [email protected] @BWKnopper github.com/bknopper
    NASA
    • Space Technology 5 mission
    • launched March 22, 2006, and completed June 20, 2006
    • Three full service 25-kilogram-class spacecraft

    View Slide

  10. [email protected] @BWKnopper github.com/bknopper
    NASA Continued
    • Needs even smaller antenna
    • That still functions according to spec
    • Need forsolution that’s not easy to engineer
    • So they used an EA that made these:

    View Slide

  11. [email protected] @BWKnopper github.com/bknopper

    View Slide

  12. [email protected] @BWKnopper github.com/bknopper
    Recap
    • Powerfulexample
    • First evolved object to travel through space
    • How?

    View Slide

  13. [email protected] @BWKnopper github.com/bknopper
    Evolution

    View Slide

  14. [email protected] @BWKnopper github.com/bknopper
    Evolution - “Survival of the fittest”
    Finite
    Resources
    Lifeforms with
    a basic instinct
    towards
    Reproduction
    Natural
    Selection

    View Slide

  15. [email protected] @BWKnopper github.com/bknopper
    Recombination
    Mutation

    View Slide

  16. [email protected] @BWKnopper github.com/bknopper
    Recombination
    Mutation

    View Slide

  17. [email protected] @BWKnopper github.com/bknopper
    From evolution to problem solving
    Environment Problem
    Individual
    Candidate Solution

    View Slide

  18. [email protected] @BWKnopper github.com/bknopper
    Puzzle solving time!
    • More down to earth example
    • TravellingSalesman Problem

    View Slide

  19. [email protected] @BWKnopper github.com/bknopper
    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…

    View Slide

  20. [email protected] @BWKnopper github.com/bknopper
    Puzzle solving time!
    • More down to earth example
    • TravellingSalesman Problem
    • Use case to show you
    • EvolutionaryAlgorithm Design
    • Plain Go Code
    • Demo

    View Slide

  21. [email protected] @BWKnopper github.com/bknopper
    • No GoPro(pun intended)
    • Big thanks to Rob Brinkman
    • Why then?
    Disclaimer

    View Slide

  22. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;

    View Slide

  23. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;

    View Slide

  24. [email protected] @BWKnopper github.com/bknopper
    Candidate Solution - Representation
    • n = 6
    • Label cities 1,2,3,4,5,6
    • And base city 1
    • Candidate Solution
    • Signifyingthe route
    • for n = 10
    • Enables
    • Calculatingdistance (fitness function)
    • Mutation
    • Recombination
    1
    5
    6
    3
    4
    2
    1
    1
    10
    9
    4
    7
    3
    5
    6
    8
    2
    1

    View Slide

  25. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;

    View Slide

  26. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;
    EVALUATE each candidate;

    View Slide

  27. [email protected] @BWKnopper github.com/bknopper
    Evaluation Function (Fitness Function)
    • Summed distance:
    • d1,2 + d2,4 + … + d5,1
    • Used golang-geofor calculations
    • Minimize!
    1
    5
    6
    3
    4
    2
    1

    View Slide

  28. [email protected] @BWKnopper github.com/bknopper
    /**
    * Calculates the total distance of the whole route
    * and stores it as this candidate solution's fitness
    */
    func (candidateSolution *CandidateSolution) calculateFitness() {
    }

    View Slide

  29. [email protected] @BWKnopper github.com/bknopper
    /**
    * Calculates the total distance of the whole route
    * and stores it as this candidate solution's fitness
    */
    func (candidateSolution *CandidateSolution) calculateFitness() {
    totalDistance := float64(0)
    for i := 0; i < (len(candidateSolution.Route) - 1); i++ {
    }
    candidateSolution.Fitness = totalDistance
    }

    View Slide

  30. [email protected] @BWKnopper github.com/bknopper
    /**
    * Calculates the total distance of the whole route
    * and stores it as this candidate solution's fitness
    */
    func (candidateSolution *CandidateSolution) calculateFitness() {
    totalDistance := float64(0)
    for i := 0; i < (len(candidateSolution.Route) - 1); i++ {
    city := candidateSolution.Route[i]
    nextCity := candidateSolution.Route[i + 1]
    totalDistance += city.calculateDistance(nextCity)
    }
    candidateSolution.Fitness = totalDistance
    }

    View Slide

  31. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;
    EVALUATE each candidate;

    View Slide

  32. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;
    EVALUATE each candidate;
    WHILE ( TERMINATION CONDITION is not satisfied ) {
    }

    View Slide

  33. [email protected] @BWKnopper github.com/bknopper
    Figures from “Introduction toEvolutionary Computing” byA.E. Eiben & J.E. Smith (Springer)
    Termination Condition
    • EA’s are stochastic
    • May never find optimum

    View Slide

  34. [email protected] @BWKnopper github.com/bknopper
    Termination Condition
    • Combination
    • Sure to terminate
    • Time
    • Max number of runs (generations)
    • Goal
    • Fitness threshold
    • Fitness improvementstagnation
    Figure from “Introduction to Evolutionary Computing” by A.E. Eiben & J.E. Smith (Springer)

    View Slide

  35. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;
    EVALUATE each candidate;
    WHILE ( TERMINATION CONDITION is not satisfied ) {
    }

    View Slide

  36. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;
    EVALUATE each candidate;
    WHILE ( TERMINATION CONDITION is not satisfied ) {
    1 SELECT parents;
    }

    View Slide

  37. [email protected] @BWKnopper github.com/bknopper
    Parent Selection
    • Where x is the number of parents:
    • Pick x best
    • Random x
    • Best xout of random y
    • In our example:
    • Best x out of random y

    View Slide

  38. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {

    View Slide

  39. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {
    tempPopulation := make(CandidateSolutions, algorithm.populationSize)
    copy(tempPopulation, algorithm.population)
    randomCandidates := make(CandidateSolutions, algorithm.parentPoolSize)

    View Slide

  40. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {
    tempPopulation := make(CandidateSolutions, algorithm.populationSize)
    copy(tempPopulation, algorithm.population)
    randomCandidates := make(CandidateSolutions, algorithm.parentPoolSize)
    for i := 0; i < algorithm.parentPoolSize; i++ {
    /* pick random candidates */

    View Slide

  41. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {
    tempPopulation := make(CandidateSolutions, algorithm.populationSize)
    copy(tempPopulation, algorithm.population)
    randomCandidates := make(CandidateSolutions, algorithm.parentPoolSize)
    for i := 0; i < algorithm.parentPoolSize; i++ {
    randomIndex := rand.Intn(len(tempPopulation))
    randomCandidateSolution := tempPopulation[randomIndex]

    View Slide

  42. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {
    tempPopulation := make(CandidateSolutions, algorithm.populationSize)
    copy(tempPopulation, algorithm.population)
    randomCandidates := make(CandidateSolutions, algorithm.parentPoolSize)
    for i := 0; i < algorithm.parentPoolSize; i++ {
    randomIndex := rand.Intn(len(tempPopulation))
    randomCandidateSolution := tempPopulation[randomIndex]
    randomCandidates[i] = randomCandidateSolution

    View Slide

  43. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {
    tempPopulation := make(CandidateSolutions, algorithm.populationSize)
    copy(tempPopulation, algorithm.population)
    randomCandidates := make(CandidateSolutions, algorithm.parentPoolSize)
    for i := 0; i < algorithm.parentPoolSize; i++ {
    randomIndex := rand.Intn(len(tempPopulation))
    randomCandidateSolution := tempPopulation[randomIndex]
    randomCandidates[i] = randomCandidateSolution
    /* delete the candidate from the temp population, so we can't pick it again */
    tempPopulation[randomIndex] = tempPopulation[len(tempPopulation)-1]
    tempPopulation = tempPopulation[:len(tempPopulation)-1]
    }

    View Slide

  44. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {
    tempPopulation := make(CandidateSolutions, algorithm.populationSize)
    copy(tempPopulation, algorithm.population)
    randomCandidates := make(CandidateSolutions, algorithm.parentPoolSize)
    for i := 0; i < algorithm.parentPoolSize; i++ {
    randomIndex := rand.Intn(len(tempPopulation))
    randomCandidateSolution := tempPopulation[randomIndex]
    randomCandidates[i] = randomCandidateSolution
    /* delete the candidate from the temp population, so we can't pick it again */
    tempPopulation[randomIndex] = tempPopulation[len(tempPopulation)-1]
    tempPopulation = tempPopulation[:len(tempPopulation)-1]
    }
    /* Sort the population so that the best candidates are up front */
    sort.Sort(randomCandidates)

    View Slide

  45. [email protected] @BWKnopper github.com/bknopper
    func (algorithm *Algorithm) parentSelection() CandidateSolutions {
    tempPopulation := make(CandidateSolutions, algorithm.populationSize)
    copy(tempPopulation, algorithm.population)
    randomCandidates := make(CandidateSolutions, algorithm.parentPoolSize)
    for i := 0; i < algorithm.parentPoolSize; i++ {
    randomIndex := rand.Intn(len(tempPopulation))
    randomCandidateSolution := tempPopulation[randomIndex]
    randomCandidates[i] = randomCandidateSolution
    /* delete the candidate from the temp population, so we can't pick it again */
    tempPopulation[randomIndex] = tempPopulation[len(tempPopulation)-1]
    tempPopulation = tempPopulation[:len(tempPopulation)-1]
    }
    /* Sort the population so that the best candidates are up front */
    sort.Sort(randomCandidates)
    /* return a list with size parentSelectionSize with the best CandidateSolutions */
    return randomCandidates[0:algorithm.parentSelectionSize]
    }

    View Slide

  46. [email protected] @BWKnopper github.com/bknopper
    EA Algorithm (Pseudocode)
    INITIALISE population with random candidate solutions;
    EVALUATE each candidate;
    WHILE ( TERMINATION CONDITION is not satisfied ) {
    1 SELECT parents;
    }

    View Slide

  47. [email protected] @BWKnopper github.com/bknopper
    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;
    }

    View Slide

  48. [email protected] @BWKnopper github.com/bknopper
    Recombination
    • In our example:
    • half-half does not work
    • “Cut-and-crossfill”
    1
    6
    5
    3
    4
    2
    1
    1
    4
    2
    1
    1
    2
    4
    5
    6
    3
    1
    1
    5
    4
    2
    1 1
    3
    5
    4
    2
    1 1
    6
    3
    5
    4
    2
    1 1
    4
    2
    5
    6
    3
    1
    1
    2
    4
    5
    6
    3
    1 1
    2
    4
    5
    6
    3
    1 1
    2
    4
    5
    6
    3
    1

    View Slide

  49. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {

    View Slide

  50. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {
    /* get routes of both parents */
    parentRoute1 := candidateSolution.VisitingCities
    parentRoute2 := otherParent.VisitingCities

    View Slide

  51. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {
    /* get routes of both parents */
    parentRoute1 := candidateSolution.VisitingCities
    parentRoute2 := otherParent.VisitingCities
    /* randomize cutIndex for "cross-and-fill point" */
    cutIndex := int32(rand.Intn(len(parentRoute1)))

    View Slide

  52. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {
    /* get routes of both parents */
    parentRoute1 := candidateSolution.VisitingCities
    parentRoute2 := otherParent.VisitingCities
    /* randomize cutIndex for "cross-and-fill point" */
    cutIndex := int32(rand.Intn(len(parentRoute1)))
    /* initialize the routes for the children */
    childRoute1 := make(Cities, len(parentRoute1))
    childRoute2 := make(Cities, len(parentRoute1))

    View Slide

  53. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {
    /* get routes of both parents */
    parentRoute1 := candidateSolution.VisitingCities
    parentRoute2 := otherParent.VisitingCities
    /* randomize cutIndex for "cross-and-fill point" */
    cutIndex := int32(rand.Intn(len(parentRoute1)))
    /* initialize the routes for the children */
    childRoute1 := make(Cities, len(parentRoute1))
    childRoute2 := make(Cities, len(parentRoute1))
    /* get the first part of both parent routes using the cut index */
    partRoute1 := parentRoute1[0:cutIndex]
    partRoute2 := parentRoute2[0:cutIndex]

    View Slide

  54. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {
    /* get routes of both parents */
    parentRoute1 := candidateSolution.VisitingCities
    parentRoute2 := otherParent.VisitingCities
    /* randomize cutIndex for "cross-and-fill point" */
    cutIndex := int32(rand.Intn(len(parentRoute1)))
    /* initialize the routes for the children */
    childRoute1 := make(Cities, len(parentRoute1))
    childRoute2 := make(Cities, len(parentRoute1))
    /* get the first part of both parent routes using the cut index */
    partRoute1 := parentRoute1[0:cutIndex]
    partRoute2 := parentRoute2[0:cutIndex]
    /* copy the first part of the parents cut into the children */
    copy(childRoute1, partRoute1)
    copy(childRoute2, partRoute2)

    View Slide

  55. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {
    /* get routes of both parents */
    parentRoute1 := candidateSolution.VisitingCities
    parentRoute2 := otherParent.VisitingCities
    /* randomize cutIndex for "cross-and-fill point" */
    cutIndex := int32(rand.Intn(len(parentRoute1)))
    /* initialize the routes for the children */
    childRoute1 := make(Cities, len(parentRoute1))
    childRoute2 := make(Cities, len(parentRoute1))
    /* get the first part of both parent routes using the cut index */
    partRoute1 := parentRoute1[0:cutIndex]
    partRoute2 := parentRoute2[0:cutIndex]
    /* copy the first part of the parents cut into the children */
    copy(childRoute1, partRoute1)
    copy(childRoute2, partRoute2)
    candidateSolution.crossFill(childRoute1, parentRoute2, cutIndex)
    candidateSolution.crossFill(childRoute2, parentRoute1, cutIndex)

    View Slide

  56. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) recombine(otherParent CandidateSolution) CandidateSolutions {
    /* get routes of both parents */
    parentRoute1 := candidateSolution.VisitingCities
    parentRoute2 := otherParent.VisitingCities
    /* randomize cutIndex for "cross-and-fill point" */
    cutIndex := int32(rand.Intn(len(parentRoute1)))
    /* initialize the routes for the children */
    childRoute1 := make(Cities, len(parentRoute1))
    childRoute2 := make(Cities, len(parentRoute1))
    /* get the first part of both parent routes using the cut index */
    partRoute1 := parentRoute1[0:cutIndex]
    partRoute2 := parentRoute2[0:cutIndex]
    /* copy the first part of the parents cut into the children */
    copy(childRoute1, partRoute1)
    copy(childRoute2, partRoute2)
    candidateSolution.crossFill(childRoute1, parentRoute2, cutIndex)
    candidateSolution.crossFill(childRoute2, parentRoute1, cutIndex)
    /* create new children using the new children routes */
    child1 := NewCandidateSolution(getBaseCity(), childRoute1);
    child2 := NewCandidateSolution(getBaseCity(), childRoute2);
    /* put the children in a list and return it */
    return CandidateSolutions{child1, child2}
    }

    View Slide

  57. [email protected] @BWKnopper github.com/bknopper
    /**
    * 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)
    */
    func (candidateSolution *CandidateSolution) crossFill(childRoute Cities, parentRoute []City, cutIndex int32) {

    View Slide

  58. [email protected] @BWKnopper github.com/bknopper
    /**
    * 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)
    */
    func (candidateSolution *CandidateSolution) crossFill(childRoute Cities, parentRoute []City, cutIndex int32) {
    /*
    * traverse the parent route from the cut index on and add every city
    * not yet in the child to the child
    */
    childRouteIndex := cutIndex
    for i := cutIndex; i < int32(len(parentRoute)); i++ {
    nextCityOnRoute := parentRoute[i]
    if (!childRoute.contains(nextCityOnRoute)) {
    childRoute[childRouteIndex] = nextCityOnRoute
    childRouteIndex++
    }
    }
    1
    4
    2
    5
    6
    3
    1

    View Slide

  59. [email protected] @BWKnopper github.com/bknopper
    /**
    * 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)
    */
    func (candidateSolution *CandidateSolution) crossFill(childRoute Cities, parentRoute []City, cutIndex int32) {
    /*
    * traverse the parent route from the cut index on and add every city
    * not yet in the child to the child
    */
    childRouteIndex := cutIndex
    for i := cutIndex; i < int32(len(parentRoute)); i++ {
    nextCityOnRoute := parentRoute[i]
    if (!childRoute.contains(nextCityOnRoute)) {
    childRoute[childRouteIndex] = nextCityOnRoute
    childRouteIndex++
    }
    }
    /*
    * traverse the parent route from the start of the route and add every
    * city not yet in the child to the child
    */
    for i := 0; i < int(cutIndex); i++ {
    nextCityOnRoute := parentRoute[i]
    if (!childRoute.contains(nextCityOnRoute)) {
    childRoute[childRouteIndex] = nextCityOnRoute
    childRouteIndex++
    }
    }
    }
    1
    4
    2
    5
    6
    3
    1
    1
    4
    2
    5
    6
    3
    1

    View Slide

  60. [email protected] @BWKnopper github.com/bknopper
    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;
    }

    View Slide

  61. [email protected] @BWKnopper github.com/bknopper
    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;
    }

    View Slide

  62. [email protected] @BWKnopper github.com/bknopper
    1
    6
    5
    3
    4
    2
    1
    Mutation
    • Change of nr won’t work
    • Infeasiblecandidate solution
    • Swap to the rescue!
    1
    6
    5
    3
    4
    2
    1 1
    2
    5
    3
    4
    6
    1

    View Slide

  63. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) mutate() {
    1
    6
    5
    3
    4
    2
    1

    View Slide

  64. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) mutate() {
    /* randomly select two indices in the route */
    indexFirstCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    indexSecondCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    1
    6
    5
    3
    4
    2
    1
    1
    6
    5
    3
    4
    2
    1

    View Slide

  65. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) mutate() {
    /* randomly select two indices in the route */
    indexFirstCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    indexSecondCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    /* Make sure they are different */
    for (indexFirstCity == indexSecondCity) {
    indexSecondCity = int32(rand.Intn(len(candidateSolution.VisitingCities)))
    }
    1
    6
    5
    3
    4
    2
    1
    1
    6
    5
    3
    4
    2
    1

    View Slide

  66. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) mutate() {
    /* randomly select two indices in the route */
    indexFirstCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    indexSecondCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    /* Make sure they are different */
    for (indexFirstCity == indexSecondCity) {
    indexSecondCity = int32(rand.Intn(len(candidateSolution.VisitingCities)))
    }
    /* Retrieve the cities */
    firstCity := candidateSolution.VisitingCities[indexFirstCity]
    secondCity := candidateSolution.VisitingCities[indexSecondCity]
    1
    6
    5
    3
    4
    2
    1
    1
    6
    5
    3
    4
    2
    1

    View Slide

  67. [email protected] @BWKnopper github.com/bknopper
    func (candidateSolution *CandidateSolution) mutate() {
    /* randomly select two indices in the route */
    indexFirstCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    indexSecondCity := int32(rand.Intn(len(candidateSolution.VisitingCities)))
    /* Make sure they are different */
    for (indexFirstCity == indexSecondCity) {
    indexSecondCity = int32(rand.Intn(len(candidateSolution.VisitingCities)))
    }
    /* Retrieve the cities */
    firstCity := candidateSolution.VisitingCities[indexFirstCity]
    secondCity := candidateSolution.VisitingCities[indexSecondCity]
    /* Changer! */
    candidateSolution.VisitingCities[indexFirstCity] = secondCity
    candidateSolution.VisitingCities[indexFirstCity] = firstCity
    }
    1
    2
    5
    3
    4
    6
    1
    1
    6
    5
    3
    4
    2
    1
    1
    6
    5
    3
    4
    2
    1

    View Slide

  68. [email protected] @BWKnopper github.com/bknopper
    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;
    }

    View Slide

  69. [email protected] @BWKnopper github.com/bknopper
    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;
    }

    View Slide

  70. [email protected] @BWKnopper github.com/bknopper
    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;
    }

    View Slide

  71. [email protected] @BWKnopper github.com/bknopper
    Survivor Selection
    • Replacement Strategy
    • Do nothing
    • Replace Worst

    View Slide

  72. [email protected] @BWKnopper github.com/bknopper
    /**
    * Selects the survivors by removing the worst candidate
    * solutions from the list, so we have the original
    * population size again
    */
    func (algorithm *Algorithm) selectSurvivors() {
    }

    View Slide

  73. [email protected] @BWKnopper github.com/bknopper
    /**
    * Selects the survivors by removing the worst candidate
    * solutions from the list, so we have the original
    * population size again
    */
    func (algorithm *Algorithm) selectSurvivors() {
    sort.Sort(algorithm.population)
    }

    View Slide

  74. [email protected] @BWKnopper github.com/bknopper
    /**
    * Selects the survivors by removing the worst candidate
    * solutions from the list, so we have the original
    * population size again
    */
    func (algorithm *Algorithm) selectSurvivors() {
    sort.Sort(algorithm.population)
    algorithm.population = algorithm.population[:algorithm.populationSize]
    }

    View Slide

  75. [email protected] @BWKnopper github.com/bknopper
    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;
    }

    View Slide

  76. [email protected] @BWKnopper github.com/bknopper
    Tuning…
    • Mutation probability
    • Population size
    • Nr of offspring
    • Termination condition (# runs or fitness)
    • Parent selection
    • Survival selection
    • Initialisation
    • Random

    View Slide

  77. [email protected] @BWKnopper github.com/bknopper
    EA Behavior
    Figures from “Introduction to Evolutionary Computing” by A.E. Eiben & J.E. Smith (Springer)

    View Slide

  78. [email protected] @BWKnopper github.com/bknopper
    Demo!
    https://github.com/bknopper/TSPEvolutionaryAlgorithmsDemo.git

    View Slide

  79. [email protected] @BWKnopper github.com/bknopper
    With great power comes great responsibility
    • I’m sure I cannot find a solution using a brute-force approach?
    • (within a reasonable amountof time)
    • Am I facing an optimization or search problem?
    • Can I encode a candidate solution to the problem?
    • Representationpossible?
    • Can I determine the fitness of a candidate solution?

    View Slide

  80. [email protected] @BWKnopper github.com/bknopper
    Literature

    View Slide

  81. [email protected] @BWKnopper github.com/bknopper

    View Slide

  82. [email protected] @BWKnopper github.com/bknopper
    Additional questions?
    • Contact me on @BWKnopper
    • Google it!
    • There’slotstofind…
    • Papers
    • Demo’s

    View Slide

  83. [email protected] @BWKnopper github.com/bknopper
    Slide 83 of 68

    View Slide

  84. [email protected] @BWKnopper github.com/bknopper

    View Slide