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.
• 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…
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 }
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)
:= 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] }
:= 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)
:= 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] }
/* 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 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]
/* 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)
/* 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)
/* 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} }
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) {
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
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
candidate solutions; EVALUATE each candidate; WHILE ( TERMINATION CONDITION is not satisfied ) { 1 SELECT parents; 2 RECOMBINE pairs of parents; 3 MUTATE the resulting offspring; }
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
candidate solutions; EVALUATE each candidate; WHILE ( TERMINATION CONDITION is not satisfied ) { 1 SELECT parents; 2 RECOMBINE pairs of parents; 3 MUTATE the resulting offspring; }
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; }
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; }
the worst candidate * solutions from the list, so we have the original * population size again */ func (algorithm *Algorithm) selectSurvivors() { sort.Sort(algorithm.population) }
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] }
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; }
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?