Skip to content

Instantly share code, notes, and snippets.

@reyman
Created April 7, 2012 21:38
Show Gist options
  • Save reyman/2332285 to your computer and use it in GitHub Desktop.
Save reyman/2332285 to your computer and use it in GitHub Desktop.
my code
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package fr.iscpif.mgo.ga.algorithm
import java.util.Random
import fr.iscpif.mgo.ga._
import fr.iscpif.mgo.ga.operators.crossover.SBXBoundedCrossover
import fr.iscpif.mgo.ga.operators.mutation.CoEvolvingSigmaValuesMutation
import fr.iscpif.mgo.ga.selection.stochastic.BinaryTournamentNSGA2
import fr.iscpif.mgo._
import fr.iscpif.mgo.CrossOver
import fr.iscpif.mgo.Individual._
import fr.iscpif.mgo.ga.domination._
import fr.iscpif.mgo.ga.selection.Distance
import fr.iscpif.mgo.ga.selection.Ranking._
import fr.iscpif.mgo.ga.selection.ParetoRank
import fr.iscpif.mgo.ga.selection.Ranking
import fr.iscpif.mgo.ga.selection.Rank
import fr.iscpif.mgo.tools.Math
import scala.annotation.tailrec
import termination.{AbstractTermination, SameRankingTermination}
import selection.ParetoRankingStrategy.NonDominatedSorting
object NSGAII {
def buildIndividualsWithDistanceAndRanking[G <: GAGenome, FIT <: GAFitness](
individuals: IndexedSeq[Individual[G, FIT]],
dominance: Dominant,
rank: Rank) = {
val ranks = rank(individuals, dominance)
val distances = Distance.crowding(individuals)
(individuals zip ranks zip distances) map {
case ((i, iranking), idistance) =>
new Individual[G, FIT] with Distance with Ranking {
val genome = i.genome
val fitness = i.fitness
val distance = idistance.distance
val rank = iranking.rank
}
}
}
def sigma(
maxStep : Int,
factory: GAGenomeWithSigmaFactory,
evaluator: GAGenomeWithSigma => GAFitness,
sbxDistributionIndex: Double,
dominance: Dominant = new StrictDominant,
rank: Rank = new ParetoRank,
selection: Selection[Individual[GAGenomeWithSigma, GAFitness] with Distance with Ranking] = new BinaryTournamentNSGA2[Individual[GAGenomeWithSigma, GAFitness] with Distance with Ranking]
):NSGAII[GAGenomeWithSigma, GAGenomeWithSigmaFactory] = {
def _dominance = dominance
def _selection = selection
def _rank = rank
new NSGAII[GAGenomeWithSigma, GAGenomeWithSigmaFactory](maxStep,factory,evaluator) {
def mutationOperator = new CoEvolvingSigmaValuesMutation[GAGenomeWithSigma, GAGenomeWithSigmaFactory]
def crossoverOperator = new SBXBoundedCrossover[GAGenomeWithSigma, GAGenomeWithSigmaFactory](sbxDistributionIndex)
def dominance = _dominance
def selection = _selection
def rank = _rank
}
}
}
import NSGAII._
abstract class NSGAII[G <: GAGenome, F <: GAGenomeFactory[G]](numberStep:Int, factory: F, evaluator: G => GAFitness)
extends AbstractAlgorithm[G,F](numberStep,factory, evaluator) {
override type I <: Individual[G, GAFitness] with Distance with Ranking
def dominance: Dominant
def rank: Rank
def termination : AbstractTermination[I] = new SameRankingTermination[I](dominance, rank)
/*def apply(population: IndexedSeq[Individual[G, GAFitness]] ,factory: F, evaluator: G => GAFitness, stopAfterSteady: Int)(implicit aprng: Random): IndexedSeq[Individual[G, GAFitness] with Distance with Ranking] = {
@tailrec def evolveUntilSteady(population: IndexedSeq[Individual[G, GAFitness] with Distance with Ranking], steadyUntil: Int = 0): IndexedSeq[Individual[G, GAFitness] with Distance with Ranking] = {
//println(steadyUntil)
//population.foreach{i => println(i.rank + " " + i.genome)}
if(steadyUntil >= stopAfterSteady) population
else {
val nextPop = evolve(population, factory, evaluator)
if(!steady(population, nextPop)) evolveUntilSteady(nextPop, 0)
else evolveUntilSteady(nextPop, steadyUntil + 1)
}
}
evolveUntilSteady(buildIndividualsWithDistanceAndRanking(population, dominance, rank))
} */
//override def evolve(population: IndexedSeq[Individual[G, GAFitness]])(implicit aprng: Random): IndexedSeq[Individual[G, GAFitness]]
override def evolve(population: IndexedSeq[I])(implicit aprng: Random): IndexedSeq[I] = {
val offspring = breed(
population,
population.size
).map{ g => Individual(g, evaluator) }
val archive = population ++ offspring
//Elitisme strategy
val individuals = buildIndividualsWithDistanceAndRanking(archive, dominance, rank)
NonDominatedSorting.apply(individuals, population.size)(dominance)
}
def breed(archive: IndexedSeq[I],
offSpringSize: Int)(implicit aprng: Random): IndexedSeq[G] = {
@tailrec def breed(acc: List[G] = List.empty): List[G] = {
if (acc.size >= offSpringSize) acc
else {
val newIndividuals = crossoverOperator(selection(archive).genome, selection(archive).genome, factory)
breed(acc ++ newIndividuals)
}
}
breed().toIndexedSeq
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment