33 #ifndef SHARK_ALGORITHMS_DIRECTSEARCH_HYPERVOLUME_CONTRIBUTION_APPROXIMATOR_H 34 #define SHARK_ALGORITHMS_DIRECTSEARCH_HYPERVOLUME_CONTRIBUTION_APPROXIMATOR_H 36 #include <boost/cstdint.hpp> 67 template<
typename VectorType>
109 : m_startDeltaMultiplier( 0.1 )
110 , m_multiplierDelta( 0.775 )
111 , m_minimumMultiplierDelta( 0.2 )
113 , m_errorProbability(1.E-2)
114 , m_errorBound(1.E-2)
131 template<
typename Archive>
132 void serialize( Archive & archive,
const unsigned int version ) {
133 archive & BOOST_SERIALIZATION_NVP(m_startDeltaMultiplier);
134 archive & BOOST_SERIALIZATION_NVP(m_multiplierDelta);
135 archive & BOOST_SERIALIZATION_NVP(m_minimumMultiplierDelta);
136 archive & BOOST_SERIALIZATION_NVP(m_gamma);
137 archive & BOOST_SERIALIZATION_NVP(m_errorProbability);
138 archive & BOOST_SERIALIZATION_NVP(m_errorBound);
145 template<
class Set,
class VectorType>
146 std::vector<KeyValuePair<double,std::size_t> >
smallest(Set
const& points, std::size_t k,
VectorType const& reference)
const{
150 std::vector< Point<VectorType> > front;
151 for(
auto const&
point: points) {
152 front.emplace_back(
point, reference );
154 computeBoundingBoxes( front );
156 std::vector< typename std::vector< Point<VectorType> >::iterator > activePoints;
157 for(
auto it = front.begin(); it != front.end(); ++it ) {
158 activePoints.push_back( it );
161 auto smallest = computeSmallest(activePoints, front.size());
163 std::vector<KeyValuePair<double,std::size_t> > result(1);
164 result[0].key =
smallest->approximatedContribution;
165 result[0].value =
smallest-front.begin();
177 std::vector<KeyValuePair<double,std::size_t> >
smallest(Set
const& points, std::size_t k)
const{
182 std::vector<std::size_t> minIndex(points[0].size(),0);
183 RealVector minVal = points[0];
184 RealVector reference=points[0];
185 for(std::size_t i = 1; i != points.size(); ++i){
186 noalias(reference) = max(reference,points[i]);
187 for(std::size_t j = 0; j != minVal.size(); ++j){
188 if(points[i](j)< minVal[j]){
189 minVal[j] = points[i](j);
195 std::vector< Point<RealVector> > front;
196 front.reserve( points.size() );
197 for(
auto const&
point: points){
198 front.emplace_back(
point, reference );
200 computeBoundingBoxes( front );
202 std::vector<std::vector< Point<RealVector> >::iterator > activePoints;
203 for(
auto it = front.begin(); it != front.end(); ++it ) {
204 if(std::find(minIndex.begin(),minIndex.end(),it-front.begin()) != minIndex.end())
212 activePoints.push_back( it );
217 auto smallest = computeSmallest(activePoints, front.size());
218 std::vector<KeyValuePair<double,std::size_t> > result(1);
219 result[0].key =
smallest->approximatedContribution;
220 result[0].value =
smallest-front.begin();
227 typename Set::value_type computeSmallest(Set& activePoints, std::size_t n)
const{
228 typedef typename Set::value_type SetIter;
231 for(
auto it = activePoints.begin(); it != activePoints.end(); ++it )
232 delta = std::max( delta, (*it)->boundingBoxVolume );
235 unsigned int round = 0;
242 if(shouldCompute(*activePoints[i])){
243 computeExactly(*activePoints[i]);
248 for(
auto point: activePoints )
252 auto minimalElement = std::min_element(
253 activePoints.begin(),activePoints.end(),
254 [](SetIter
const& a, SetIter
const& b){
return a->approximatedContribution < b->approximatedContribution;}
258 if( activePoints.size() > 2 ) {
259 sample( **minimalElement, round, m_minimumMultiplierDelta * delta, n );
260 minimalElement = std::min_element(
261 activePoints.begin(),activePoints.end(),
262 [](SetIter
const& a, SetIter
const& b){
return a->approximatedContribution < b->approximatedContribution;}
267 double erase_level = (*minimalElement)->contributionUpperBound;
268 auto erase_start = std::remove_if(
269 activePoints.begin(),activePoints.end(),
270 [=](SetIter
const&
point){
return point->contributionLowerBound > erase_level;}
272 activePoints.erase(erase_start,activePoints.end());
275 if(activePoints.size() == 1)
276 return activePoints.front();
283 for(
auto it = activePoints.begin(); it != activePoints.end(); ++it ) {
284 if( it == minimalElement )
287 double den = (*it)->contributionLowerBound;
289 d = std::numeric_limits<double>::max();
291 d = std::max(d,nom/den);
295 if(d < 1. + m_errorBound){
296 return *minimalElement;
309 template<
class VectorType>
313 double logFactor = std::log( 2. * n * (1. + m_gamma) / (m_errorProbability * m_gamma) );
314 double logR = std::log( static_cast<double>( r ) );
319 std::size_t threshold =
static_cast<std::size_t
>(thresholdD);
324 for(
unsigned int i = 0; i < point.
sample.size(); i++ ) {
349 template<
typename Set,
typename VectorType>
350 bool isPointDominated( Set
const&
set,
VectorType const& point )
const{
352 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>
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>
432 std::vector<VectorType> transformedPoints(numPoints);
433 for(std::size_t j = 0; j != numPoints; ++j){