com.ciphertool.genetics.algorithms.crossover.LiberalUnevaluatedCrossoverAlgorithm.java Source code

Java tutorial

Introduction

Here is the source code for com.ciphertool.genetics.algorithms.crossover.LiberalUnevaluatedCrossoverAlgorithm.java

Source

/**
 * Copyright 2012 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.crossover;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;

import com.ciphertool.genetics.algorithms.mutation.MutationAlgorithm;
import com.ciphertool.genetics.dao.GeneListDao;
import com.ciphertool.genetics.entities.Chromosome;
import com.ciphertool.genetics.util.ChromosomeHelper;
import com.ciphertool.genetics.util.FitnessEvaluator;

public class LiberalUnevaluatedCrossoverAlgorithm implements CrossoverAlgorithm {
    @SuppressWarnings("unused")
    private Logger log = Logger.getLogger(getClass());
    private GeneListDao geneListDao;
    private ChromosomeHelper chromosomeHelper;
    private MutationAlgorithm mutationAlgorithm;
    private boolean mutateDuringCrossover;

    @Override
    public List<Chromosome> crossover(Chromosome parentA, Chromosome parentB) {
        List<Chromosome> children = new ArrayList<Chromosome>();

        Chromosome firstChild = performCrossover(parentA, parentB);
        // The chromosome will be null if it's identical to one of its parents
        if (firstChild != null) {
            children.add(firstChild);
            parentA.increaseNumberOfChildren();
            parentB.increaseNumberOfChildren();
        }

        return children;
    }

    /**
     * This crossover algorithm does a liberal amount of changes since it
     * replaces genes regardless of their begin and end sequence positions
     */
    public Chromosome performCrossover(Chromosome parentA, Chromosome parentB) {
        Chromosome child = parentA.clone();

        int childGeneIndex = 0;

        /*
         * Make sure we don't exceed parentB's index, or else we will get an
         * IndexOutOfBoundsException
         */
        while (childGeneIndex < child.getGenes().size() && childGeneIndex < parentB.getGenes().size()) {
            /*
             * Flip a coin to see if the current Gene should be replaced
             */
            if (((int) (Math.random() * 2)) == 0) {
                child.replaceGene(childGeneIndex, parentB.getGenes().get(childGeneIndex).clone());

                while (child.actualSize() < child.targetSize()) {
                    child.addGene(geneListDao.findRandomGene(child, child.actualSize() - 1));
                }
            }

            childGeneIndex++;
        }

        /*
         * Trim the Chromosome in case it ends with too many sequences due to
         * the nature of this algorithm
         */
        chromosomeHelper.resizeChromosome(child);

        if (mutateDuringCrossover) {
            mutationAlgorithm.mutateChromosome(child);
        }

        // Don't return this child if it's identical to one of its parents
        if (child.equals(parentA) || child.equals(parentB)) {
            return null;
        }

        /*
         * Child is guaranteed to have at least as good fitness as its parent
         */
        return child;
    }

    /**
     * @param fitnessEvaluator
     *            the fitnessEvaluator to set
     */
    @Override
    @Required
    public void setFitnessEvaluator(FitnessEvaluator fitnessEvaluator) {
        /*
         * fitnessEvaluator is required by other crossover algorithms, so this
         * is just to satisfy the interface.
         */
    }

    /**
     * @param geneListDao
     *            the geneListDao to set
     */
    @Required
    public void setGeneListDao(GeneListDao geneListDao) {
        this.geneListDao = geneListDao;
    }

    /**
     * @param chromosomeHelper
     *            the chromosomeHelper to set
     */
    @Required
    public void setChromosomeHelper(ChromosomeHelper chromosomeHelper) {
        this.chromosomeHelper = chromosomeHelper;
    }

    /**
     * @param mutationAlgorithm
     *            the mutationAlgorithm to set
     */
    @Override
    @Required
    public void setMutationAlgorithm(MutationAlgorithm mutationAlgorithm) {
        this.mutationAlgorithm = mutationAlgorithm;
    }

    /**
     * @param mutateDuringCrossover
     *            the mutateDuringCrossover to set
     */
    @Override
    public void setMutateDuringCrossover(boolean mutateDuringCrossover) {
        this.mutateDuringCrossover = mutateDuringCrossover;
    }
}