我正在尝试使用Apache Commons提供的java优化库来解决受约束的非线性267维优化问题。
经过3天的破译,这就是我所拥有的:
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));
}
}
无论出于何种原因,optimize.optimize()都会抛出空指针错误。也许我只是愚蠢但我无法弄清楚如何让它发挥作用。
这是错误:
线程“main”java.lang.NullPointerException中的异常 在org.apache.commons.math3.optim.nonlinear.scalar.noderiv.BOBYQAOptimizer.setup(BOBYQAOptimizer.java:2401) 在org.apache.commons.math3.optim.nonlinear.scalar.noderiv.BOBYQAOptimizer.doOptimize(BOBYQAOptimizer.java:236) 在org.apache.commons.math3.optim.nonlinear.scalar.noderiv.BOBYQAOptimizer.doOptimize(BOBYQAOptimizer.java:49) 在org.apache.commons.math3.optim.BaseOptimizer.optimize(BaseOptimizer.java:143) 在org.apache.commons.math3.optim.BaseMultivariateOptimizer.optimize(BaseMultivariateOptimizer.java:66) 在org.apache.commons.math3.optim.nonlinear.scalar.MultivariateOptimizer.optimize(MultivariateOptimizer.java:64) 在Test.Code.optimize2.main(optimize2.java:39)
答案 0 :(得分:6)
直接查看BOBYQA code,实际上似乎问题是您没有明确定义任何变量边界。第2401行(setup
方法)内容如下:
boundDifference[i] = upperBound[i] - lowerBound[i];
在doOptimze
方法中,在调用setup
之前,使用以下方法设置边界:
final double[] lowerBound = getLowerBound();
final double[] upperBound = getUpperBound();
这些方法在BaseMultivariateOptimizer中定义如下:
public double[] getLowerBound() {
return lowerBound == null ? null : lowerBound.clone();
}
(类似于getUpperBound()
)。但只有lowerBound
调用中的优化数据包含边界信息时,才会设置 BaseMultivariateOptimizer 中的upperBound
和optimize
。如果未在optimize
的调用中设置边界,则应收到NullPointerException
。
查看BOBYQA test code,如果您将以下参数添加到optimize
调用中,它似乎就足够了:
SimpleBounds.unbounded(point.length)
话虽如此,我也认为您无法使用 Apache Commons Math 中的任何非线性优化器完全解决您的问题,因为据我所知,这些优化器都没有可以处理线性或非线性约束。我建议你看一下例如Michael Powell的 COBYLA2 算法。我已将此算法的原始FORTRAN代码迁移到Java,您可以找到代码here和here。