/*-------------------------------------------------------------------------------------*/ /* NOMAD - Nonlinear Optimization by Mesh Adaptive Direct search - version 3.6.1 */ /* */ /* Copyright (C) 2001-2012 Mark Abramson - the Boeing Company, Seattle */ /* Charles Audet - Ecole Polytechnique, Montreal */ /* Gilles Couture - Ecole Polytechnique, Montreal */ /* John Dennis - Rice University, Houston */ /* Sebastien Le Digabel - Ecole Polytechnique, Montreal */ /* Christophe Tribes - Ecole Polytechnique, Montreal */ /* */ /* funded in part by AFOSR and Exxon Mobil */ /* */ /* Author: Sebastien Le Digabel */ /* */ /* Contact information: */ /* Ecole Polytechnique de Montreal - GERAD */ /* C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada */ /* e-mail: nomad@gerad.ca */ /* phone : 1-514-340-6053 #6928 */ /* fax : 1-514-340-5665 */ /* */ /* This program is free software: you can redistribute it and/or modify it under the */ /* terms of the GNU Lesser General Public License as published by the Free Software */ /* Foundation, either version 3 of the License, or (at your option) any later */ /* version. */ /* */ /* This program is distributed in the hope that it will be useful, but WITHOUT ANY */ /* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A */ /* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License along */ /* with this program. If not, see . */ /* */ /* You can find information on the NOMAD software at www.gerad.ca/nomad */ /*-------------------------------------------------------------------------------------*/ /** \file Priority_Eval_Point.cpp \brief Evaluation point with a priority (implementation) \author Sebastien Le Digabel \date 2010-04-22 \see Priority_Eval_Point.hpp */ #include "Priority_Eval_Point.hpp" /*------------------------------------------------*/ /* comparison operator */ /*------------------------------------------------*/ /* . x1.dominates(x2) returns true if x1 should */ /* be evaluated before x2 */ /* . x is a Priority_Eval_Point */ /*------------------------------------------------*/ bool NOMAD::Priority_Eval_Point::dominates ( const NOMAD::Set_Element & x ) const { if ( this == &x ) return false; const NOMAD::Eval_Point * x1 = get_element(); const NOMAD::Eval_Point * x2 = x.get_element(); // criterion 1: user criterion: // ------------ const NOMAD::Double uep1 = x1->get_user_eval_priority(); if ( uep1.is_defined() ) { const NOMAD::Double uep2 = x2->get_user_eval_priority(); if ( uep2.is_defined() ) { if ( uep1 > uep2 ) return true; if ( uep2 > uep1 ) return false; } } // specific Priority_Eval_Point elements of comparison: NOMAD::Double x_f_sgte; NOMAD::Double x_h_sgte; NOMAD::Double x_f_model; NOMAD::Double x_h_model; NOMAD::Double x_angle_success_dir; NOMAD::Double x_angle_simplex_grad; x.get_priority_criteria ( x_f_sgte , x_h_sgte , x_f_model , x_h_model , x_angle_success_dir , x_angle_simplex_grad ); // criterion 2: give priority to already evaluated cache points: // ------------ if ( x1->is_in_cache() && !x2->is_in_cache() ) return true; if ( x2->is_in_cache() && !x1->is_in_cache() ) return false; // criterion 3: give priority to already evaluated points // ------------ that are eval_ok: if ( x1->is_eval_ok() && !x2->is_eval_ok() ) return true; if ( x2->is_eval_ok() && !x1->is_eval_ok() ) return false; // criterion 4: true f and h values: // ----------- int flag = compare_hf_values ( x1->get_h() , x1->get_f() , x2->get_h() , x2->get_f() ); if ( flag ) return ( flag > 0 ); // criterion 5: surrogate f and h values: // ------------ flag = compare_hf_values ( _h_sgte , _f_sgte , x_h_sgte , x_f_sgte ); if ( flag ) return ( flag > 0 ); // criterion 6: model f and h values: // ------------ flag = compare_hf_values ( _h_model , _f_model , x_h_model , x_f_model ); if ( flag ) return ( flag > 0 ); // criterion 7: check the angle with the last successful direction: // ------------ if ( _angle_success_dir.is_defined() && x_angle_success_dir.is_defined() ) { if ( _angle_success_dir < x_angle_success_dir ) return true; if ( x_angle_success_dir < _angle_success_dir ) return false; } // !not used! // criterion 8: check the angle with the simplex gradient: // ------------ if ( _angle_simplex_grad.is_defined() && x_angle_simplex_grad.is_defined() ) { if ( _angle_simplex_grad < x_angle_simplex_grad ) return true; if ( x_angle_simplex_grad < _angle_simplex_grad ) return false; } // criterion 9: take the point with the best h value: // ------------ flag = compare_h_values ( x1->get_h() , x2->get_h() ); if ( flag ) return ( flag > 0 ); flag = compare_h_values ( _h_sgte , x_h_sgte ); if ( flag ) return ( flag > 0 ); flag = compare_h_values ( _h_model , x_h_model ); if ( flag ) return ( flag > 0 ); // criterion 10: random criterion for randomly generated directions: // ------------- const NOMAD::Double rep1 = x1->get_rand_eval_priority(); if ( rep1.is_defined() ) { const NOMAD::Double rep2 = x2->get_rand_eval_priority(); if ( rep2.is_defined() ) { if ( rep1 < rep2 ) return true; if ( rep2 < rep1 ) return false; } } // criterion 11: compare the tags: // ------------- return x1->get_tag() < x2->get_tag(); } /*-----------------------------------------------*/ /* compare the h values of two points */ /*-----------------------------------------------*/ /* . return h(x1) < h(x2) with the format: */ /* 1 : x1 better than x2 */ /* -1 : x2 better than x1 */ /* 0 : undetermined */ /* . private method */ /*-----------------------------------------------*/ int NOMAD::Priority_Eval_Point::compare_h_values ( const NOMAD::Double & hx1 , const NOMAD::Double & hx2 ) const { if ( hx1.is_defined() && hx2.is_defined() ) { if ( hx1 < hx2 ) return 1; if ( hx2 < hx1 ) return -1; } return 0; } /*-----------------------------------------------*/ /* compare the h and f values of two points */ /*-----------------------------------------------*/ /* . return ( h(x1),f(x1) ) < ( h(x2),f(x2) ) */ /* with the following format: */ /* 1 : x1 better than x2 */ /* -1 : x2 better than x1 */ /* 0 : undetermined */ /* . private method */ /*-----------------------------------------------*/ int NOMAD::Priority_Eval_Point::compare_hf_values ( const NOMAD::Double & hx1 , const NOMAD::Double & fx1 , const NOMAD::Double & hx2 , const NOMAD::Double & fx2 ) const { if ( fx1.is_defined() && fx2.is_defined() ) { if ( hx1.is_defined() && hx2.is_defined() ) { // x1 is feasible: if ( hx1 <= _h_min ) { // both points are feasible: if ( hx2 <= _h_min ) { if ( fx1 < fx2 ) return 1; if ( fx2 < fx1 ) return -1; } // x1 feasible and x2 infeasible: else return 1; } // x1 is infeasible: else { // x2 is feasible: if ( hx2 <= _h_min ) return -1; // both points are infeasible: if ( ( hx1 < hx2 && fx1 < fx2 ) || ( hx1 == hx2 && fx1 < fx2 ) || ( hx1 < hx2 && fx1 == fx2 ) ) return 1; if ( ( hx2 < hx1 && fx2 < fx1 ) || ( hx2 == hx1 && fx2 < fx1 ) || ( hx2 < hx1 && fx2 == fx1 ) ) return -1; } } // we only have f values: else { if ( fx1 < fx2 ) return 1; if ( fx2 < fx1 ) return -1; } } return 0; }