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

org.evosuite.ga.metaheuristics.GeneticAlgorithm Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
 * contributors
 *
 * This file is part of EvoSuite.
 *
 * EvoSuite is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3.0 of the License, or
 * (at your option) any later version.
 *
 * EvoSuite 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
 * Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with EvoSuite. If not, see .
 */
package org.evosuite.ga.metaheuristics;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.evosuite.Properties;
import org.evosuite.Properties.Algorithm;
import org.evosuite.ga.Chromosome;
import org.evosuite.ga.ChromosomeFactory;
import org.evosuite.ga.FitnessFunction;
import org.evosuite.ga.archive.Archive;
import org.evosuite.ga.bloatcontrol.BloatControlFunction;
import org.evosuite.ga.localsearch.DefaultLocalSearchObjective;
import org.evosuite.ga.localsearch.LocalSearchBudget;
import org.evosuite.ga.localsearch.LocalSearchObjective;
import org.evosuite.ga.operators.crossover.CrossOverFunction;
import org.evosuite.ga.operators.crossover.SinglePointCrossOver;
import org.evosuite.ga.operators.ranking.RankBasedPreferenceSorting;
import org.evosuite.ga.operators.ranking.RankingFunction;
import org.evosuite.ga.operators.selection.RankSelection;
import org.evosuite.ga.operators.selection.SelectionFunction;
import org.evosuite.ga.populationlimit.IndividualPopulationLimit;
import org.evosuite.ga.populationlimit.PopulationLimit;
import org.evosuite.ga.stoppingconditions.MaxGenerationStoppingCondition;
import org.evosuite.ga.stoppingconditions.StoppingCondition;
import org.evosuite.symbolic.DSEStats;
import org.evosuite.testcase.execution.ExecutionTracer;
import org.evosuite.testsuite.TestSuiteChromosome;
import org.evosuite.utils.ArrayUtil;
import org.evosuite.utils.LoggingUtils;
import org.evosuite.utils.Randomness;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Abstract superclass of genetic algorithms
 * 
 * @author Gordon Fraser
 */
