/*-------------------------------------------------------------------------------------*/
/* 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;
}