package net.sf.openrocket.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import net.sf.openrocket.optimization.general.Function;
import net.sf.openrocket.optimization.general.FunctionOptimizer;
import net.sf.openrocket.optimization.general.OptimizationController;
import net.sf.openrocket.optimization.general.OptimizationException;
import net.sf.openrocket.optimization.general.ParallelExecutorCache;
import net.sf.openrocket.optimization.general.Point;
import net.sf.openrocket.optimization.general.multidim.MultidirectionalSearchOptimizer;
import net.sf.openrocket.util.MathUtil;
public class TestFunctionOptimizerLoop {
private static final double PRECISION = 0.01;
private int stepCount = 0;
private int evaluations = 0;
private void go(final FunctionOptimizer optimizer, final Point optimum, final int maxSteps, ExecutorService executor) throws OptimizationException {
Function function = new Function() {
@Override
public double evaluate(Point p) throws InterruptedException {
evaluations++;
return p.sub(optimum).length2();
}
};
OptimizationController control = new OptimizationController() {
@Override
public boolean stepTaken(Point oldPoint, double oldValue, Point newPoint, double newValue, double stepSize) {
stepCount++;
if (stepCount % 1000 == 0) {
System.err.println("WARNING: Over " + stepCount + " steps required for optimum=" + optimum +
" position=" + newPoint);
}
double distance = newPoint.sub(optimum).length();
return distance >= PRECISION;
}
};
;
ParallelExecutorCache cache = new ParallelExecutorCache(executor);
cache.setFunction(function);
optimizer.setFunctionCache(cache);
optimizer.optimize(new Point(optimum.dim(), 0.5), control);
}
public static void main(String[] args) throws OptimizationException {
System.err.println("PRECISION = " + PRECISION);
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
for (int dim = 1; dim <= 10; dim++) {
List<Integer> stepCount = new ArrayList<Integer>();
List<Integer> functionCount = new ArrayList<Integer>();
MultidirectionalSearchOptimizer optimizer = new MultidirectionalSearchOptimizer();
for (int count = 0; count < 200; count++) {
TestFunctionOptimizerLoop test = new TestFunctionOptimizerLoop();
double[] point = new double[dim];
for (int i = 0; i < dim; i++) {
point[i] = Math.random();
}
// point[0] = 0.7;
test.go(optimizer, new Point(point), 20, executor);
stepCount.add(test.stepCount);
functionCount.add(test.evaluations);
}
// System.err.println("StepCount = " + stepCount);
System.out.printf("dim=%d Steps avg=%5.2f dev=%5.2f median=%.1f " +
"Evaluations avg=%5.2f dev=%5.2f median=%.1f\n",
dim, MathUtil.average(stepCount), MathUtil.stddev(stepCount), MathUtil.median(stepCount),
MathUtil.average(functionCount), MathUtil.stddev(functionCount), MathUtil.median(functionCount));
System.out.println("stat: " + optimizer.getStatistics());
}
executor.shutdownNow();
}
}