4

我試圖用Apache Commons提供的java優化庫解決約束非線性267維優化問題。Apache Commons優化問題

破譯後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()拋出空指針錯誤。也許我只是愚蠢的,但我不知道如何讓這個工作。

以下是錯誤:在螺紋

異常 「主」 顯示java.lang.NullPointerException 在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。 (org.apache.commons.math3.optim.BaseOptimizer.optimize(BaseOptimizer.java:143) at 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

發佈包含堆棧跟蹤的完整錯誤消息。 – jlordo

+0

* BOBYQA *算法不支持線性或非線性約束,僅支持可變邊界。我不是100%確定,但我並不認爲* Apache Commons Math *中的任何非線性可選算法都能夠處理變量邊界以外的約束。鮑威爾的* COBYLA2 *算法確實支持任意約束。我已經將原始實現的Fortran代碼轉換爲Java,你可以在這裏找到它(https://github.com/cureos/jcobyla)和[here](http://www.codeproject.com/Articles/ 508513 /免費非線性微分 - 優化 - 對-NET-和)。 –

回答

4

直視BOBYQA code,它實際上好像問題是你沒有明確定義任何變量邊界。 2401行(setup方法)如下:

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

這些方法在BaseMultivariateOptimizer定義是這樣的:

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

doOptimze方法中,在主叫setup邊界時才使用這些方法設置爲:

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

(和類似地用於getUpperBound())。但lowerBoundupperBoundBaseMultivariateOptimizer僅在optimize調用中的優化數據包含邊界信息時纔會設置。如果在調用optimize時未設置邊界,則應該收到NullPointerException

看着它好像它,如果你添加下面的參數傳遞給optimize調用應該是足夠的BOBYQA test code

SimpleBounds.unbounded(point.length) 

話雖如此,我也不認爲你將能夠徹底解決您問題使用Apache Commons Math中的任何非線性優化器,因爲據我所知,這些優化器都不能處理線性或非線性約束。我建議您參考Michael Powell的COBYLA2算法。我已將此算法的原始FORTRAN代碼遷移到Java,並且您可以找到代碼herehere

+0

好的,所以我嘗試了Jcobyla,我對約束的表示有些困惑。假設我想約束500 = x [1] + x [0]。我將如何在計算功能中表示這一點。 – Kammeot

+2

@InspiredOne * COBYLA2 *中的約束條件應該使得每個約束函數都要求是非負的,即** C(x)> = 0 **。我認爲處理平等約束** C = e **的可行方法是將其表示爲具有小容差的平方差,**(Ce)^ 2 <= tol **或重新擬合以適合* COBYLA2 * ,** tol - (Ce)^ 2> = 0 **。 –

+1

謝謝,這清除了它。我很高興繼續我的項目。我一直堅持優化問題一週。你是最棒的 :) – Kammeot