AbstractionAndPrecisionFitnessFunction.java
package de.uka.ipd.sdq.beagle.core.judge;
import de.uka.ipd.sdq.beagle.core.ExternalCallParameter;
import de.uka.ipd.sdq.beagle.core.ResourceDemandingInternalAction;
import de.uka.ipd.sdq.beagle.core.SeffBranch;
import de.uka.ipd.sdq.beagle.core.SeffLoop;
import de.uka.ipd.sdq.beagle.core.evaluableexpressions.EvaluableExpression;
import de.uka.ipd.sdq.beagle.core.evaluableexpressions.EvaluableVariableAssignment;
import de.uka.ipd.sdq.beagle.core.measurement.BranchDecisionMeasurementResult;
import de.uka.ipd.sdq.beagle.core.measurement.LoopRepetitionCountMeasurementResult;
import de.uka.ipd.sdq.beagle.core.measurement.ParameterChangeMeasurementResult;
import de.uka.ipd.sdq.beagle.core.measurement.ResourceDemandMeasurementResult;
import org.apache.commons.lang3.Validate;
import java.util.Set;
/**
* Fitness function regarding abstract but precise expression as fittest. Naturally, these
* requirements contradict each other. This fitness function grades the expression finding
* the best compromise (reasonable abstracted but still precise enough to be meaningful)
* best.
*
* @author Joshua Gleitze
* @author Christoph Michelbach
*/
public class AbstractionAndPrecisionFitnessFunction implements EvaluableExpressionFitnessFunction {
/**
* Defines how important human-comprehensibility is compared to low computational
* complexity. Values are ϵ [0, 1]. The importance of computational complexity is
* {@code 1 - HUMAN_COMPREHENSIBILITY_VALUE}.
*/
private static final double HUMAN_COMPREHENSIBILITY_VALUE = .5d;
/**
* Defines how important human-comprehensibility and low computational complexity are
* compared to precision. The importance of precision is {@code 1 - NICE_VALUE}.
*/
private static final double NICE_VALUE = .2d;
/**
* Norms the human-comprehensibility.
*/
private static final double HUMAN_COMPREHENSIBILITY_NORMATION = .01d;
/**
* Norms the computational complexity.
*/
private static final double COMPUTATIONIONAL_COMPLEXITY_NORMATION = .01d;
@Override
public double gradeFor(final ResourceDemandingInternalAction rdia, final EvaluableExpression expression,
final EvaluableExpressionFitnessFunctionBlackboardView blackboard) {
Validate.notNull(rdia);
Validate.notNull(expression);
Validate.notNull(blackboard);
final Set<ResourceDemandMeasurementResult> resourceDemandMeasurementResults =
blackboard.getMeasurementResultsFor(rdia);
// If there is no expression, return infinity.
if (resourceDemandMeasurementResults.size() == 0) {
return Double.POSITIVE_INFINITY;
}
double meanSquareDeviation = 0;
for (final ResourceDemandMeasurementResult resourceDemandMeasurementResult : resourceDemandMeasurementResults) {
final double realValue = resourceDemandMeasurementResult.getValue();
// final Parameterisation parameterisation =
// resourceDemandMeasurementResult.getParameterisation();
final EvaluableVariableAssignment evaluableVariableAssignment = new EvaluableVariableAssignment();
final double predictedValue = expression.evaluate(evaluableVariableAssignment);
final double squareDeviation = Math.pow(Math.abs(realValue) - Math.abs(predictedValue), 2);
meanSquareDeviation += squareDeviation / resourceDemandMeasurementResults.size();
}
return this.determineFitnessValue(expression, meanSquareDeviation);
}
@Override
public double gradeFor(final SeffBranch branch, final EvaluableExpression expression,
final EvaluableExpressionFitnessFunctionBlackboardView blackboard) {
Validate.notNull(branch);
Validate.notNull(expression);
Validate.notNull(blackboard);
final Set<BranchDecisionMeasurementResult> branchDecisionMeasurementResults =
blackboard.getMeasurementResultsFor(branch);
// If there is no expression, return infinity.
if (branchDecisionMeasurementResults.size() == 0) {
return Double.POSITIVE_INFINITY;
}
double meanSquareDeviation = 0;
for (final BranchDecisionMeasurementResult branchDecisionMeasurementResult : branchDecisionMeasurementResults) {
final double realValue = branchDecisionMeasurementResult.getBranchIndex();
// final Parameterisation parameterisation =
// branchDecisionMeasurementResult.getParameterisation();
final EvaluableVariableAssignment evaluableVariableAssignment = new EvaluableVariableAssignment();
final double predictedValue = expression.evaluate(evaluableVariableAssignment);
final double squareDeviation = Math.pow(Math.abs(realValue) - Math.abs(predictedValue), 2);
meanSquareDeviation += squareDeviation / branchDecisionMeasurementResults.size();
}
return this.determineFitnessValue(expression, meanSquareDeviation);
}
@Override
public double gradeFor(final SeffLoop loop, final EvaluableExpression expression,
final EvaluableExpressionFitnessFunctionBlackboardView blackboard) {
Validate.notNull(loop);
Validate.notNull(expression);
Validate.notNull(blackboard);
final Set<LoopRepetitionCountMeasurementResult> loopRepetitionCountMeasurementResults =
blackboard.getMeasurementResultsFor(loop);
// If there is no expression, return infinity.
if (loopRepetitionCountMeasurementResults.size() == 0) {
return Double.POSITIVE_INFINITY;
}
double meanSquareDeviation = 0;
// @formatter:off
for (final LoopRepetitionCountMeasurementResult loopRepetitionCountMeasurementResult
: loopRepetitionCountMeasurementResults) {
// @formatter:on
final double realValue = loopRepetitionCountMeasurementResult.getCount();
// final Parameterisation parameterisation =
// loopRepetitionCountMeasurementResult.getParameterisation();
final EvaluableVariableAssignment evaluableVariableAssignment = new EvaluableVariableAssignment();
final double predictedValue = expression.evaluate(evaluableVariableAssignment);
final double squareDeviation = Math.pow(Math.abs(realValue) - Math.abs(predictedValue), 2);
meanSquareDeviation += squareDeviation / loopRepetitionCountMeasurementResults.size();
}
return this.determineFitnessValue(expression, meanSquareDeviation);
}
@Override
public double gradeFor(final ExternalCallParameter parameter, final EvaluableExpression expression,
final EvaluableExpressionFitnessFunctionBlackboardView blackboard) {
Validate.notNull(parameter);
Validate.notNull(expression);
Validate.notNull(blackboard);
final Set<ParameterChangeMeasurementResult> parameterChangeMeasurementResults =
blackboard.getMeasurementResultsFor(parameter);
// If there is no expression, return infinity.
if (parameterChangeMeasurementResults.size() == 0) {
return Double.POSITIVE_INFINITY;
}
double meanSquareDeviation = 0;
for (final ParameterChangeMeasurementResult parameterChangeMeasurementResult : parameterChangeMeasurementResults) {
final double realValue = parameterChangeMeasurementResult.getCount();
// final Parameterisation parameterisation =
// parameterChangeMeasurementResult.getParameterisation();
final EvaluableVariableAssignment evaluableVariableAssignment = new EvaluableVariableAssignment();
final double predictedValue = expression.evaluate(evaluableVariableAssignment);
final double squareDeviation = Math.pow(Math.abs(realValue) - Math.abs(predictedValue), 2);
meanSquareDeviation += squareDeviation / parameterChangeMeasurementResults.size();
}
return this.determineFitnessValue(expression, meanSquareDeviation);
}
/**
* Determines the fitness value of {@code expression}.
*
* @param expression The {@link EvaluableExpression}.
* @param meanSquareDeviation The mean square deviation of {@code expression} from the
* measured values.
* @return The fitness value of {@code expression}.
*/
private double determineFitnessValue(final EvaluableExpression expression, final double meanSquareDeviation) {
final EvaluableExpressionComplexityAnalyser evaluableExpressionComplexityAnalyser =
new EvaluableExpressionComplexityAnalyser();
evaluableExpressionComplexityAnalyser.determineComplexity(expression);
final double humanComprehensibilityComplexity =
evaluableExpressionComplexityAnalyser.getHumanComprehensibilityComplexitySum()
* HUMAN_COMPREHENSIBILITY_NORMATION;
final double computationalComplexity = evaluableExpressionComplexityAnalyser.getComputationalComplexitySum()
* COMPUTATIONIONAL_COMPLEXITY_NORMATION;
final double combinedComplexity = HUMAN_COMPREHENSIBILITY_VALUE * humanComprehensibilityComplexity
+ (1 - HUMAN_COMPREHENSIBILITY_VALUE) * computationalComplexity;
return NICE_VALUE * combinedComplexity + (1 - NICE_VALUE) * meanSquareDeviation;
}
}