All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mgo.evolution.neat.NEATCrossover.scala Maven / Gradle / Ivy

The newest version!
///*
// * Copyright (C) 17/09/2015 Guillaume Chérel
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program.  If not, see .
// */
//package mgo.evolution.crossover
//
//import mgo.fitness.DoubleFitness
//import mgo.{ Individual, Population }
//import mgo.evolution.genome.NEATGenomesAlign
//import mgo.evolution.genome.NEATGenome
//import mgo.evolution.genome.NEATGenome.Genome
//
//import scalaz._
//import Scalaz._
//
//import scala.collection.immutable.IntMap
//import scala.util.Random
//
//trait NEATCrossover <: Crossover with NEATGenomesAlign with NEATGenome with DoubleFitness {
//
//  def crossoverInheritDisabledProb: Double
//
//  override def crossover(indivs: Seq[Individual[G, P, F]], population: Population[G, P, F], archive: A)(implicit rng: Random): BreedingContext[Vector[G]] = {
//    val Vector(i1, i2) = indivs
//
//    // - genes that match no other gene in the other genome are disjoint if they occur within the range of the the other genome innovation numbers
//    // - they are excess if they occur outside this range.
//    val aligned = alignGenomes(i1.genome.connectionGenes, i2.genome.connectionGenes)
//
//    // - a new offspring is composed by chosing each matching genes randomly from either parent.
//    // - excess or disjoint genes from the fittest parent are included.
//    // - if the parents fitnesses are the same, inherit from the smallest genome or randomly
//    val fittest = if (i1.fitness == i2.fitness) 0 else if (i1.fitness > i2.fitness) 1 else 2
//
//    val newconnectiongenes =
//      aligned.foldLeft(Seq[ConnectionGene]()) { (acc, pair) =>
//        pair match {
//          case (None, Some(cg2), _) =>
//            if (fittest == 1) acc
//            else if (fittest == 2) acc :+ cg2
//            else if (rng.nextBoolean()) acc else acc :+ cg2
//
//          case (Some(cg1), None, _) =>
//            if (fittest == 1) acc :+ cg1
//            else if (fittest == 2) acc
//            else if (rng.nextBoolean()) acc :+ cg1 else acc
//
//          case (Some(cg1), Some(cg2), _) =>
//            val inherit =
//              if (fittest == 1) cg1
//              else if (fittest == 2) cg2
//              else if (rng.nextBoolean()) cg1 else cg2
//
//            // If one gene is disabled, the offspring gene is more likely to be disabled
//            val disable =
//              if (!(cg1.enabled && cg2.enabled)) rng.nextDouble() < crossoverInheritDisabledProb
//              else false
//
//            if (disable) acc :+ inherit.copy(enabled = false)
//            else acc :+ inherit
//
//          case (None, None, _) => acc
//        }
//      }.toVector
//
//    // Include at least one node from each parent. Also include one for each input, output, and bias node that are not connected.
//    val newnodesidx =
//      (newconnectiongenes.flatMap { cg => Seq(cg.inNode, cg.outNode) } ++
//        (inputNodesIndices ++ biasNodesIndices ++ outputNodesIndices)
//      ).toSet
//    val newnodes = IntMap(newnodesidx.toSeq.map { i =>
//      i -> {
//        if (!i1.genome.nodes.contains(i)) i2.genome.nodes(i)
//        else if (!i2.genome.nodes.contains(i)) i1.genome.nodes(i)
//        else if (rng.nextBoolean()) i1.genome.nodes(i) else i2.genome.nodes(i)
//      }
//    }: _*)
//
//    if (newconnectiongenes.exists(cg1 => {
//      if (newnodes(cg1.inNode).level >= newnodes(cg1.outNode).level) {
//        println(cg1)
//        true
//      } else false
//    })) throw new RuntimeException(s"Backwards!! $newconnectiongenes $newnodes\n$i1\n$i2")
//    val result = Genome(
//      connectionGenes = newconnectiongenes,
//      nodes = newnodes,
//      // Give the offspring its parents species. Species will be reattributed at the postBreeding
//      // stage anyway. This will just be used as a hint to speed up species attribution
//      species = i1.genome.species,
//      lastNodeId = newnodes.lastKey)
//
//    Vector(result).point[BreedingContext]
//  }
//}
//




© 2015 - 2024 Weber Informatics LLC | Privacy Policy