Java中的线性/二次方程求解

时间:2018-06-01 17:37:11

标签: java mathematical-optimization linear-programming quadratic-programming

我有一套"线性"基于this paper约束的方程,以便从目标函数中找到梯度m和延迟b1,如下所示:

目标函数= 2y - ((24538 + 1660b1)/ 566400)x - 2b1> = 0

约束函数=

  • y - ((12.7-b1)/ 480)x-b1> = 0
  • y - ((19.9-b1)/ 1180)x - b1> = 0
  • (19.9-b1)/ 1180)> = 0.01
  • (12.7-b1)/ 480)> = 0.01

问题在于,因为它使用了3个变量(x,y,b1),而b1乘以x它以某种方式使它成为二次规划而我很困惑如何解决这个问题甚至在代码中使用它来代表它几个Java库,如ojalgo或JOptimizer。

如何使用上述库以程序方式解决此问题?

1 个答案:

答案 0 :(得分:0)

根据我的理解,你的功能不是二次方。 (也许把这个问题交给math.stackexchange.com)。

我已经使用 JOptimizer ,发现它对于线性问题非常有能力和快速但从未将它用于非线性问题。但是,JOptimizer网站确实有它可以解决的各种非线性问题的例子。

为了支持这一点,JOptimizer有一个名为ConvexMultivariateRealFunction的类,您可以使用它来表示您的函数。基本上,在您的类的实现中,您编写的函数返回函数的值,它的渐变,以及函数的任何给定输入集的Hessian矩阵。

如何为您的特定函数执行所有操作是一个数学问题,以及您的函数是否满足JOptimizer能够满足的限制的问题(例如,函数需要两次可微分)。

以下是ConvexMultivariateRealFunction的示例(摘自JOptimizer网站)。您可以看到value实现包含自变量之间的除法,加上取幂 - 所以绝对不是线性的!

inequalities[1] = new ConvexMultivariateRealFunction() {

            public double value(DoubleMatrix1D X) {
                double y0 = X.getQuick(0);
                double y1 = X.getQuick(1);
                double t =  X.getQuick(2);
                return t * (Math.pow(y0 / t - c0, 2) + Math.pow(y1 / t - c1, 2) - Math.pow(R, 2));
            }

            public DoubleMatrix1D gradient(DoubleMatrix1D X) {
                double y0 = X.getQuick(0);
                double y1 = X.getQuick(1);
                double t =  X.getQuick(2);
                double[] ret = new double[3];
                ret[0] = 2 * (y0/t - c0);
                ret[1] = 2 * (y1/t - c1);
                ret[2] = Math.pow(c0, 2) + Math.pow(c1, 2) - Math.pow(R, 2) - (Math.pow(y0, 2) + Math.pow(y1, 2))/Math.pow(t, 2);
                return F1.make(ret);
            }

            public DoubleMatrix2D hessian(DoubleMatrix1D X) {
                double y0 = X.getQuick(0);
                double y1 = X.getQuick(1);
                double t =  X.getQuick(2);
                double[][] ret = {
                    {                2/t,                   0, -2*y0/Math.pow(t,2)}, 
                    {                  0,                 2/t, -2*y1/Math.pow(t,2)}, 
                    {-2*y0/Math.pow(t,2), -2*y1/Math.pow(t,2),  2*(Math.pow(y0,2) + Math.pow(y1,2))/Math.pow(t,3)}};
                return F2.make(ret);
            }

            public int getDim() {
                return 3;
            }
        };