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

eu.stamp.botsing.ga.strategy.GuidedGeneticAlgorithm Maven / Gradle / Ivy

package eu.stamp.botsing.ga.strategy;

/*-
 * #%L
 * botsing-reproduction
 * %%
 * Copyright (C) 2017 - 2018 eu.stamp-project
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */


import eu.stamp.botsing.CrashProperties;
import eu.stamp.botsing.ga.strategy.operators.GuidedMutation;
import eu.stamp.botsing.ga.strategy.operators.GuidedSinglePointCrossover;
import org.evosuite.Properties;
import org.evosuite.ga.*;
import org.evosuite.ga.metaheuristics.GeneticAlgorithm;
import org.evosuite.ga.stoppingconditions.StoppingCondition;
import org.evosuite.utils.Randomness;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;


public class GuidedGeneticAlgorithm extends GeneticAlgorithm {

    private static final Logger LOG = LoggerFactory.getLogger(GuidedGeneticAlgorithm.class);

    protected ReplacementFunction replacementFunction = new FitnessReplacementFunction();

    private GuidedMutation mutation;

    private int populationSize;

    private int eliteSize;

    public GuidedGeneticAlgorithm(ChromosomeFactory factory) {
        super(factory);
        this.crossoverFunction = new GuidedSinglePointCrossover();
        this.mutation = new GuidedMutation();
        try {
            this.populationSize =  CrashProperties.getInstance().getIntValue("population");
            this.eliteSize = CrashProperties.getInstance().getIntValue("elite");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Properties.NoSuchParameterException e) {
            e.printStackTrace();
        }
    }

    public void setFitnessFunction(){

    }

    @Override
    public void generateSolution() {
        currentIteration = 0;

        // generate solution
        initializePopulation();

        LOG.debug("Starting evolution");
        int starvationCounter = 0;
        double bestFitness = Double.MAX_VALUE;
        double lastBestFitness = Double.MAX_VALUE;

        double bestFFinInitialization = getBestFitness();
        LOG.debug("Best FF in the initial population is: "+bestFFinInitialization);
        while (!isFinished()){
            double bestFitnessBeforeEvolution = getBestFitness();
            evolve();
            sortPopulation();
            double newFitness = getBestFitness();
            LOG.info("New fitness Function is: "+newFitness);

            if (Double.compare(bestFitness, lastBestFitness) == 0) {
                starvationCounter++;
            } else {
                LOG.info("reset starvationCounter after " + starvationCounter + " iterations");
                starvationCounter = 0;
                lastBestFitness = bestFitness;
            }

            updateSecondaryCriterion(starvationCounter);

            LOG.info("Current iteration: " + currentIteration);
            this.notifyIteration();

        }
    }

    @Override
    protected void evolve() {
        List newGeneration = new ArrayList();
        // Elitism
        LOG.debug("Selection");

        newGeneration.addAll(elitism());

        while (newGeneration.size() < this.populationSize && !isFinished()) {
            LOG.debug("Generating offspring");
            T parent1 = selectionFunction.select(population);
            T parent2 = selectionFunction.select(population);
            T offspring1 = (T) parent1.clone();
            T offspring2 = (T) parent2.clone();
            // Crossover
            if (Randomness.nextDouble() <= Properties.CROSSOVER_RATE) {
                ((GuidedSinglePointCrossover) crossoverFunction).crossOver(offspring1, offspring2);
            }

            // Mutation
            this.mutation.mutateOffspring(offspring1);
            notifyMutation(offspring1);
            this.mutation.mutateOffspring(offspring2);
            notifyMutation(offspring2);

            //calculate fitness
            calculateFitness(offspring1);
            calculateFitness(offspring2);

            // If and only if one of the offsprings is not worse than the best parent, we replace parents by offsprings.
            if (keepOffspring(parent1, parent2, offspring1, offspring2)) {
                LOG.debug("Replace parents");

                // Reject offspring straight away if it's too long
                int rejected = 0;
                if (isTooLong(offspring1) || offspring1.size() == 0) {
                    rejected++;
                } else {
                    newGeneration.add(offspring1);
                }

                if (isTooLong(offspring2) || offspring2.size() == 0) {
                    rejected++;
                } else {
                    newGeneration.add(offspring2);
                }

                if (rejected == 1) {
                    newGeneration.add(Randomness.choice(parent1, parent2));
                }else if (rejected == 2) {
                    newGeneration.add(parent1);
                    newGeneration.add(parent2);
                }
            } else {
                LOG.debug("Keep parents");
                newGeneration.add(parent1);
                newGeneration.add(parent2);
            }
        }

        population = newGeneration;
        // archive
        updateFitnessFunctionsAndValues();

        currentIteration++;
    }

    protected List  elitism() {
        List elite = new ArrayList();
        LOG.debug("Cloning the best individuals to next generation");
        for (int i = 0; i < this.eliteSize; i++) {
            elite.add(population.get(i));
        }
        return elite;
    }

    @Override
    public void initializePopulation() {
        if (!population.isEmpty()) {
            return;
        }

        // Generate Initial Population
        generatePopulation(this.populationSize);

        LOG.debug("Initializing the population.");
        // Calculate fitness functions
        calculateFitness();
        // Sort individuals
        sortPopulation();
        assert!population.isEmpty() : "Could not create any test";
    }

    protected void sortPopulation() {
        LOG.debug("Sort current population.");
        if (fitnessFunctions.get(0).isMaximizationFunction()) {
            Collections.sort(population, Collections.reverseOrder());
        } else {
            Collections.sort(population);
        }
    }

    private void calculateFitness() {
        LOG.debug("Calculating fitness for " + population.size() + " individuals");
        Iterator iterator = population.iterator();
        while (iterator.hasNext()) {
            T c = iterator.next();
            if (isFinished()) {
                if (c.isChanged()){
                    iterator.remove();
                }
            } else {
                calculateFitness(c);
            }
        }
    }

    private void calculateFitness(T chromosome){
        for (FitnessFunction fitnessFunction : fitnessFunctions) {
            notifyEvaluation(chromosome);
            double value = fitnessFunction.getFitness(chromosome);
        }
    }

    private void generatePopulation(int populationSize) {
        LOG.debug("Creating random population");
        for (int i = 0; i < populationSize; i++) {
            T individual;
            individual = chromosomeFactory.getChromosome();
            for (FitnessFunction fitnessFunction : this.fitnessFunctions) {
                individual.addFitness(fitnessFunction);
            }

            population.add(individual);

            if (isFinished()){
                break;
            }
        }
    }

    public boolean isFinished() {
        for (StoppingCondition c : stoppingConditions) {
            LOG.debug("Current value of stopping condition "+ c.getClass().toString()+": "+c.getCurrentValue());

            // logger.error(c + " "+ c.getCurrentValue());
            if (c.isFinished()){
                LOG.info(c.toString());
                return true;
            }
        }
        return false;
    }

    private double getBestFitness() {
        T bestIndividual = getBestIndividual();
        for (FitnessFunction ff : fitnessFunctions) {
            ff.getFitness(bestIndividual);
        }
        return bestIndividual.getFitness();
    }

    public T getBestIndividual() {
        if (population.isEmpty()) {
            return this.chromosomeFactory.getChromosome();
        }

        // Assume population is sorted
        return population.get(0);
    }

    protected boolean keepOffspring(Chromosome parent1, Chromosome parent2, Chromosome offspring1,
                                    Chromosome offspring2) {
        return replacementFunction.keepOffspring(parent1, parent2, offspring1, offspring2);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy