org.evosuite.testcase.localsearch.FloatLocalSearch 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.testcase.localsearch;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.evosuite.ga.localsearch.LocalSearchBudget;
import org.evosuite.ga.localsearch.LocalSearchObjective;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.TestChromosome;
import org.evosuite.testcase.execution.ExecutionResult;
import org.evosuite.testcase.statements.numeric.NumericalPrimitiveStatement;
import org.evosuite.testsuite.localsearch.TestSuiteLocalSearchObjective;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* FloatLocalSearch class.
*
*
* @author Gordon Fraser
*/
public class FloatLocalSearch extends StatementLocalSearch {
private static final Logger logger = LoggerFactory.getLogger(TestCaseLocalSearch.class);
private T oldValue;
/* (non-Javadoc)
* @see org.evosuite.testcase.LocalSearch#doSearch(org.evosuite.testcase.TestChromosome, int, org.evosuite.ga.LocalSearchObjective)
*/
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public boolean doSearch(TestChromosome test, int statement,
LocalSearchObjective objective) {
TestCase slice = test.getTestCase().clone();
int newPos = slice.sliceFor(slice.getStatement(statement).getReturnValue());
TestCase oldTest = test.getTestCase();
test.setTestCase(slice);
test.setChanged(true);
/**
* Commenting the call to getCopyForTest(). It seems unusual that fitness
* should be considered on a new test suite instead of the original objective
*/
// objective = ((TestSuiteLocalSearchObjective)objective).getCopyForTest(test);
int oldStatement = statement;
statement = newPos;
boolean improved = false;
NumericalPrimitiveStatement p = (NumericalPrimitiveStatement) test.getTestCase().getStatement(statement);
double value = p.getValue().doubleValue();
if (Double.isInfinite(value) || Double.isNaN(value)) {
return false;
}
logger.info("Applying search to: " + p.getCode());
int change = doSearch(test, statement, objective, 1.0, 2, p);
if(change != 0)
improved = true;
else { // if(change == 0) {
// Only apply search after the comma if the fitness was affected by the first part of the search
logger.info("Stopping search as variable doesn't influence fitness");
test.setTestCase(oldTest);
return improved;
}
logger.info("Checking after the comma: " + p.getCode());
int maxPrecision = p.getValue().getClass().equals(Float.class) ? 7 : 15;
for (int precision = 1; precision <= maxPrecision; precision++) {
if(LocalSearchBudget.getInstance().isFinished())
break;
roundPrecision(test, objective, precision, p);
logger.debug("Current precision: " + precision);
change = doSearch(test, statement, objective, Math.pow(10.0, -precision), 2, p);
if(change < 0)
improved = true;
}
logger.debug("Finished local search with result " + p.getCode());
if(improved) {
NumericalPrimitiveStatement ps = (NumericalPrimitiveStatement) oldTest.getStatement(oldStatement);
ps.setValue(p.getValue());
}
test.setChanged(true);
test.setTestCase(oldTest);
return improved;
}
@SuppressWarnings("unchecked")
private boolean roundPrecision(TestChromosome test,
LocalSearchObjective objective, int precision,
NumericalPrimitiveStatement p) {
double value = p.getValue().doubleValue();
if (Double.isInfinite(value) || Double.isNaN(value)) {
return false;
}
BigDecimal bd = new BigDecimal(value).setScale(precision, RoundingMode.HALF_EVEN);
if (bd.doubleValue() == value) {
return false;
}
double newValue = bd.doubleValue();
oldValue = p.getValue();
ExecutionResult oldResult = test.getLastExecutionResult();
if (p.getValue().getClass().equals(Float.class))
p.setValue((T) (new Float(newValue)));
else
p.setValue((T) (new Double(newValue)));
logger.info("Trying to chop precision " + precision + ": " + value + " -> "
+ newValue);
if (objective.hasNotWorsened(test)) {
return true;
} else {
logger.info("Restoring old value: "+value);
p.setValue(oldValue);
test.setLastExecutionResult(oldResult);
test.setChanged(false);
return false;
}
}
private int doSearch(TestChromosome test, int statement,
LocalSearchObjective objective, double initialDelta, double factor,
NumericalPrimitiveStatement p) {
int changed = 0;
oldValue = p.getValue();
ExecutionResult oldResult = test.getLastExecutionResult();
boolean done = false;
while (!done) {
done = true;
// Try +1
p.increment(initialDelta);
logger.info("Trying increment of " + p.getCode());
//logger.info(" -> " + p.getCode());
int change = objective.hasChanged(test);
if(change != 0)
changed = change;
if (change < 0) {
done = false;
// changed = true;
iterate(factor * initialDelta, factor, objective, test, p, statement);
oldValue = p.getValue();
oldResult = test.getLastExecutionResult();
} else {
// Restore original, try -1
p.setValue(oldValue);
test.setLastExecutionResult(oldResult);
test.setChanged(false);
p.increment(-initialDelta);
logger.info("Trying decrement of " + p.getCode());
//logger.info(" -> " + p.getCode());
change = objective.hasChanged(test);
if (change < 0) {
logger.info("Iterating because of improvement");
changed = change;
done = false;
iterate(-factor * initialDelta, factor, objective, test, p, statement);
oldValue = p.getValue();
oldResult = test.getLastExecutionResult();
} else {
logger.info("Not iterating because no improvement");
p.setValue(oldValue);
test.setLastExecutionResult(oldResult);
test.setChanged(false);
}
}
}
logger.debug("Finished local search with result " + p.getCode());
return changed;
}
private boolean iterate(double delta, double factor, LocalSearchObjective objective,
TestChromosome test, NumericalPrimitiveStatement p, int statement) {
boolean improvement = false;
T oldValue = p.getValue();
ExecutionResult oldResult = test.getLastExecutionResult();
logger.info("Trying increment " + delta + " of " + p.getCode());
p.increment(delta);
while (objective.hasImproved(test)) {
oldValue = p.getValue();
oldResult = test.getLastExecutionResult();
test.setChanged(false);
improvement = true;
delta = factor * delta;
//if (delta > 1)
// return improvement;
logger.info("Trying increment " + delta + " of " + p.getCode());
p.increment(delta);
}
p.setValue(oldValue);
test.setLastExecutionResult(oldResult);
test.setChanged(false);
return improvement;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy