bbopt / nomad

NOMAD - A blackbox optimization software
https://nomad-4-user-guide.readthedocs.io/
GNU Lesser General Public License v3.0
110 stars 24 forks source link

How to retrieve the best solution #142

Closed gitouni closed 1 year ago

gitouni commented 1 year ago

I have installed NOMAD 4 follwing the stpes of README.txt and find that the solution is accessible here.

However, I cannot find CacheBase in NOMAD namespace. I need to retrieve the value of the best solution in my program. Is this function implemented in NOMAD4? I only include "Nomad/nomad.hpp" in my cpp file.

Many thanks for your help.

ctribes commented 1 year ago

You will need to add

#include "Cache/CacheBase.hpp"

Here is some code to retrieve the best feasible and best infeasible solution (the code is from the PyNomad interface).

`

    // Set the best feasible and best infeasible solutions

    std::vector<NOMAD::EvalPoint> evalPointFeasList, evalPointInfList;

    auto nbFeas = NOMAD::CacheBase::getInstance()->findBestFeas(evalPointFeasList, NOMAD::Point(), 
    NOMAD::EvalType::BB, NOMAD::ComputeType::STANDARD, nullptr);

    auto nbInf  = NOMAD::CacheBase::getInstance()->findBestInf(evalPointInfList, NOMAD::INF, NOMAD::Point(), 
    NOMAD::EvalType::BB, NOMAD::ComputeType::STANDARD, nullptr);

    if (nbInf > 0)
    {
        // Use first infeasible point. This could be generalized to show
        // all infeasible points.
        // Smart pointers should also be used.
        // For now, keep the same logic as with PyNomad 1.
        // One of the pointer is set to null to identify the type of solution
        NOMAD::EvalPoint evalPointInf = evalPointInfList[0];
        bestInfeasSol = std::make_shared<NOMAD::EvalPoint>(evalPointInf);
        if (0 == nbFeas)
        {
            bestFeasSol = nullptr;
        }
    }
    if (nbFeas > 0)
    {
        NOMAD::EvalPoint evalPointFeas = evalPointFeasList[0];
        bestFeasSol = std::make_shared<NOMAD::EvalPoint>(evalPointFeas);
        bestInfeasSol = nullptr;
    }
    if (0 == nbFeas)
    {
        bestFeasSol = nullptr;
    }
    if(0 == nbInf)
    {
        bestInfeasSol = nullptr;
    }

`

gitouni commented 1 year ago

Many thanks for your help. Now I have understood how to retrieve the best feasible and infeasible solution from EvalPointList. Could you further tell me how to get the EvalPointList from a NOMAD_MAIN_STEP? Here is an example NOMAD cpp: ( I only show a snippet here)

#include "Nomad/nomad.hpp"
auto nomad_params = std::make_shared<NOMAD::AllParameters>();
nomad_params->set_MAX_BB_EVAL(iba_params.max_bbeval);
nomad_params->set_DIMENSION(7);
NOMAD::BBOutputTypeList bbOutputTypes;
bbOutputTypes.push_back(NOMAD::BBOutputType::OBJ);
nomad_params->set_BB_OUTPUT_TYPE(bbOutputTypes);
/**some codes go here**/
nomad_params->checkAndComply();

NOMAD::MainStep nomad_main_step;
nomad_main_step.setAllParameters(nomad_params);
auto ev = std::make_unique<BALoss>(nomad_params->getEvalParams(), PointCloudFiles, KeyFrames, iba_params);
nomad_main_step.setEvaluator(std::move(ev));
nomad_main_step.start();
nomad_main_step.run();
/**retrieve the EvalPointList and Best Solution here**/

I appreciate your reply.

ctribes commented 1 year ago

You don't get the the eval points list from NOMAD::MainStep object. You get it from the singleton instance of NOMAD::CacheBase. This is done in the lines with NOMAD::CacheBase::getInstance()->findBestFeas and NOMAD::CacheBase::getInstance()->findBestInfeas

Have you tried to paste the code snippet I provided into your code? It should give you the best eval points.

If you want to run several consecutive NOMAD::MainStep from scratch, you will need to call the static NOMAD::MainStep::resetComponentsBetweenOptimization() function. This will reset the cache and other components.

gitouni commented 1 year ago

You don't get the the eval points list from NOMAD::MainStep object. You get it from the singleton instance of NOMAD::CacheBase. This is done in the lines with NOMAD::CacheBase::getInstance()->findBestFeas and NOMAD::CacheBase::getInstance()->findBestInfeas

Have you tried to paste the code snippet I provided into your code? It should give you the best eval points.

If you want to run several consecutive NOMAD::MainStep from scratch, you will need to call the static NOMAD::MainStep::resetComponentsBetweenOptimization() function. This will reset the cache and other components.

My appology. It works when I paste your codes below my snippet. Thanks.