Back to TIL list

Otimização numérica em C++

Created at

A OptimLib é uma biblioteca C++ lightweight para otimização numérica de funções não lineares.

Instalação da optimlib

git clone https://github.com/kthohr/optim.gitcd optim./configure --header-only-version

Após os comandos acima é criado um diretório chamado header_only_version. A partir daí é só incluir este diretório nos flags de compilação: -Ialgum-lugar/header_only_version

Exemplo 1

Neste exemplo usaremos o método Differential Evolution (DE) que é uma busca genética estocástica para otimização global.

Localizar o mínimo da função .

Função exemplo para busca do mínimo.
Função exemplo para busca do mínimo.

A função a ser otimizada precisa ter o seguinte formato:

double f( vetor_de_entrada,          vetor_de_gradiente,          parametros_adicionais )

Definindo nosso usando o formato acima:

double f( const arma::vec &vals_inp,          arma::vec *grad_out,          void *opt_data ){  // Nosssa função é muito simples e só utiliza uma entrada  const double x = vals_inp( 0 );  return x * x - 5 * x + 6;}

Realizando a otimização:

arma::vec x = arma::ones( 1, 1 ) + 0.5; // Valor inicial 1.5if( optim::de( x, f, nullptr ) ) {  cout << "Mínimo para f(x): "       << "x² - 5x + 6 => " << x << endl;  // Mínimo para f(x) = x² - 5x + 6 => 2.5000}

Exemplo 2

A função anterior é muito bem comportada e sem mínimos locais. Vamos complicar um pouco.

Localizar o mínimo da função .

Cálculo do valor mínimo.
Cálculo do valor mínimo.

Definindo a nova função:

double h( const arma::vec &vals_inp,          arma::vec *grad_out,          void *opt_data ){  const double x  = vals_inp( 0 );  return x * x - 5 * x + 6 + 0.2 * sin( 10 * x );}

Realizando a otimização:

arma::vec x = arma::ones( 1, 1 ) + 0.5; // Valor inicial 1.5if( optim::de( x, h, nullptr ) ) {  cout << "Mínimo para h(x): "       << "x² - 5x + 6 + 0.2 sin( 10x ) => "       << x << endl;  // Mínimo para h(x): x² - 5x + 6 + 0.2 sin( 10x ) => 2.3693}

Referências