Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache Commons Optimization Troubles

I'm trying to solve a constrained non-linear 267 dimensional optimization problem with the java optimization library supplied by Apache Commons.

After 3 days of deciphering, this is what I have:

public class optimize2 {

public static void main(String []args){

    double[] point = {1.,2.};
    double[] cost = {3., 2.};
    MultivariateFunction function = new MultivariateFunction() {
            public double value(double[] point) {
                    double x = point[0];
                    double y = point[1];
                    return x * y;
            }
    };


    MultivariateOptimizer optimize = new BOBYQAOptimizer(5);
    optimize.optimize(
            new MaxEval(200),
            GoalType.MAXIMIZE,
            new InitialGuess(point),
            new ObjectiveFunction(function),
            new LinearConstraint(cost, Relationship.EQ, 30));
}

}

For whatever reason optimize.optimize() is throwing a null pointer error. Maybe I'm just being dumb but I can't figure out how to get this to work.

Here is the error:

Exception in thread "main" java.lang.NullPointerException at org.apache.commons.math3.optim.nonlinear.scalar.noderiv.BOBYQAOptimizer.setup(BOBYQAOptimizer.java:2401) at org.apache.commons.math3.optim.nonlinear.scalar.noderiv.BOBYQAOptimizer.doOptimize(BOBYQAOptimizer.java:236) at org.apache.commons.math3.optim.nonlinear.scalar.noderiv.BOBYQAOptimizer.doOptimize(BOBYQAOptimizer.java:49) at org.apache.commons.math3.optim.BaseOptimizer.optimize(BaseOptimizer.java:143) at org.apache.commons.math3.optim.BaseMultivariateOptimizer.optimize(BaseMultivariateOptimizer.java:66) at org.apache.commons.math3.optim.nonlinear.scalar.MultivariateOptimizer.optimize(MultivariateOptimizer.java:64) at Test.Code.optimize2.main(optimize2.java:39)

like image 309
Kammeot Avatar asked Jun 05 '13 21:06

Kammeot


1 Answers

Looking directly into the BOBYQA code, it actually seems like the problem is that you have not explicitly defined any variable bounds. Line 2401 (setup method) reads as follows:

boundDifference[i] = upperBound[i] - lowerBound[i];

In the doOptimze method, prior to calling setup the bounds are set using these methods:

final double[] lowerBound = getLowerBound();
final double[] upperBound = getUpperBound();

These methods are defined in BaseMultivariateOptimizer like this:

public double[] getLowerBound() {
    return lowerBound == null ? null : lowerBound.clone();
}

(and analogously for getUpperBound()). But lowerBound and upperBound in BaseMultivariateOptimizer are only set if the optimization data in the optimize call contains bounds information. If the bounds are not set in the call to optimize, you should therefore receive a NullPointerException.

Looking at the BOBYQA test code it seems like it should be sufficient if you add the following argument to the optimize call:

SimpleBounds.unbounded(point.length)

Having said that, I also do not think you will be able to completely solve your problem using any of the nonlinear optimizers in Apache Commons Math, since as far as I can tell none of these optimizers can handle linear or nonlinear constraints. I recommend that you take a look at for example Michael Powell's COBYLA2 algorithm instead. I have migrated the original FORTRAN code of this algorithm to Java, and you can find the code here and here.

like image 87
Anders Gustafsson Avatar answered Sep 27 '22 23:09

Anders Gustafsson