【问题标题】:Apache Commons Optimization TroublesApache Commons 优化问题
【发布时间】:2013-06-01 18:06:34
【问题描述】:

我正在尝试使用 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)

【问题讨论】:

  • 发布完整的错误消息,包括堆栈跟踪。
  • BOBYQA 算法不支持线性或非线性约束,仅支持变量界限。我不是 100% 确定,但我实际上并不认为 Apache Commons Math 中的任何非线性 opt 算法都能够处理变量边界以外的约束。 Powell 的 COBYLA2 算法确实支持任意约束。我已经将原始实现的Fortran代码转换为Java,你可以找到它herehere

标签: java optimization multidimensional-array nonlinear-optimization


【解决方案1】:

直接查看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())。但是 BaseMultivariateOptimizer 中的 lowerBoundupperBound 仅在 optimize 调用中的优化数据包含边界信息时才设置。如果在对optimize 的调用中未设置边界,则您应该收到NullPointerException

看看BOBYQA test code,如果您将以下参数添加到optimize 调用中似乎就足够了:

SimpleBounds.unbounded(point.length)

话虽如此,我也不认为您将能够使用 Apache Commons Math 中的任何非线性优化器完全解决您的问题,因为据我所知,这些优化器中没有一个可以处理线性或非线性约束。我建议您查看例如 Michael Powell 的 COBYLA2 算法。我已经把这个算法的原始FORTRAN代码移植到Java了,你可以找到代码herehere

【讨论】:

  • 好的,所以我正在尝试 Jcobyla,但我对约束的表示有点困惑。假设我想要约束 500 = x[1] + x[0]。我将如何在计算函数中表示它。
  • @InspiredOne COBYLA2 中的约束应该被表述为使得每个约束函数都必须是非负的,即 C(x) >= 0乙>。我认为处理等式约束 C=e 的可行方法是将其表述为具有小容差的平方差 (Ce)^2 或重新制定以适合 COBYLA2 , tol - (Ce)^2 >= 0
  • 谢谢,解决了。我很高兴能继续我的项目。我被优化问题困扰了一个星期。你是最棒的:)
猜你喜欢
  • 1970-01-01
  • 2014-05-01
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
  • 1970-01-01
相关资源
最近更新 更多