public abstract class GeneticAlgorithm implements SearchAlgorithm,
		Serializable {

	private static final long serialVersionUID = 5155609385855093435L;

	private static final Logger logger = LoggerFactory.getLogger(GeneticAlgorithm.class);

	/** Fitness function to rank individuals */
	protected List> fitnessFunctions = new ArrayList>();

	/** Selection function to select parents */
	protected SelectionFunction selectionFunction = new RankSelection();

	/** CrossOver function */
	protected CrossOverFunction crossoverFunction = new SinglePointCrossOver();

	/** Current population */
	protected List population = new ArrayList();

	/** Generator for initial population */
	protected ChromosomeFactory chromosomeFactory;

	/** Listeners */
	protected transient Set listeners = new HashSet();

	/** List of conditions on which to end the search */
	protected transient Set stoppingConditions = new HashSet();

	/** Bloat control, to avoid too long chromosomes */
	protected Set bloatControl = new HashSet();

	/** Local search might need a different local objective */
	protected LocalSearchObjective localObjective = new DefaultLocalSearchObjective<>();

	/** The population limit decides when an iteration is done */
	protected PopulationLimit populationLimit = new IndividualPopulationLimit();

	/** Age of the population */
	protected int currentIteration = 0;

	protected double localSearchProbability = Properties.LOCAL_SEARCH_PROBABILITY;

	/** Selected ranking strategy **/
	protected RankingFunction rankingFunction = new RankBasedPreferenceSorting();

	/**
	 * Constructor
	 * 
	 * @param factory
	 *            a {@link org.evosuite.ga.ChromosomeFactory} object.
	 */
	public GeneticAlgorithm(ChromosomeFactory factory) {
		chromosomeFactory = factory;
		addStoppingCondition(new MaxGenerationStoppingCondition());
		if (Properties.LOCAL_SEARCH_RATE > 0)
			addListener(LocalSearchBudget.getInstance());
		// addBloatControl(new MaxSizeBloatControl());
	}

	/**
	 * Generate one new generation
	 */
	protected abstract void evolve();

	/**
	 * Local search is only applied every X generations
	 * 
	 * @return a boolean.
	 */
	protected boolean shouldApplyLocalSearch() {
		// If local search is not set to a rate, then we don't use it at all
		if (Properties.LOCAL_SEARCH_RATE <= 0)
			return false;

		if (getAge() % Properties.LOCAL_SEARCH_RATE == 0) {
			if (Randomness.nextDouble() <= localSearchProbability) {
				return true;
			}
		}
		return false;
	}

	protected void disableFirstSecondaryCriterion() {
		if (TestSuiteChromosome.getSecondaryObjectivesSize() > 1) {
			TestSuiteChromosome.disableFirstSecondaryObjective();
			if (ArrayUtil.contains(Properties.SECONDARY_OBJECTIVE, Properties.SecondaryObjective.IBRANCH)) {
				ExecutionTracer.disableContext();
			}
			logger.info("second secondary criterion enabled");
		}
	}

	protected void enableFirstSecondaryCriterion() {
		if (TestSuiteChromosome.getSecondaryObjectivesSize() > 1) {
			TestSuiteChromosome.enableFirstSecondaryObjective();
			if (ArrayUtil.contains(Properties.SECONDARY_OBJECTIVE, Properties.SecondaryObjective.IBRANCH)) {
				ExecutionTracer.enableContext();
			}
			logger.info("first secondary criterion enabled");
		}
	}

	/**
	 * enable and disable secondary criteria according to the strategy defined
	 * in the Properties file.
	 * 
	 * @param starvationCounter
	 */
	protected void updateSecondaryCriterion(int starvationCounter) {

		if (Properties.ENABLE_SECONDARY_OBJECTIVE_AFTER > 0
				&& TestSuiteChromosome.getSecondaryObjectivesSize() > 1) {

			double progress = this.progress() * 100.0;

			if (progress > Properties.ENABLE_SECONDARY_OBJECTIVE_AFTER) {
				if (Properties.ENABLE_SECONDARY_OBJECTIVE_STARVATION) {
					updateSecondaryObjectiveStarvation(starvationCounter);
				} else {
					enableFirstSecondaryCriterion();
					Properties.ENABLE_SECONDARY_OBJECTIVE_AFTER = 0;
				}
			}
		} else if (Properties.ENABLE_SECONDARY_OBJECTIVE_STARVATION
				&& Properties.ENABLE_SECONDARY_OBJECTIVE_AFTER == 0
				&& TestSuiteChromosome.getSecondaryObjectivesSize() > 1) {
			updateSecondaryObjectiveStarvation(starvationCounter);
		}
	}

	private void updateSecondaryObjectiveStarvation(int starvationCounter) {
		if (starvationCounter > Properties.STARVATION_AFTER_GENERATION && !TestSuiteChromosome.isFirstSecondaryObjectiveEnabled()) {
			enableFirstSecondaryCriterion();
		} else {
			if (starvationCounter == 0 && TestSuiteChromosome.isFirstSecondaryObjectiveEnabled()
					&& TestSuiteChromosome.getSecondaryObjectivesSize() > 1) {
				disableFirstSecondaryCriterion();
			}
		}
	}

	/**
	 * Apply local search, starting from the best individual and continue
	 * applying it to all individuals until the local search budget is used up.
	 * 
	 * The population list is re-ordered if needed.
	 */
	protected void applyLocalSearch() {
		if (!shouldApplyLocalSearch())
			return;

		logger.debug("Applying local search");
		LocalSearchBudget.getInstance().localSearchStarted();

		boolean improvement = false;

		for (Chromosome individual : population) {
			if (isFinished())
				break;

			if (LocalSearchBudget.getInstance().isFinished()) {
				logger.debug("Local search budget used up, exiting local search");
				break;
			}

			if (individual.localSearch(localObjective)) {
				improvement = true;
			}
		}
		
		if (improvement) {
			DSEStats.getInstance().reportNewIncrease();
			updateProbability(true);
			logger.debug("Increasing probability of applying LS to " + localSearchProbability);
		} else {
			DSEStats.getInstance().reportNewDecrease();
			updateProbability(false);
			logger.debug("Decreasing probability of applying LS to " + localSearchProbability);
		}

		if (improvement) {
			// If an improvement occurred to one of the individuals, it could
			// be the case that the improvement was so good, that the individual
			// has surpassed to the previous individual, which makes the population
			// list not sorted any more. 
			if (!populationIsSorted()) {
				this.sortPopulation();
			}
		}
	}

	/**
	 * Returns true if the population is sorted according to the fitness 
	 * values.
	 * 
	 * @return true if the population is sorted (or empty)
	 */
	private boolean populationIsSorted() {
		Chromosome previousIndividual = null;
		for (Chromosome currentIndividual : this.population) {
			if (previousIndividual!=null) {
				if (!isBetterOrEqual(previousIndividual, currentIndividual)) {
					// at least two individuals are not sorted
					return false;
				}
			}
			previousIndividual = currentIndividual;
		}
		// the population is sorted (or empty)
		return true;
	}

	/**
	 * Returns true if the fitness functions are maximization functions
	 * or false if all fitness functions are minimisation functions.
	 * It expects that all fitnessFunctions are minimising or maximising,
	 * it cannot happen that minimization and maximization functions are
	 * together.
	 * 
	 * @return
	 */
	private boolean isMaximizationFunction() {
		return fitnessFunctions.get(0).isMaximizationFunction();
	}

	protected void updateProbability(boolean improvement){
		if (improvement) {
			localSearchProbability *= Properties.LOCAL_SEARCH_ADAPTATION_RATE;
			localSearchProbability = Math.min(localSearchProbability, 1.0);
		} else {
			localSearchProbability /= Properties.LOCAL_SEARCH_ADAPTATION_RATE;
			localSearchProbability = Math.max(localSearchProbability, Double.MIN_VALUE);
		}
		// localSearchProbability = Math.pow(
		// 1.0 + ((1.0 - localSearchProbability) / localSearchProbability) *
		// Math.exp(delta), -1.0);
	}
	
	
	/**
	 * Apply dynamic symbolic execution
	 */
	/*
	 * @Deprecated protected void applyDSE() {
	 * logger.info("Applying DSE at generation " + currentIteration);
	 * DSEBudget.DSEStarted();
	 * 
	 * boolean success = false;
	 * 
	 * for (Chromosome individual : population) { if (isFinished()) break;
	 * 
	 * if (DSEBudget.isFinished()) break;
	 * 
	 * boolean result = individual.applyDSE(this); if(result) success = true; }
	 * 
	 * if(Properties.DSE_ADAPTIVE_PROBABILITY > 0.0) { if(success) {
	 * Properties.DSE_ADAPTIVE_PROBABILITY *= Properties.DSE_ADAPTIVE_RATE;
	 * Properties.DSE_ADAPTIVE_PROBABILITY =
	 * Math.min(Properties.DSE_ADAPTIVE_PROBABILITY, 1.0); } else {
	 * Properties.DSE_ADAPTIVE_PROBABILITY /= Properties.DSE_ADAPTIVE_RATE;
	 * Properties.DSE_ADAPTIVE_PROBABILITY =
	 * Math.max(Properties.DSE_ADAPTIVE_PROBABILITY, Double.MIN_VALUE); }
	 * logger.
	 * info("Updating DSE probability to "+Properties.DSE_ADAPTIVE_PROBABILITY);
	 * } }
	 */
	/**
	 * Set up initial population
	 */
	public abstract void initializePopulation();

	/**
	 * {@inheritDoc}
	 * 
	 * Generate solution
	 */
	@Override
	public abstract void generateSolution();

	/**
	 * Fills the population at first with recycled chromosomes - for more
	 * information see recycleChromosomes() and ChromosomeRecycler - and after
	 * that, the population is filled with random chromosomes.
	 * 
	 * This method guarantees at least a proportion of
	 * Properties.initially_enforeced_Randomness % of random chromosomes
	 * 
	 * @param population_size
	 *            a int.
	 */
	protected void generateInitialPopulation(int population_size) {
		generateRandomPopulation(population_size - population.size());
	}

	/**
	 * This method can be used to kick out chromosomes when the population is
	 * possibly overcrowded
	 * 
	 * Depending on the Property "starve_by_fitness" chromosome are either
	 * kicked out randomly or according to their fitness
	 * 
	 * @param limit
	 *            a int.
	 */
	protected void starveToLimit(int limit) {
		if (Properties.STARVE_BY_FITNESS)
			starveByFitness(limit);
		else
			starveRandomly(limit);
	}

	/**
	 * This method can be used to kick out random chromosomes in the current
	 * population until the given limit is reached again.
	 * 
	 * @param limit
	 *            a int.
	 */
	protected void starveRandomly(int limit) {
		while (population.size() > limit) {
			int removePos = Randomness.nextInt() % population.size();
			population.remove(removePos);
		}
	}

	/**
	 * This method can be used to kick out the worst chromosomes in the current
	 * population until the given limit is reached again.
	 * 
	 * @param limit
	 *            a int.
	 */
	protected void starveByFitness(int limit) {
		calculateFitnessAndSortPopulation();
		for (int i = population.size() - 1; i >= limit; i--) {
			population.remove(i);
		}
	}

	/**
	 * Generate random population of given size
	 * 
	 * @param population_size
	 *            a int.
	 */
	protected void generateRandomPopulation(int population_size) {
		logger.debug("Creating random population");
		for (int i = 0; i < population_size; i++) {
			T individual = chromosomeFactory.getChromosome();
			for (FitnessFunction fitnessFunction : this.fitnessFunctions) {
				individual.addFitness(fitnessFunction);
			}

			population.add(individual);
			if (isFinished())
				break;
		}
		logger.debug("Created " + population.size() + " individuals");
	}

	/**
	 * Delete all current individuals
	 */
	public void clearPopulation() {
		logger.debug("Resetting population");
		population.clear();
	}

	/**
	 * Add new fitness function (i.e., for new mutation)
	 * 
	 * @param function
	 *            a {@link org.evosuite.ga.FitnessFunction} object.
	 */
	public void addFitnessFunction(FitnessFunction function) {
		fitnessFunctions.add(function);
		localObjective.addFitnessFunction(function);
	}

	public void addFitnessFunctions(List> functions) {
		for (FitnessFunction function : functions)
			this.addFitnessFunction(function);
	}

	/**
	 * Get currently used fitness function
	 * 
	 * @return a {@link org.evosuite.ga.FitnessFunction} object.
	 */
	public FitnessFunction getFitnessFunction() {
		return fitnessFunctions.get(0);
	}

	/**
	 * Get all used fitness function
	 * 
	 * @return a {@link org.evosuite.ga.FitnessFunction} object.
	 */
	public List> getFitnessFunctions() {
		return fitnessFunctions;
	}

	public int getNumberOfFitnessFunctions() {
		return fitnessFunctions.size();
	}

	/**
	 * 
	 * @return
	 */
	@Override
	public String toString() {
		StringBuilder str = new StringBuilder();

		int i = 0;
		for (Chromosome c : population) {
			str.append("\n  - test " + i);

			for (FitnessFunction ff : this.fitnessFunctions) {
				DecimalFormat df = new DecimalFormat("#.#####");
				str.append(", " + ff.getClass().getSimpleName().replace("CoverageSuiteFitness", "")
						+ " " + df.format(c.getFitness(ff)));
			}

			i++;
		}

		return str.toString();
	}

	
	/**
	 * Set new fitness function (i.e., for new mutation)
	 * 
	 * @param function
	 *            a
	 *            {@link org.evosuite.ga.operators.selection.SelectionFunction}
	 *            object.
	 */
	public void setSelectionFunction(SelectionFunction function) {
		selectionFunction = function;
	}

	/**
	 * Get currently used fitness function
	 * 
	 * @return a {@link org.evosuite.ga.operators.selection.SelectionFunction}
	 *         object.
	 */
	public SelectionFunction getSelectionFunction() {
		return selectionFunction;
	}

	/**
	 * Set the new ranking function (only used by MOO algorithms)
	 * 
	 * @param function a {@link org.evosuite.ga.operators.ranking.RankingFunction} object
	 */
	public void setRankingFunction(RankingFunction function) {
		this.rankingFunction = function;
	}

	/**
	 * Get currently used ranking function (only used by MOO algorithms)
	 * 
	 * @return a {@link org.evosuite.ga.operators.ranking.RankingFunction} object
	 */
	public RankingFunction getRankingFunction() {
		return this.rankingFunction;
	}

	/**
	 * Set new bloat control function
	 * 
	 * @param bloat_control
	 *            a {@link org.evosuite.ga.bloatcontrol.BloatControlFunction}
	 *            object.
	 */
	public void setBloatControl(BloatControlFunction bloat_control) {
		this.bloatControl.clear();
		addBloatControl(bloat_control);
	}

	/**
	 * Set new bloat control function
	 * 
	 * @param bloat_control
	 *            a {@link org.evosuite.ga.bloatcontrol.BloatControlFunction}
	 *            object.
	 */
	public void addBloatControl(BloatControlFunction bloat_control) {
		this.bloatControl.add(bloat_control);
	}

	/**
	 * Check whether individual is suitable according to bloat control functions
	 * 
	 * @param chromosome
	 *            a {@link org.evosuite.ga.Chromosome} object.
	 * @return a boolean.
	 */
	public boolean isTooLong(Chromosome chromosome) {
		for (BloatControlFunction b : bloatControl) {
			if (b.isTooLong(chromosome))
				return true;
		}
		return false;
	}

	/**
	 * Get number of iterations
	 * 
	 * @return Number of iterations
	 */
	public int getAge() {
		return currentIteration;
	}

	/**
	 * Calculate fitness for all individuals
	 */
	protected void calculateFitness() {
		logger.debug("Calculating fitness for " + population.size() + " individuals");

		Iterator iterator = this.population.iterator();
		while (iterator.hasNext()) {
			T c = iterator.next();
			if (isFinished()) {
				if (c.isChanged())
					iterator.remove();
			} else {
				this.calculateFitness(c);
			}
		}
	}

	/**
	 * Calculate fitness for an individual
	 * 
	 * @param c
	 */
	protected void calculateFitness(T c) {
		for (FitnessFunction fitnessFunction : this.fitnessFunctions) {
			fitnessFunction.getFitness(c);
			notifyEvaluation(c);
		}
	}

	/**
	 * Calculate fitness for all individuals and sort them
	 */
	protected void calculateFitnessAndSortPopulation() {
		this.calculateFitness();
		// Sort population
		this.sortPopulation();
	}

	/**
	 * 

* getPopulationSize *

* * @return a int. */ public int getPopulationSize() { return population.size(); } /** * Copy best individuals * * @return a {@link java.util.List} object. */ @SuppressWarnings("unchecked") protected List elitism() { logger.debug("Elitism with ELITE = " + Properties.ELITE); List elite = new ArrayList(); for (int i = 0; i < Properties.ELITE; i++) { logger.trace("Copying individual " + i + " with fitness " + population.get(i).getFitness()); elite.add((T) population.get(i).clone()); } logger.trace("Done."); return elite; } /** * Create random individuals * * @return a {@link java.util.List} object. */ protected List randomism() { logger.debug("Randomism"); List randoms = new ArrayList(); for (int i = 0; i < Properties.ELITE; i++) { randoms.add(chromosomeFactory.getChromosome()); } return randoms; } /** * update archive fitness functions */ public void updateFitnessFunctionsAndValues() { for (FitnessFunction f : fitnessFunctions) { f.updateCoveredGoals(); } // Do we actually have to perform yet another fitness evaluation? // Yes, if ARCHIVE has been updated, No otherwise. if (!Archive.getArchiveInstance().hasBeenUpdated()) { return; } for (T t : population) { for (FitnessFunction fitnessFunction : fitnessFunctions) { fitnessFunction.getFitness(t); } } Archive.getArchiveInstance().setHasBeenUpdated(false); } /** * Penalty if individual is not unique * * @param individual * a {@link org.evosuite.ga.Chromosome} object. * @param generation * a {@link java.util.List} object. */ /* * protected void kinCompensation(Chromosome individual, List * generation) { * * if (Properties.KINCOMPENSATION >= 1.0) return; * * boolean unique = true; * * for (Chromosome other : generation) { if (other == individual) continue; * * if (other.equals(individual)) { unique = false; break; } } * * if (!unique) { logger.debug("Applying kin compensation"); if * (fitnessFunction.isMaximizationFunction()) * individual.setFitness(individual.getFitness() * Properties.KINCOMPENSATION); else * individual.setFitness(individual.getFitness() (2.0 - * Properties.KINCOMPENSATION)); } } */ /** * Return the individual with the highest fitChromosomeess * * @return a {@link org.evosuite.ga.Chromosome} object. */ public T getBestIndividual() { if (population.isEmpty()) { return this.chromosomeFactory.getChromosome(); } // Assume population is sorted return population.get(0); } /** * Return the individual(s) with the highest fitChromosomeess * * @return a list of {@link org.evosuite.ga.Chromosome} object(s). */ public List getBestIndividuals() { List bestIndividuals = new ArrayList(); if (this.population.isEmpty()) { bestIndividuals.add(this.chromosomeFactory.getChromosome()); return bestIndividuals; } if (Properties.ALGORITHM == Algorithm.NSGAII || Properties.ALGORITHM == Algorithm.SPEA2) return population; // Assume population is sorted bestIndividuals.add(population.get(0)); return bestIndividuals; } /** * Write to a file all fitness values of each individuals. * * @param individuals a list of {@link org.evosuite.ga.Chromosome} object(s). */ public void writeIndividuals(List individuals) { if (!Properties.WRITE_INDIVIDUALS) { return; } File dir = new File(Properties.REPORT_DIR); if (!dir.exists()) { if (!dir.mkdirs()) { throw new RuntimeException("Cannot create report dir: " + Properties.REPORT_DIR); } } try { File populationFile = new File( Properties.REPORT_DIR + File.separator + "pareto_" + this.currentIteration + ".csv"); populationFile.createNewFile(); FileWriter fw = new FileWriter(populationFile.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); PrintWriter out = new PrintWriter(bw); // header List l_string = new ArrayList(); if (Properties.ALGORITHM == Algorithm.NSGAII) { l_string.add("rank"); } else if (Properties.ALGORITHM == Algorithm.SPEA2) { l_string.add("strength"); } for (int i = 0; i < this.fitnessFunctions.size(); i++) { l_string.add(this.fitnessFunctions.get(i).getClass().getSimpleName()); } out.println(String.join(",", l_string)); // content for (int j = 0; j < individuals.size(); j++) { l_string.clear(); T individual = individuals.get(j); if (Properties.ALGORITHM == Algorithm.NSGAII) { l_string.add(Integer.toString(individual.getRank())); } else if (Properties.ALGORITHM == Algorithm.SPEA2) { l_string.add(Double.toString(individual.getDistance())); } for (int i = 0; i < this.fitnessFunctions.size(); i++) { l_string.add(Double.toString(individual.getFitness(this.fitnessFunctions.get(i)))); } out.println(String.join(",", l_string)); } out.close(); bw.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } /** * Set a new factory method * * @param factory * a {@link org.evosuite.ga.ChromosomeFactory} object. */ public void setChromosomeFactory(ChromosomeFactory factory) { chromosomeFactory = factory; } /** * Set a new xover function * * @param crossover * a * {@link org.evosuite.ga.operators.crossover.CrossOverFunction} * object. */ public void setCrossOverFunction(CrossOverFunction crossover) { this.crossoverFunction = crossover; } /** * Add a new search listener * * @param listener * a {@link org.evosuite.ga.metaheuristics.SearchListener} * object. */ public void addListener(SearchListener listener) { listeners.add(listener); } /** * Remove a search listener * * @param listener * a {@link org.evosuite.ga.metaheuristics.SearchListener} * object. */ public void removeListener(SearchListener listener) { listeners.remove(listener); } /** * Notify all search listeners of search start */ protected void notifySearchStarted() { for (SearchListener listener : listeners) { listener.searchStarted(this); } } /** * Notify all search listeners of search end */ protected void notifySearchFinished() { for (SearchListener listener : listeners) { listener.searchFinished(this); } } /** * Notify all search listeners of iteration */ protected void notifyIteration() { for (SearchListener listener : listeners) { listener.iteration(this); } } /** * Notify all search listeners of fitness evaluation * * @param chromosome * a {@link org.evosuite.ga.Chromosome} object. */ protected void notifyEvaluation(Chromosome chromosome) { for (SearchListener listener : listeners) { listener.fitnessEvaluation(chromosome); } } /** * Notify all search listeners of a mutation * * @param chromosome * a {@link org.evosuite.ga.Chromosome} object. */ protected void notifyMutation(Chromosome chromosome) { for (SearchListener listener : listeners) { listener.modification(chromosome); } } /** * Sort the population by fitness * * WARN: used only with singular objective algorithms, multi-objective * algorithms should implement their own 'sort' */ protected void sortPopulation() { if (Properties.SHUFFLE_GOALS) Randomness.shuffle(population); if (isMaximizationFunction()) { Collections.sort(population, Collections.reverseOrder()); } else { Collections.sort(population); } } /** * Accessor for population Chromosome * * * @return a {@link java.util.List} object. */ public List getPopulation() { return population; } /** * Determine if the next generation has reached its size limit * * @param nextGeneration * a {@link java.util.List} object. * @return a boolean. */ public boolean isNextPopulationFull(List nextGeneration) { return populationLimit.isPopulationFull(nextGeneration); } /** * Set a new population limit function * * @param limit * a {@link org.evosuite.ga.populationlimit.PopulationLimit} * object. */ public void setPopulationLimit(PopulationLimit limit) { this.populationLimit = limit; } /** * Determine whether any of the stopping conditions hold * * @return a boolean. */ public boolean isFinished() { for (StoppingCondition c : stoppingConditions) { // logger.error(c + " "+ c.getCurrentValue()); if (c.isFinished()) return true; } return false; } // TODO: Override equals method in StoppingCondition /** *

* addStoppingCondition *

* * @param condition * a {@link org.evosuite.ga.stoppingconditions.StoppingCondition} * object. */ public void addStoppingCondition(StoppingCondition condition) { Iterator it = stoppingConditions.iterator(); while (it.hasNext()) { if (it.next().getClass().equals(condition.getClass())) { return; } } logger.debug("Adding new stopping condition"); stoppingConditions.add(condition); addListener(condition); } public Set getStoppingConditions() { return stoppingConditions; } // TODO: Override equals method in StoppingCondition /** *

* setStoppingCondition *

* * @param condition * a {@link org.evosuite.ga.stoppingconditions.StoppingCondition} * object. */ public void setStoppingCondition(StoppingCondition condition) { stoppingConditions.clear(); logger.debug("Setting stopping condition"); stoppingConditions.add(condition); addListener(condition); } /** *

* removeStoppingCondition *

* * @param condition * a {@link org.evosuite.ga.stoppingconditions.StoppingCondition} * object. */ public void removeStoppingCondition(StoppingCondition condition) { Iterator it = stoppingConditions.iterator(); while (it.hasNext()) { if (it.next().getClass().equals(condition.getClass())) { it.remove(); removeListener(condition); } } } /** *

* resetStoppingConditions *

*/ public void resetStoppingConditions() { for (StoppingCondition c : stoppingConditions) { c.reset(); } } /** *

* setStoppingConditionLimit *

* * @param value * a int. */ public void setStoppingConditionLimit(int value) { for (StoppingCondition c : stoppingConditions) { c.setLimit(value); } } protected void updateBestIndividualFromArchive() { if (!Properties.TEST_ARCHIVE) return; T best = Archive.getArchiveInstance().mergeArchiveAndSolution(getBestIndividual()); // The archive may contain tests evaluated with a fitness function // that is not part of the optimization (e.g. ibranch secondary objective) Iterator> it = best.getCoverageValues().keySet().iterator(); while(it.hasNext()) { FitnessFunction ff = it.next(); if(!fitnessFunctions.contains(ff)) it.remove(); } population.add(0, best); } /** * Returns true if the chromosome1 is better or equal than * chromosome2 according to the compound fitness function. * * @param chromosome1 * a {@link org.evosuite.ga.Chromosome} object. * @param chromosome2 * a {@link org.evosuite.ga.Chromosome} object. * @return a boolean. */ protected boolean isBetterOrEqual(Chromosome chromosome1, Chromosome chromosome2) { // if (fitnessFunction.isMaximizationFunction()) { if (getFitnessFunction().isMaximizationFunction()) { return chromosome1.compareTo(chromosome2) >= 0; } else { return chromosome1.compareTo(chromosome2) <= 0; } } /* * protected boolean isBetter(Chromosome chromosome1, Chromosome * chromosome2) { if (fitnessFunction.isMaximizationFunction()) { return * chromosome1.compareTo(chromosome2) > 0; } else { return * chromosome1.compareTo(chromosome2) < 0; } } */ /** *

* getBest *

* * @param chromosome1 * a {@link org.evosuite.ga.Chromosome} object. * @param chromosome2 * a {@link org.evosuite.ga.Chromosome} object. * @return a {@link org.evosuite.ga.Chromosome} object. */ /* * protected Chromosome getBest(Chromosome chromosome1, Chromosome * chromosome2) { if (isBetterOrEqual(chromosome1, chromosome2)) return * chromosome1; else return chromosome2; } */ /** * Prints out all information regarding this GAs stopping conditions * * So far only used for testing purposes in TestSuiteGenerator */ public void printBudget() { LoggingUtils.getEvoLogger().info("* GA-Budget:"); for (StoppingCondition sc : stoppingConditions) LoggingUtils.getEvoLogger().info("\t- " + sc.toString()); } /** *

* getBudgetString *

* * @return a {@link java.lang.String} object. */ public String getBudgetString() { String r = ""; for (StoppingCondition sc : stoppingConditions) r += sc.toString() + " "; return r; } /** * Returns the progress of the search. * * @return a value [0.0, 1.0] */ protected double progress() { long totalbudget = 0; long currentbudget = 0; for (StoppingCondition sc : this.stoppingConditions) { if (sc.getLimit() != 0) { totalbudget += sc.getLimit(); currentbudget += sc.getCurrentValue(); } } return (double) currentbudget / (double) totalbudget; } /* * private void writeObject(ObjectOutputStream oos) throws IOException { if * (listeners.contains(SearchStatistics.getInstance())) { * removeListener(SearchStatistics.getInstance()); oos.defaultWriteObject(); * oos.writeObject(Boolean.TRUE); // Write/save additional fields * oos.writeObject(SearchStatistics.getInstance()); } else { * oos.defaultWriteObject(); oos.writeObject(Boolean.FALSE); } } * * // assumes "static java.util.Date aDate;" declared private void * readObject(ObjectInputStream ois) throws ClassNotFoundException, * IOException { ois.defaultReadObject(); listeners = new * HashSet(); stoppingConditions = new * HashSet(); * * boolean addStatistics = (Boolean) ois.readObject(); if (addStatistics) { * SearchStatistics.setInstance((SearchStatistics) ois.readObject()); * addListener(SearchStatistics.getInstance()); } } */ }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy