Java tutorial
/** * Copyright 2015 George Belden * * This file is part of ZodiacGenetics. * * ZodiacGenetics 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. * * ZodiacGenetics 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 * ZodiacGenetics. If not, see <http://www.gnu.org/licenses/>. */ package com.ciphertool.genetics.algorithms.mutation.cipherkey; import java.util.Random; import java.util.Set; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Required; import com.ciphertool.genetics.algorithms.mutation.NonUniformMutationAlgorithm; import com.ciphertool.genetics.dao.GeneDao; import com.ciphertool.genetics.entities.KeyedChromosome; public class RandomValueMutationAlgorithm implements NonUniformMutationAlgorithm<KeyedChromosome<Object>> { private static Logger log = Logger.getLogger(RandomValueMutationAlgorithm.class); private GeneDao geneDao; private Integer maxMutationsPerChromosome; @Override public void mutateChromosome(KeyedChromosome<Object> chromosome) { if (maxMutationsPerChromosome == null) { throw new IllegalStateException("The maxMutationsPerChromosome cannot be null."); } /* * Choose a random number of mutations constrained by the configurable * max and the total number of genes */ int numMutations = (int) (Math.random() * Math.min(maxMutationsPerChromosome, chromosome.getGenes().size())) + 1; Set<Object> availableKeys = chromosome.getGenes().keySet(); for (int i = 0; i < numMutations; i++) { // Keep track of the mutated keys mutateRandomGene(chromosome, availableKeys); } } /** * Performs a genetic mutation of a random Gene of the supplied Chromosome * * @param chromosome * the Chromosome to mutate * @param availableIndices * the Set of available indices to mutate */ protected void mutateRandomGene(KeyedChromosome<Object> chromosome, Set<Object> availableIndices) { if (availableIndices == null || availableIndices.isEmpty()) { log.warn( "List of available indices is null or empty. Unable to find a Gene to mutate. Returning null."); return; } Random generator = new Random(); Object[] keys = availableIndices.toArray(); // Get a random map key Object randomKey = keys[generator.nextInt(keys.length)]; // Replace that map value with a randomly generated Gene chromosome.getGenes().put((Object) randomKey, geneDao.findRandomGene(chromosome)); // Remove the key so that it is not used for mutation again availableIndices.remove(randomKey); } /** * @param geneDao * the geneDao to set */ @Required public void setGeneDao(GeneDao geneDao) { this.geneDao = geneDao; } @Override public void setMaxMutationsPerChromosome(Integer maxMutationsPerChromosome) { this.maxMutationsPerChromosome = maxMutationsPerChromosome; } }