public function crossoverUniform(Population $population, $selectionMethod = 2, $tournamentSize = 10) { $newPopulation = new Population($population->size()); for ($populationIndex = 0; $populationIndex < $population->size(); $populationIndex++) { $parent1 = $population->getFittestIndividual($populationIndex); if ($this->crossoverRate > Random::generate() && $populationIndex > $this->elitismCount) { $offspring = new Individual($parent1->getChromosomeLength()); if ($selectionMethod == 1) { $parent2 = $this->selectParentRoulette($population); } else { if ($selectionMethod == 2) { if ($tournamentSize <= $population->size()) { $parent2 = $this->selectParentTournament($population, $tournamentSize); } else { throw new Exception("Tournament size larger than populations"); } } } for ($geneIndex = 0; $geneIndex < $parent1->getChromosomeLength(); $geneIndex++) { if (0.5 > Random::generate()) { $offspring->setGene($geneIndex, $parent1->getGene($geneIndex)); } else { $offspring->setGene($geneIndex, $parent2->getGene($geneIndex)); } } $newPopulation->setIndividual($populationIndex, $offspring); } else { $newPopulation->setIndividual($populationIndex, $parent1); } } return $newPopulation; }
private function getChildren($couple) { $geneCount = $couple[0]->getGeneCount(); $child1 = new Individual($geneCount); $child2 = new Individual($geneCount); /* @var Individual[] $couple */ for ($i = 0; $i < count($geneCount); $i++) { if (rand(0, 1)) { // Swap gene $child1->setGene($i, $couple[1]->getGene($i)); $child2->setGene($i, $couple[0]->getGene($i)); } else { // No gene swap $child1->setGene($i, $couple[0]->getGene($i)); $child2->setGene($i, $couple[1]->getGene($i)); } } return [$child1, $child2]; }