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