Commit d518c042 authored by Daniel Lehmberg's avatar Daniel Lehmberg
Browse files

WIP: almost finished test (bug search)

parent db01a353
......@@ -10,7 +10,15 @@
"attributesType" : "org.vadere.state.attributes.processor.AttributesTestOptimizationMetricProcessor",
"attributes" : {
"expectedResult" : "SUCCESS",
"optimizationMetricProcessorId" : 2
"optimizationMetricProcessorId" : 2,
"maxMeanPointDistance" : 0.0,
"maxMeanDifferenceFuncValue" : 0.0,
"infoMinPointDistanceL2" : 0.0,
"infoMaxPointDistanceL2" : 0.0,
"infoMinFuncDifference" : 0.0,
"infoMaxFuncDifference" : 0.0,
"infoStddevPointDistance" : 0.0,
"infoStddevDifferenceFuncValue" : 0.0
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianMetricOptimizationProcessor",
......
......@@ -10,7 +10,15 @@
"attributesType" : "org.vadere.state.attributes.processor.AttributesTestOptimizationMetricProcessor",
"attributes" : {
"expectedResult" : "SUCCESS",
"optimizationMetricProcessorId" : 2
"optimizationMetricProcessorId" : 2,
"maxMeanPointDistance" : 0.0,
"maxMeanDifferenceFuncValue" : 0.0,
"infoMinPointDistanceL2" : 0.0,
"infoMaxPointDistanceL2" : 0.0,
"infoMinFuncDifference" : 0.0,
"infoMaxFuncDifference" : 0.0,
"infoStddevPointDistance" : 0.0,
"infoStddevDifferenceFuncValue" : 0.0
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianMetricOptimizationProcessor",
......@@ -42,10 +50,10 @@
}
},
"org.vadere.state.attributes.models.AttributesOSM" : {
"stepCircleResolution" : 4,
"stepCircleResolution" : 1,
"numberOfCircles" : 1,
"optimizationType" : "NELDER_MEAD",
"varyStepDirection" : true,
"varyStepDirection" : false,
"movementType" : "ARBITRARY",
"stepLengthIntercept" : 0.4625,
"stepLengthSlopeSpeed" : 0.2345,
......
......@@ -10,7 +10,15 @@
"attributesType" : "org.vadere.state.attributes.processor.AttributesTestOptimizationMetricProcessor",
"attributes" : {
"expectedResult" : "SUCCESS",
"optimizationMetricProcessorId" : 2
"optimizationMetricProcessorId" : 2,
"maxMeanPointDistance" : 0.0,
"maxMeanDifferenceFuncValue" : 0.0,
"infoMinPointDistanceL2" : 0.0,
"infoMaxPointDistanceL2" : 0.0,
"infoMinFuncDifference" : 0.0,
"infoMaxFuncDifference" : 0.0,
"infoStddevPointDistance" : 0.0,
"infoStddevDifferenceFuncValue" : 0.0
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianMetricOptimizationProcessor",
......
......@@ -10,7 +10,15 @@
"attributesType" : "org.vadere.state.attributes.processor.AttributesTestOptimizationMetricProcessor",
"attributes" : {
"expectedResult" : "SUCCESS",
"optimizationMetricProcessorId" : 2
"optimizationMetricProcessorId" : 2,
"maxMeanPointDistance" : 0.0,
"maxMeanDifferenceFuncValue" : 0.0,
"infoMinPointDistanceL2" : 0.0,
"infoMaxPointDistanceL2" : 0.0,
"infoMinFuncDifference" : 0.0,
"infoMaxFuncDifference" : 0.0,
"infoStddevPointDistance" : 0.0,
"infoStddevDifferenceFuncValue" : 0.0
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianMetricOptimizationProcessor",
......
package org.vadere.simulator.models.osm.optimization;
import org.vadere.simulator.projects.dataprocessing.processor.tests.TestOptimizationMetricNelderMeadProcessor;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.logging.Logger;
/**
* Stores the values of the true solution (which can be computed analytically or by brute force) and the solution that
......@@ -33,6 +35,14 @@ public class OptimizationMetric {
this.foundPoint = foundPoint;
this.foundFuncValue = foundFuncValue;
if(optimalFuncValue > foundFuncValue){
Logger.getLogger(TestOptimizationMetricNelderMeadProcessor.class).warn(
"Found optimal value is better than brute force. This can indicate that the " +
"brute force is not fine grained enough. BRUTE FORCE: " + optimalFuncValue +
" OPTIMIZER: " + foundFuncValue);
}
}
public double getSimTime() {
......
......@@ -57,7 +57,6 @@ public abstract class StepCircleOptimizer {
}
}
protected boolean getComputeMetric(){
return computeMetric;
}
......@@ -70,14 +69,14 @@ public abstract class StepCircleOptimizer {
var bruteForceMethod = new StepCircleOptimizerDiscrete(0, new Random());
VPoint optimalPoint = bruteForceMethod.getNextPosition(pedestrian, getReachablePositions(reachableArea),
reachableArea.getRadius());
reachableArea.getRadius(), true);
double optimalFuncValue; // -1 = invalid number
try{
optimalFuncValue = potentialEvaluationFunction.getValue(optimalPoint);
}catch (Exception e) {
Logger.getLogger(StepCircleOptimizerDiscrete.class).error("Potential evaluation threw error. " +
"Setting value to invalid (-1)");
Logger.getLogger(StepCircleOptimizerDiscrete.class).error("Potential evaluation for computing the brute " +
"force solution threw error. Setting value to invalid (-1).");
optimalFuncValue = -1;
}
......@@ -112,9 +111,9 @@ public abstract class StepCircleOptimizer {
null,
false,
reachableArea,
30,
5000,
100,
100000,
0,
2 * Math.PI);
2.0 * Math.PI);
}
}
......@@ -37,10 +37,15 @@ public class StepCircleOptimizerDiscrete extends StepCircleOptimizer {
double stepSize = ((VCircle) reachableArea).getRadius();
List<VPoint> positions = getReachablePositions(pedestrian, (VCircle) reachableArea, random);
return getNextPosition(pedestrian, positions, stepSize);
return getNextPosition(pedestrian, positions, stepSize, false);
}
public VPoint getNextPosition(@NotNull final PedestrianOSM pedestrian, List<VPoint> positions, double stepSize){
public VPoint getNextPosition(@NotNull final PedestrianOSM pedestrian, final List<VPoint> positions,
final double stepSize, final boolean bruteForce){
/*bruteForce gets exactly the best (numerical) position among the tested 'positions' without any side
* conditions.
* */
PotentialEvaluationFunction potentialEvaluationFunction = new PotentialEvaluationFunction(pedestrian);
potentialEvaluationFunction.setStepSize(stepSize);
......@@ -49,17 +54,19 @@ public class StepCircleOptimizerDiscrete extends StepCircleOptimizer {
VPoint nextPos = curPos.clone();
double curPosPotential = pedestrian.getPotential(curPos);
double potential = curPosPotential;
double tmpPotential = 0;
double currentPotential = 0;
for (VPoint tmpPos : positions) {
for (VPoint currentPosition : positions) {
try {
tmpPotential = potentialEvaluationFunction.getValue(tmpPos);
currentPotential = potentialEvaluationFunction.getValue(currentPosition);
// DL: it is not exactly clear how this condition works (where is the value 0.0001 coming from?, Why
// is there a random boolean?
boolean fineTuneCondition = (Math.abs(currentPotential - potential) <= 0.0001 && random.nextBoolean());
if (tmpPotential < potential
|| (Math.abs(tmpPotential - potential) <= 0.0001 && random
.nextBoolean())) {
potential = tmpPotential;
nextPos = tmpPos;
if (currentPotential < potential || (bruteForce || fineTuneCondition)) {
potential = currentPotential;
nextPos = currentPosition;
}
} catch (Exception e) {
Logger.getLogger(StepCircleOptimizerDiscrete.class).error("Potential evaluation threw an topographyError.");
......@@ -67,7 +74,7 @@ public class StepCircleOptimizerDiscrete extends StepCircleOptimizer {
}
if (curPosPotential - potential <= movementThreshold) {
if (bruteForce || curPosPotential - potential <= movementThreshold) {
nextPos = curPos;
}
......
......@@ -36,7 +36,6 @@ public class TestOptimizationMetricNelderMeadProcessor extends TestProcessor {
public TestOptimizationMetricNelderMeadProcessor() {
super("test-pedestrianMetricOptimizationProcessor");
// TODO: for now there are no Attributes needed, but maybe it is possible to the test cases via attributes?
setAttributes(new AttributesTestOptimizationMetricProcessor());
}
......@@ -44,13 +43,13 @@ public class TestOptimizationMetricNelderMeadProcessor extends TestProcessor {
public void init(@NotNull final ProcessorManager manager) {
super.init(manager);
// will be set by during "doUpdate", because the name is only accessible via the SimualtionState
// will be set by during "doUpdate", because the name is only accessible via the SimulationState
this.scenarioName = null;
AttributesTestOptimizationMetricProcessor att = this.getAttributes();
pedestrianMetricOptimizationProcessor =
(PedestrianMetricOptimizationProcessor) manager.getProcessor(
att.getOptimizationMetricNelderMeadProcessor());
att.getOptimizationMetricProcessorId());
}
@Override
......@@ -60,7 +59,7 @@ public class TestOptimizationMetricNelderMeadProcessor extends TestProcessor {
this.scenarioName = state.getName();
}else{
if(!this.scenarioName.equals(state.getName())){
throw new RuntimeException("This should never happen!");
throw new RuntimeException("The scenario name should never get changed during simulation!");
}
}
......@@ -80,32 +79,71 @@ public class TestOptimizationMetricNelderMeadProcessor extends TestProcessor {
ArrayList<Double> pointDistanceL2Values = new ArrayList<>();
ArrayList<Double> differenceFuncValues = new ArrayList<>();
for(OptimizationMetric singleMetic : processorData.values()){
for(OptimizationMetric singleMetric : processorData.values()){
pointDistanceL2Values.add(singleMetic.getOptimalPoint().distance(singleMetic.getFoundPoint()));
pointDistanceL2Values.add(singleMetric.getOptimalPoint().distance(singleMetric.getFoundPoint()));
// Insert all values for difference in the function values.
if(singleMetic.getOptimalFuncValue() > singleMetic.getFoundFuncValue()){
Logger.getLogger(TestOptimizationMetricNelderMeadProcessor.class).warn(
"Found optimal value is better than brute force. This can indicate that the " +
"brute force is not fine grained enough.");
}
differenceFuncValues.add(singleMetic.getOptimalFuncValue() - singleMetic.getFoundFuncValue());
differenceFuncValues.add(singleMetric.getOptimalFuncValue() - singleMetric.getFoundFuncValue());
}
var metricStatistics = computeStatistics(pointDistanceL2Values, differenceFuncValues);
printStatistics(metricStatistics);
// TODO: test also that all pedestrian get to the target, this is required for optimization.
AttributesTestOptimizationMetricProcessor attr = this.getAttributes();
String msg = getCompareValuesString("mean difference in point distance",
metricStatistics.get("meanPointDistance"), attr.getMaxMeanPointDistance());
handleAssertion(metricStatistics.get("meanPointDistance")<=attr.getMaxMeanPointDistance(), msg);
msg = getCompareValuesString("mean difference in function value",
metricStatistics.get("meanDifferenceFuncValue"), attr.getMaxMeanPointDistance());
handleAssertion(
metricStatistics.get("meanDifferenceFuncValue")<=attr.getMaxMeanDifferenceFuncValue(), msg);
}
private String getCompareValuesString(String valueName, double newValue, double referenceValue){
double diff = newValue - referenceValue;
String msg;
if(newValue < referenceValue){
msg = "POSITIVE -- The statistics '" + valueName + "' decreased by " + diff
+ " (BEFORE:" + referenceValue + " NOW: " + newValue + ")";
}else if(newValue > referenceValue){
msg = "NEGATIVE -- The statistics '" + valueName + "' increased by " + diff +
" (BEFORE:" + referenceValue + " NOW: " + newValue + ")";
}else{
msg = "NEUTRAL -- The statistics '" + valueName + "' is equal to the reference value.";
}
return msg;
}
private void printStatistics(HashMap<String, Double> statistics){
AttributesTestOptimizationMetricProcessor attr = this.getAttributes();
System.out.println("---------------------------------------------------------------");
System.out.println("OUTPUT FROM PedestrianMetricOptimizationProcessor: ");
System.out.println("SCENARIO: " + scenarioName);
System.out.println("STATISTICS: " + metricStatistics);
System.out.println("---------------------------------------------------------------");
System.out.println("######################################################################################");
System.out.println("######################################################################################");
System.out.println("######################################################################################");
System.out.println("INFORMATION FROM TestOptimizationMetricNelderMeadProcessor");
System.out.println();
System.out.println(getCompareValuesString("minimum point distance", statistics.get("minPointDistanceL2"), attr.getInfoMinPointDistanceL2()));
System.out.println(getCompareValuesString("maximum point distance", statistics.get("maxPointDistanceL2"), attr.getInfoMaxPointDistanceL2()));
System.out.println(getCompareValuesString("standard deviation point distance", statistics.get("stddevPointDistance"), attr.getInfoStddevPointDistance()));
System.out.println(getCompareValuesString("minimum function difference", statistics.get("minDifferenceFuncValue"), attr.getInfoMinFuncDifference()));
System.out.println(getCompareValuesString("maximum function difference", statistics.get("maxDifferenceFuncValue"), attr.getInfoMaxFuncDifference()));
System.out.println(getCompareValuesString("standard deviation function difference", statistics.get("stddevDifferenceFuncValue"), attr.getInfoStddevDifferenceFuncValue()));
System.out.println("######################################################################################");
System.out.println("######################################################################################");
// TODO: later on checks are required
/* String msg = invalidEvacuationTimes + "(#invalid evacuation times) <= " + 0;
handleAssertion(invalidEvacuationTimes <= 0, msg);*/
}
......@@ -151,7 +189,6 @@ public class TestOptimizationMetricNelderMeadProcessor extends TestProcessor {
}
@Override
public AttributesTestOptimizationMetricProcessor getAttributes() {
if (super.getAttributes() == null) {
......
......@@ -9,13 +9,57 @@ public class AttributesTestOptimizationMetricProcessor extends AttributesTestPro
private int optimizationMetricProcessorId;
public int getOptimizationMetricNelderMeadProcessor() {
checkSealed();
return this.optimizationMetricProcessorId;
/** Following have to be fulfilled (i.e. the mean has to be below this. If the mean increases the value, the
* processor will fail. */
private double maxMeanPointDistance;
private double maxMeanDifferenceFuncValue;
/** These are just for information and reference -- there is a print out the console that compares these
* the statistics.
*/
private double infoMinPointDistanceL2;
private double infoMaxPointDistanceL2;
private double infoMinFuncDifference;
private double infoMaxFuncDifference;
private double infoStddevPointDistance;
private double infoStddevDifferenceFuncValue;
public int getOptimizationMetricProcessorId() {
return optimizationMetricProcessorId;
}
public double getMaxMeanPointDistance() {
return maxMeanPointDistance;
}
public double getMaxMeanDifferenceFuncValue() {
return maxMeanDifferenceFuncValue;
}
public double getInfoMinPointDistanceL2() {
return infoMinPointDistanceL2;
}
public double getInfoMaxPointDistanceL2() {
return infoMaxPointDistanceL2;
}
public double getInfoStddevPointDistance() {
return infoStddevPointDistance;
}
public double getInfoStddevDifferenceFuncValue() {
return infoStddevDifferenceFuncValue;
}
public double getInfoMaxFuncDifference() {
return infoMaxFuncDifference;
}
public void setEvacuationTimeProcessorId(final int optimizationMetricProcessorId) {
checkSealed();
this.optimizationMetricProcessorId = optimizationMetricProcessorId;
public double getInfoMinFuncDifference() {
return infoMinFuncDifference;
}
}
......@@ -189,6 +189,7 @@ public class GeometryUtils {
final double anchorAngle,
final double angle) {
assert !varyDirection || random != null;
double randOffset = varyDirection ? random.nextDouble() : 0;
List<VPoint> reachablePositions = new ArrayList<>();
......@@ -201,8 +202,8 @@ public class GeometryUtils {
int numberOfGridPoints = (int) Math.ceil(circleOfGrid / circle.getRadius() * numberOfPointsOfLargestCircle);
// reduce number of grid points proportional to the constraint of direction
if (angle < 2 * Math.PI) {
numberOfGridPoints = (int) Math.ceil(numberOfGridPoints * angle / (2 * Math.PI));
if (angle < 2.0 * Math.PI) {
numberOfGridPoints = (int) Math.ceil(numberOfGridPoints * angle / (2.0 * Math.PI));
}
double angleDelta = angle / numberOfGridPoints;
......@@ -212,9 +213,7 @@ public class GeometryUtils {
double x = circleOfGrid * Math.cos(anchorAngle + angleDelta * (randOffset + i)) + circle.getCenter().getX();
double y = circleOfGrid * Math.sin(anchorAngle + angleDelta * (randOffset + i)) + circle.getCenter().getY();
VPoint tmpPos = new VPoint(x, y);
reachablePositions.add(tmpPos);
reachablePositions.add(new VPoint(x, y));
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment