/*-------------------------------------------------------------------------------------*/
/* 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 Multi_Obj_Evaluator.cpp
\brief NOMAD::Evaluator subclass for multiobjective optimization (implementation)
\author Sebastien Le Digabel
\date 2010-04-09
\see Multi_Obj_Evaluator.hpp
*/
#include "Multi_Obj_Evaluator.hpp"
/*-----------------------------------*/
/* static members initialization */
/*-----------------------------------*/
int NOMAD::Multi_Obj_Evaluator::_i1 = -1;
int NOMAD::Multi_Obj_Evaluator::_i2 = -1;
/*---------------------------------------*/
/* initialization of objective indexes */
/* (static) */
/*---------------------------------------*/
void NOMAD::Multi_Obj_Evaluator::set_obj_indexes ( const std::list & index_obj )
{
if ( index_obj.size() != 2 )
throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
"Multi_Obj_Evaluator defined with a number of indexes different than two" );
std::list::const_iterator it = index_obj.begin();
NOMAD::Multi_Obj_Evaluator::_i1 = *it;
it++;
NOMAD::Multi_Obj_Evaluator::_i2 = *it;
}
/*-------------------------------------------------------------*/
/* computation of f, taking into account the two objectives, */
/* with weights _w1 and _w2 */
/*-------------------------------------------------------------*/
void NOMAD::Multi_Obj_Evaluator::compute_f ( NOMAD::Eval_Point & x ) const
{
if ( _i1 < 0 || _i2 < 0 )
throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
"Multi_Obj_Evaluator::compute_f(): no objective indexes defined" );
int obj_index [2];
obj_index[0] = _i1;
obj_index[1] = _i2;
const NOMAD::Point & bbo = x.get_bb_outputs();
// a reference is available:
if ( _ref )
{
NOMAD::multi_formulation_type mft = _p.get_multi_formulation();
if ( mft == NOMAD::UNDEFINED_FORMULATION )
throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
"Multi_Obj_Evaluator::compute_f(): no formulation type is defined" );
// normalized formulation:
if ( mft == NOMAD::NORMALIZED || mft == NOMAD::DIST_LINF ) {
// f1 - r1:
NOMAD::Double d = bbo[obj_index[0]] - (*_ref)[0];
// f2 - r2:
NOMAD::Double f2mr2 = bbo[obj_index[1]] - (*_ref)[1];
// we take the max:
if ( f2mr2 > d )
d = f2mr2;
x.set_f ( d );
}
// product formulation:
else if ( mft == NOMAD::PRODUCT ) {
NOMAD::Double prod = 1.0 , ri , fi;
for ( int i = 0 ; i < 2 ; ++i ) {
ri = (*_ref)[i];
fi = bbo[obj_index[i]];
if ( fi > ri ) {
prod = 0.0;
break;
}
prod = prod * (ri-fi).pow2();
}
x.set_f ( -prod );
}
// distance formulation:
else {
NOMAD::Double d;
NOMAD::Double r1mf1 = (*_ref)[0] - bbo[obj_index[0]];
NOMAD::Double r2mf2 = (*_ref)[1] - bbo[obj_index[1]];
if ( r1mf1 >= 0.0 && r2mf2 >= 0.0 ) {
d = r1mf1.pow2();
NOMAD::Double tmp = r2mf2.pow2();
if ( tmp < d )
d = tmp;
d = -d;
}
else if ( r1mf1 <= 0.0 && r2mf2 <= 0.0 ) {
// with L2 norm:
if ( mft == NOMAD::DIST_L2 )
d = r1mf1.pow2() + r2mf2.pow2();
// with L1 norm:
else
d = (r1mf1.abs() + r2mf2.abs()).pow2();
// Linf norm: treated as NORMALIZED
}
else if ( r1mf1 > 0.0 )
d = r2mf2.pow2();
else
d = r1mf1.pow2();
x.set_f ( d );
}
}
// no reference is available (use weights):
else
x.set_f ( _w1 * bbo[obj_index[0]] + _w2 * bbo[obj_index[1]] );
}