1 /*-------------------------------------------------------------------------------------*/
2 /* NOMAD - Nonlinear Optimization by Mesh Adaptive Direct search - version 3.7.2 */
3 /* */
4 /* Copyright (C) 2001-2015 Mark Abramson - the Boeing Company, Seattle */
5 /* Charles Audet - Ecole Polytechnique, Montreal */
6 /* Gilles Couture - Ecole Polytechnique, Montreal */
7 /* John Dennis - Rice University, Houston */
8 /* Sebastien Le Digabel - Ecole Polytechnique, Montreal */
9 /* Christophe Tribes - Ecole Polytechnique, Montreal */
10 /* */
11 /* funded in part by AFOSR and Exxon Mobil */
12 /* */
13 /* Author: Sebastien Le Digabel */
14 /* */
15 /* Contact information: */
16 /* Ecole Polytechnique de Montreal - GERAD */
17 /* C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada */
18 /* e-mail: nomad@gerad.ca */
19 /* phone : 1-514-340-6053 #6928 */
20 /* fax : 1-514-340-5665 */
21 /* */
22 /* This program is free software: you can redistribute it and/or modify it under the */
23 /* terms of the GNU Lesser General Public License as published by the Free Software */
24 /* Foundation, either version 3 of the License, or (at your option) any later */
25 /* version. */
26 /* */
27 /* This program is distributed in the hope that it will be useful, but WITHOUT ANY */
28 /* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A */
29 /* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */
30 /* */
31 /* You should have received a copy of the GNU Lesser General Public License along */
32 /* with this program. If not, see <http://www.gnu.org/licenses/>. */
33 /* */
34 /* You can find information on the NOMAD software at www.gerad.ca/nomad */
35 /*-------------------------------------------------------------------------------------*/
36 /**
37 \file Multi_Obj_Evaluator.cpp
38 \brief NOMAD::Evaluator subclass for multiobjective optimization (implementation)
39 \author Sebastien Le Digabel
40 \date 2010-04-09
41 \see Multi_Obj_Evaluator.hpp
42 */
43 #include "Multi_Obj_Evaluator.hpp"
44
45 /*-----------------------------------*/
46 /* static members initialization */
47 /*-----------------------------------*/
48 int NOMAD::Multi_Obj_Evaluator::_i1 = -1;
49 int NOMAD::Multi_Obj_Evaluator::_i2 = -1;
50
51 /*---------------------------------------*/
52 /* initialization of objective indexes */
53 /* (static) */
54 /*---------------------------------------*/
set_obj_indexes(const std::list<int> & index_obj)55 void NOMAD::Multi_Obj_Evaluator::set_obj_indexes ( const std::list<int> & index_obj )
56 {
57 if ( index_obj.size() != 2 )
58 throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
59 "Multi_Obj_Evaluator defined with a number of indexes different than two" );
60
61 std::list<int>::const_iterator it = index_obj.begin();
62
63 NOMAD::Multi_Obj_Evaluator::_i1 = *it;
64 it++;
65 NOMAD::Multi_Obj_Evaluator::_i2 = *it;
66 }
67
68 /*-------------------------------------------------------------*/
69 /* computation of f, taking into account the two objectives, */
70 /* with weights _w1 and _w2 */
71 /*-------------------------------------------------------------*/
compute_f(NOMAD::Eval_Point & x) const72 void NOMAD::Multi_Obj_Evaluator::compute_f ( NOMAD::Eval_Point & x ) const
73 {
74 if ( _i1 < 0 || _i2 < 0 )
75 throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
76 "Multi_Obj_Evaluator::compute_f(): no objective indexes defined" );
77
78 int obj_index [2];
79 obj_index[0] = _i1;
80 obj_index[1] = _i2;
81
82 const NOMAD::Point & bbo = x.get_bb_outputs();
83
84 // a reference is available:
85 if ( _ref )
86 {
87
88 NOMAD::multi_formulation_type mft = _p.get_multi_formulation();
89
90 if ( mft == NOMAD::UNDEFINED_FORMULATION )
91 throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
92 "Multi_Obj_Evaluator::compute_f(): no formulation type is defined" );
93
94 // normalized formulation:
95 if ( mft == NOMAD::NORMALIZED || mft == NOMAD::DIST_LINF ) {
96
97 // f1 - r1:
98 NOMAD::Double d = bbo[obj_index[0]] - (*_ref)[0];
99
100 // f2 - r2:
101 NOMAD::Double f2mr2 = bbo[obj_index[1]] - (*_ref)[1];
102
103 // we take the max:
104 if ( f2mr2 > d )
105 d = f2mr2;
106
107 x.set_f ( d );
108 }
109
110 // product formulation:
111 else if ( mft == NOMAD::PRODUCT ) {
112
113 NOMAD::Double prod = 1.0 , ri , fi;
114
115 for ( int i = 0 ; i < 2 ; ++i ) {
116
117 ri = (*_ref)[i];
118 fi = bbo[obj_index[i]];
119
120 if ( fi > ri ) {
121 prod = 0.0;
122 break;
123 }
124 prod = prod * (ri-fi).pow2();
125 }
126
127 x.set_f ( -prod );
128 }
129
130 // distance formulation:
131 else {
132
133 NOMAD::Double d;
134 NOMAD::Double r1mf1 = (*_ref)[0] - bbo[obj_index[0]];
135 NOMAD::Double r2mf2 = (*_ref)[1] - bbo[obj_index[1]];
136
137 if ( r1mf1 >= 0.0 && r2mf2 >= 0.0 ) {
138 d = r1mf1.pow2();
139 NOMAD::Double tmp = r2mf2.pow2();
140 if ( tmp < d )
141 d = tmp;
142 d = -d;
143 }
144 else if ( r1mf1 <= 0.0 && r2mf2 <= 0.0 ) {
145
146 // with L2 norm:
147 if ( mft == NOMAD::DIST_L2 )
148 d = r1mf1.pow2() + r2mf2.pow2();
149
150 // with L1 norm:
151 else
152 d = (r1mf1.abs() + r2mf2.abs()).pow2();
153
154 // Linf norm: treated as NORMALIZED
155 }
156 else if ( r1mf1 > 0.0 )
157 d = r2mf2.pow2();
158 else
159 d = r1mf1.pow2();
160
161 x.set_f ( d );
162 }
163 }
164
165 // no reference is available (use weights):
166 else
167 x.set_f ( _w1 * bbo[obj_index[0]] + _w2 * bbo[obj_index[1]] );
168 }
169