67 template<
typename VectorType>
129 template<
typename Archive>
130 void serialize( Archive & archive,
const unsigned int version ) {
134 archive & BOOST_SERIALIZATION_NVP(
m_gamma);
144 template<
class Set,
class VectorType>
145 std::vector<KeyValuePair<double,std::size_t> >
smallest(Set
const& points, std::size_t k,
VectorType const& reference)
const{
149 std::vector< Point<VectorType> > front;
150 for(
auto const& point: points) {
151 front.emplace_back( point, reference );
153 computeBoundingBoxes( front );
155 std::vector< typename std::vector< Point<VectorType> >::iterator > activePoints;
156 for(
auto it = front.begin(); it != front.end(); ++it ) {
157 activePoints.push_back( it );
160 auto smallest = computeSmallest(activePoints, front.size());
162 std::vector<KeyValuePair<double,std::size_t> > result(1);
163 result[0].key =
smallest->approximatedContribution;
164 result[0].value =
smallest-front.begin();
176 std::vector<KeyValuePair<double,std::size_t> >
smallest(Set
const& points, std::size_t k)
const{
181 std::vector<std::size_t> minIndex(points[0].size(),0);
182 RealVector minVal = points[0];
183 RealVector reference=points[0];
184 for(std::size_t i = 1; i != points.size(); ++i){
185 noalias(reference) = max(reference,points[i]);
186 for(std::size_t j = 0; j != minVal.size(); ++j){
187 if(points[i](j)< minVal[j]){
188 minVal[j] = points[i](j);
194 std::vector< Point<RealVector> > front;
195 front.reserve( points.size() );
196 for(
auto const& point: points){
197 front.emplace_back( point, reference );
199 computeBoundingBoxes( front );
201 std::vector<std::vector< Point<RealVector> >::iterator > activePoints;
202 for(
auto it = front.begin(); it != front.end(); ++it ) {
203 if(std::find(minIndex.begin(),minIndex.end(),it-front.begin()) != minIndex.end())
211 activePoints.push_back( it );
216 auto smallest = computeSmallest(activePoints, front.size());
217 std::vector<KeyValuePair<double,std::size_t> > result(1);
218 result[0].key =
smallest->approximatedContribution;
219 result[0].value =
smallest-front.begin();
226 typename Set::value_type computeSmallest(Set& activePoints, std::size_t n)
const{
227 typedef typename Set::value_type SetIter;
230 for(
auto it = activePoints.begin(); it != activePoints.end(); ++it )
231 delta = std::max(
delta, (*it)->boundingBoxVolume );
234 unsigned int round = 0;
241 if(shouldCompute(*activePoints[i])){
242 computeExactly(*activePoints[i]);
247 for(
auto point: activePoints )
248 sample( *point, round,
delta, n );
251 auto minimalElement = std::min_element(
252 activePoints.begin(),activePoints.end(),
253 [](SetIter
const& a, SetIter
const& b){return a->approximatedContribution < b->approximatedContribution;}
257 if( activePoints.size() > 2 ) {
259 minimalElement = std::min_element(
260 activePoints.begin(),activePoints.end(),
261 [](SetIter
const& a, SetIter
const& b){return a->approximatedContribution < b->approximatedContribution;}
266 double erase_level = (*minimalElement)->contributionUpperBound;
267 auto erase_start = std::remove_if(
268 activePoints.begin(),activePoints.end(),
269 [=](SetIter
const& point){return point->contributionLowerBound > erase_level;}
271 activePoints.erase(erase_start,activePoints.end());
274 if(activePoints.size() == 1)
275 return activePoints.front();
282 for(
auto it = activePoints.begin(); it != activePoints.end(); ++it ) {
283 if( it == minimalElement )
285 double nom = (*minimalElement)-> contributionUpperBound;
286 double den = (*it)->contributionLowerBound;
288 d = std::numeric_limits<double>::max();
290 d = std::max(d,nom/den);
295 return *minimalElement;
308 template<
class VectorType>
309 void sample( Point<VectorType>& point,
unsigned int r,
double delta, std::size_t n )
const{
310 if(point.computedExactly)
return;
313 double logR = std::log(
static_cast<double>( r ) );
317 double thresholdD= 1.0+0.5 * ( (1. +
m_gamma) * logR + logFactor ) *
sqr( point.boundingBoxVolume /
delta );
318 std::size_t threshold =
static_cast<std::size_t
>(thresholdD);
320 for( ; point.noSamples < threshold; point.noSamples++ ) {
322 point.sample.resize(point.point.size());
323 for(
unsigned int i = 0; i < point.sample.size(); i++ ) {
328 if( !isPointDominated( point.influencingPoints, point.sample ) )
329 point.noSuccessfulSamples++;
333 point.approximatedContribution = (point.boundingBoxVolume * point.noSuccessfulSamples) / point.noSamples;
335 double deltaReached = std::sqrt( 0.5 * ((1. +
m_gamma) * logR+ logFactor ) / point.noSamples ) * point.boundingBoxVolume;
336 point.contributionLowerBound = point.approximatedContribution - deltaReached;
337 point.contributionUpperBound = point.approximatedContribution + deltaReached;
348 template<
typename Set,
typename VectorType>
349 bool isPointDominated( Set
const& set,
VectorType const& point )
const{
351 for(
unsigned int i = 0; i < set.size(); i++ ) {
362 void computeBoundingBoxes(Set& set )
const{
363 for(
auto it = set.begin(); it != set.end(); ++it ) {
366 for(
auto itt = set.begin(); itt != set.end(); ++itt ) {
373 unsigned int coordCounter = 0;
374 unsigned int coord = 0;
375 for(
unsigned int o = 0; o < p1.point.size(); o++ ) {
376 if( p2.point[ o ] > p1.point[ o ] ) {
378 if( coordCounter == 2 )
384 if( coordCounter == 1 && p1.boundingBox[ coord ] > p2.point[ coord ] )
385 p1.boundingBox[ coord ] = p2.point[ coord ];
389 it->boundingBoxVolume = 1.;
390 for(
unsigned int i = 0 ; i < it->boundingBox.size(); i++ ) {
391 it->boundingBoxVolume *= it->boundingBox[ i ] - it->point[ i ];
395 for(
auto itt = set.begin(); itt != set.end(); ++itt ) {
399 bool isInfluencing =
true;
400 for(
unsigned int i = 0; i < it->point.size(); i++ ) {
401 if( itt->point[ i ] >= it->boundingBox[ i ] ) {
402 isInfluencing =
false;
406 if( isInfluencing ) {
407 it->influencingPoints.push_back( itt );
412 template<
class VectorType>
413 bool shouldCompute(Point<VectorType>
const& point)
const{
415 if(point.computedExactly)
return false;
416 std::size_t numPoints = point.influencingPoints.size();
418 if(numPoints == 0)
return true;
419 std::size_t numObjectives = point.point.size();
421 double time = (double)point.noSamples * numObjectives;
424 double algoRunTime = 0.03 * numObjectives * numObjectives * std::pow(numPoints, numObjectives * 0.5 );
425 return time > algoRunTime;
428 template<
class VectorType>
429 void computeExactly(Point<VectorType>& point)
const{
430 std::size_t numPoints = point.influencingPoints.size();
432 std::vector<VectorType> transformedPoints(numPoints);
433 for(std::size_t j = 0; j != numPoints; ++j){
434 transformedPoints[j] = max(point.influencingPoints[j]->point, point.point);
436 HypervolumeCalculator vol;
437 double volume = point.boundingBoxVolume - vol(transformedPoints, point.boundingBox);
438 point.computedExactly =
true;
439 point.contributionLowerBound = volume;
440 point.contributionUpperBound = volume;
441 point.approximatedContribution = volume;