SLSQP в NLOPT не выполняется для квадратичной функции с большим числом условий

Я сравниваю алгоритм SLSQP с простой 10D-функцией:

f (x) = x_1 ^ 2 + 10 ^ 6 \ sum \ limit_ {i = 2} ^ {D} x_i ^ 2

Функция c ++:

double myfunc(const std::vector<double> &x, std::vector<double> &grad, void *)
{
++counter;
assert(x.size() == 10);
double y      = pow(x[0], 2);
double factor = 1e6;

for (size_t i = 1; i < 10; ++i)
y += factor * pow(x[i], 2);
if (!grad.empty())
{
assert(grad.size() == 10);
grad[0] = 2 * x[0];
for (size_t i = 1; i < 10; ++i)
grad[i] = 2 * factor * x[i];
}
return y;
}

К моему удивлению, SLSQP не работает для этой простой функции, но если я переключу алгоритм на nlopt::LD_LBFGS, Nlopt по-прежнему оптимизировать функцию эффективно.

Кто-нибудь может объяснить, почему SLSQP не работает для этой демонстрационной функции?

Версия NLOPT — 2.4.2 (предоставлена nlopt::version) ниже приведен полный код:

#include <cassert>
#include <cmath>
#include <iostream>
#include <nlopt.hpp>
#include <random>
#include <vector>
using namespace std;
mt19937_64 engine(random_device{}());
static int counter = 0;
double myfunc(const std::vector<double> &x, std::vector<double> &grad, void *)
{
++counter;
assert(x.size() == 10);
double y      = pow(x[0], 2);
double factor = 1e6;

for (size_t i = 1; i < 10; ++i)
y += factor * pow(x[i], 2);
if (!grad.empty())
{
assert(grad.size() == 10);
grad[0] = 2 * x[0];
for (size_t i = 1; i < 10; ++i)
grad[i] = 2 * factor * x[i];
}
return y;
}
int main()
{
nlopt::opt opt(nlopt::LD_LBFGS, 10);

std::vector<double> lb(10, -100);
std::vector<double> ub(10, 100);
opt.set_lower_bounds(lb);
opt.set_upper_bounds(ub);
opt.set_min_objective(myfunc, NULL);
opt.set_maxeval(1000);
// opt.add_inequality_constraint(myfunc_constr, nullptr, 1);

vector<double> x(10);
uniform_real_distribution<double> distr(-100, 100);
for (auto &vx : x)
vx = distr(engine);
double minf = 1e20;
vector<double> fake_grad;
cout << "f(x0) =    " << myfunc(x, fake_grad, nullptr) << endl;

try
{
counter = 0;
nlopt::result result = opt.optimize(x, minf);
cout << "exit val:  " << result << endl;
}
catch (runtime_error &err)
{
cerr << err.what() << endl;
}
cout << endl;
cout << "optimized: " << minf << endl;
cout << "counter:   " << counter << endl;
cout << opt.get_algorithm_name() << endl;

int maj, min, bugf;
nlopt::version(maj, min, bugf);
cout << "version: " << maj << "." << min << "." << bugf << endl;
return 0;
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]