00001
00038
00039
00040 #ifndef OBJECTIVE_FUNCTION_H
00041 #define OBJECTIVE_FUNCTION_H
00042
00043 #include <Rng/GlobalRng.h>
00044 #include <SharkDefs.h>
00045 #include <vector>
00046 #include <string>
00047 #include <Array/ArrayOp.h>
00048 #include <Array/ArrayIo.h>
00049 #include <LinAlg/VecMat.h>
00050
00051
00068 template<class T>
00069 class ConstraintHandler
00070 {
00071 public:
00072 ConstraintHandler() { }
00073 virtual ~ConstraintHandler() { }
00074
00075 virtual bool isFeasible(const T& point) const { return true; }
00076 virtual bool closestFeasible(T& point) const { return false; }
00077 };
00078
00079
00087 class BoxConstraintHandler : public ConstraintHandler<double*>
00088 {
00089 public:
00095 BoxConstraintHandler(unsigned int dim, double lower, double upper);
00096
00105 BoxConstraintHandler(unsigned int dim, double lower, double upper, unsigned int exception, double exceptionLower, double exceptionUpper);
00106
00116 BoxConstraintHandler(unsigned int dim, double lower, double upper, unsigned int exception1, double exception1Lower, double exception1Upper, unsigned int exception2, double exception2Lower, double exception2Upper);
00117
00123 BoxConstraintHandler(const std::vector<double>& lower, const std::vector<double>& upper);
00124
00126 ~BoxConstraintHandler();
00127
00128
00130 bool isFeasible(double* const& point) const;
00131
00133 bool closestFeasible(double*& point) const;
00134
00136 inline unsigned int dimension() const { return m_dimension; }
00137
00139 inline double lowerBound(unsigned int index) const { return m_lower[index]; }
00140
00142 inline double upperBound(unsigned int index) const { return m_upper[index]; }
00143
00144 protected:
00146 unsigned int m_dimension;
00147
00149 std::vector<double> m_lower;
00150
00152 std::vector<double> m_upper;
00153 };
00154
00155
00168 class ObjectiveFunction {
00169 public:
00171 ObjectiveFunction();
00172
00174 virtual ~ObjectiveFunction();
00175
00176
00178 inline unsigned timesCalled() const { return m_timesCalled; }
00179
00181 inline void resetTimesCalled() { m_timesCalled = 0; }
00182
00184 inline const std::string& name() const { return m_name; }
00185
00187 virtual unsigned int objectives() const = 0;
00188
00189 protected:
00191 unsigned m_timesCalled;
00192
00194 std::string m_name;
00195 };
00196
00197
00219 template<class T>
00220 class ObjectiveFunctionT : public ObjectiveFunction {
00221 public:
00223 ObjectiveFunctionT(ConstraintHandler<T>* constrainthandler = NULL)
00224 {
00225 this->constrainthandler = constrainthandler;
00226 }
00227
00229 ~ObjectiveFunctionT() { }
00230
00232 bool isFeasible(const T& point) const
00233 {
00234 if (constrainthandler == NULL) return true;
00235 else return constrainthandler->isFeasible(point);
00236 }
00237
00240 bool closestFeasible(T& point) const
00241 {
00242 if (constrainthandler == NULL) return false;
00243 else return constrainthandler->closestFeasible(point);
00244 }
00245
00247 virtual void result(const T& point, std::vector<double>& value) = 0;
00248
00250 double operator() (const T& point) {
00251 std::vector<double> value(1);
00252 result(point, value);
00253 return value[0];
00254 }
00255
00262 virtual bool ProposeStartingPoint(T& point) const
00263 {
00264 return false;
00265 }
00266
00268 inline const ConstraintHandler<T>* getConstraintHandler() const
00269 { return constrainthandler; }
00270
00271 protected:
00273 ConstraintHandler<T>* constrainthandler;
00274 };
00275
00276
00284 template<class T>
00285 class ObjectiveFunctionVS : public ObjectiveFunctionT<T*> {
00286 public:
00288 ObjectiveFunctionVS(unsigned d = 0, ConstraintHandler<T*>* constrainthandler = NULL)
00289 : ObjectiveFunctionT<T*>(constrainthandler)
00290 , m_dimension(d)
00291 { };
00292
00294 ~ObjectiveFunctionVS() { };
00295
00296
00298 void init(unsigned d) {
00299 m_dimension = d;
00300 }
00301
00303 inline unsigned dimension() const { return m_dimension; }
00304
00306 double operator()(const Array<T>& point) {
00307 SIZE_CHECK(point.ndim() == 1 || point.dim(0) == m_dimension);
00308 return (*this)(const_cast<T*>(&point(0)));
00309 }
00310
00312 double operator()(const std::vector<T>& point) {
00313 SIZE_CHECK(point.size() == m_dimension);
00314 return (*this)(const_cast<T*>(&point[0]));
00315 }
00316
00318 double operator() (double* const& point) {
00319
00320
00321 std::vector<double> value(1);
00322 ((ObjectiveFunctionT<const T*>*)this)->result(point, value);
00323 return value[0];
00324 }
00325
00327 void result(const Array<T>& point, std::vector<double>& value) {
00328 SIZE_CHECK(point.ndim() == 1 || point.dim(0) == m_dimension);
00329 ((ObjectiveFunctionT<T*>*)this)->result((T* const&)const_cast<T*>(&point(0)), value);
00330 }
00331
00333 void result(const std::vector<T>& point, std::vector<double>& value) {
00334 SIZE_CHECK(point.size() == m_dimension);
00335 ((ObjectiveFunctionT<T*>*)this)->result(const_cast<T*>(&point[0]), value);
00336 }
00337
00340 bool ProposeStartingPoint(T*& point) const
00341 {
00342 if (ObjectiveFunctionT<T*>::constrainthandler == NULL) return false;
00343 BoxConstraintHandler* bch = dynamic_cast<BoxConstraintHandler*>(ObjectiveFunctionT<T*>::constrainthandler);
00344 if (bch == NULL) return false;
00345 int i, ic = bch->dimension();
00346 while (true)
00347 {
00348 for (i=0; i<ic; i++) point[i] = (T)Rng::uni(bch->lowerBound(i), bch->upperBound(i));
00349 if (bch->isFeasible((double*&)point)) break;
00350 }
00351 return true;
00352 }
00353
00355 inline bool isFeasible(const Array<T>& point) const {
00356 SIZE_CHECK(point.ndim() == 1 || point.dim(0) == m_dimension);
00357 return ((ObjectiveFunctionT<T*>*)this)->isFeasible((T* const&)const_cast<T*>(&point(0)));
00358 }
00359
00361 inline bool isFeasible(const std::vector<T>& point) const {
00362 SIZE_CHECK(point.size() == m_dimension);
00363 return ((ObjectiveFunctionT<T*>*)this)->isFeasible((T* const&)const_cast<T*>(&point[0]));
00364 }
00365
00367 inline bool closestFeasible(Array<T>& point) const {
00368 SIZE_CHECK(point.ndim() == 1 || point.dim(0) == m_dimension);
00369 return ObjectiveFunctionT<T*>::ClosestFeasible(&point(0));
00370 }
00371
00373 inline bool closestFeasible(std::vector<T>& point) const {
00374 SIZE_CHECK(point.size() == m_dimension);
00375 T* p = &point[0];
00376 return ObjectiveFunctionT<T*>::closestFeasible(p);
00377 }
00378
00380 inline bool ProposeStartingPoint(Array<T>& point) const {
00381 SIZE_CHECK(point.ndim() == 1 || point.dim(0) == m_dimension);
00382 T* p = &point(0);
00383 return ProposeStartingPoint(p);
00384 }
00385
00387 inline bool ProposeStartingPoint(std::vector<T>& point) const {
00388 SIZE_CHECK(point.size() == m_dimension);
00389 T* p = &point[0];
00390 return ProposeStartingPoint(p);
00391 }
00392
00401 virtual bool utopianFitness(std::vector<double>& value) const { return false; }
00402
00412 virtual bool nadirFitness(std::vector<double>& value) const { return false; }
00413
00414 protected:
00416 unsigned m_dimension;
00417 };
00418
00419
00425 class TransformedObjectiveFunction : public ObjectiveFunctionVS<double> {
00426 public:
00428 TransformedObjectiveFunction(ObjectiveFunctionVS<double>& base, unsigned d = 0);
00429
00431 TransformedObjectiveFunction(ObjectiveFunctionVS<double>& base, const Array<double>& transformation);
00432
00434 ~TransformedObjectiveFunction();
00435
00437 void init(const Array<double>& transformation);
00438
00440 void initRandomRotation(unsigned d = 0);
00441
00443 inline const Matrix& Transformation() const { return m_Transformation; }
00444
00446 inline void result(const Array<double>& point, std::vector<double>& value)
00447 {
00448 SIZE_CHECK(point.ndim() == 1 || point.dim(0) == m_dimension);
00449 result((double*)&point(0), value);
00450 }
00451
00453 inline void result(const std::vector<double>& point, std::vector<double>& value)
00454 {
00455 SIZE_CHECK(point.size() == m_dimension);
00456 result((double*)&point[0], value);
00457 }
00458
00460 void result(double* const& point, std::vector<double>& value);
00461
00463 bool ProposeStartingPoint(double*& point) const;
00464
00466 inline void transform(Array<double>& point) const {
00467 SIZE_CHECK(point.ndim() == 1 || point.dim(0) == m_dimension);
00468 std::vector<double> tmp(m_dimension);
00469 transform(&point(0), tmp);
00470 unsigned i;
00471 for (i=0; i<m_dimension; i++) point(i) = tmp[i];
00472 }
00473
00475 inline void transform(std::vector<double>& point) const {
00476 SIZE_CHECK(point.size() == m_dimension);
00477 std::vector<double> tmp(m_dimension);
00478 transform(&point[0], tmp);
00479 unsigned i;
00480 for (i=0; i<m_dimension; i++) point[i] = tmp[i];
00481 }
00482
00484 inline void transform(double* point) const {
00485 std::vector<double> tmp(m_dimension);
00486 transform(point, tmp);
00487 unsigned i;
00488 for (i=0; i<m_dimension; i++) point[i] = tmp[i];
00489 }
00490
00492 bool utopianFitness(std::vector<double>& value) const;
00493
00495 bool nadirFitness(std::vector<double>& value) const;
00496
00498 unsigned int objectives() const;
00499
00500 protected:
00502 void transform(const double* in, std::vector<double>& out) const;
00503
00505 void transformInverse(const std::vector<double>& in, double* out) const;
00506
00508 ObjectiveFunctionVS<double>& baseObjective;
00509
00511 Matrix m_Transformation;
00512 };
00513
00514
00515 #endif