Ваши функции не квадратичные, насколько я понимаю.(Возможно, перенесите этот вопрос на math.stackexchange.com).
Я использовал JOptimizer и нашел его очень способным и быстрым для линейных задач, но никогда не использовал его для нелинейных задач,Однако на сайте JOptimizer есть примеры различных нелинейных задач, которые он может решить.
В поддержку этого в JOptimizer есть класс ConvexMultivariateRealFunction
, который вы можете использовать для представления своих функций.По сути, в вашей реализации класса вы кодируете функции, которые возвращают значение функции, ее градиент и матрицу Гессиана для любого заданного набора входных данных функции.
Как сделать все это для вашегоОтдельные функции - это математический вопрос, а также вопрос о том, удовлетворяют ли ваши функции ограничениям, на которые способен 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;
}
};