28 #ifndef SHARK_ALGORITHMS_DIRECTSEARCH_OPERATORS_DOMINATION_DCNONDOMINATEDSORT_H 29 #define SHARK_ALGORITHMS_DIRECTSEARCH_OPERATORS_DOMINATION_DCNONDOMINATEDSORT_H 76 Point(RealVector
const& objvec)
77 : obj(objvec.raw_storage().values)
79 , m_size(objvec.size())
82 bool operator<(Point
const& rhs)
const{
83 for (std::size_t i=0; i<m_size; i++)
85 if (obj[i] < rhs.obj[i])
return true;
86 if (obj[i] > rhs.obj[i])
return false;
91 for (std::size_t i=0; i<m_size; i++)
93 if (obj[i] != rhs.obj[i])
return false;
104 typedef std::vector<Point*> ContainerType;
105 typedef std::map<unsigned int, double> MapType;
106 typedef std::set<std::size_t, std::greater<std::size_t> > SetType;
107 typedef std::map<double, SetType > InverseMapType;
115 template<
typename Po
intRange,
typename RankRange>
116 void operator () (PointRange
const& pointRange, RankRange& rankRange)
118 SIZE_CHECK(pointRange.size() == rankRange.size());
119 std::size_t m = pointRange[0].size();
121 std::vector<Point> points(pointRange.size());
122 std::transform(pointRange.begin(),pointRange.end(),points.begin(),[](RealVector
const& point){
125 std::sort(points.begin(),points.end());
126 points.erase(std::unique(points.begin(),points.end()),points.end());
127 ContainerType
S(points.size());
128 for (std::size_t i = 0; i != points.size(); ++i)
137 for (std::size_t i = 0; i != pointRange.size(); ++i)
139 auto it = std::lower_bound(points.begin(), points.end(), Point(pointRange[i]));
141 rankRange[i] = it->frt;
149 return shark::dominance(blas::adapt_vector(k,lhs->obj),blas::adapt_vector(k,rhs->obj));
158 void ndHelperA(ContainerType&
S, std::size_t k)
160 if (S.size() < 2)
return;
165 S[1]->frt = std::max(S[1]->frt, S[0]->frt + 1);
177 for (std::size_t i=1; i<S.size(); i++)
179 if (S[0]->obj[k-1] != S[i]->obj[k-1])
196 ndHelperB(L, H, k-1);
215 void sweepA(ContainerType& S)
218 T[S[0]->frt] = S[0]->obj[1];
219 for (std::size_t i=1; i<S.size(); i++)
225 if (p.second <= S[i]->obj[1]) r = std::max(r, p.first);
228 if (r > 0) S[i]->frt = std::max(S[i]->frt, r + 1);
230 T[S[i]->frt] = S[i]->obj[1];
235 double median(ContainerType
const& S, std::size_t k)
237 std::vector<double> value(S.size());
238 for (std::size_t i=0; i<S.size(); i++) value[i] = S[i]->obj[k];
239 std::nth_element(value.begin(), value.begin() + value.size() / 2, value.end());
240 double ret = value[value.size() / 2];
241 if (S.size() & 1)
return ret;
242 ret += *std::max_element(value.begin(), value.begin() + value.size() / 2);
251 void splitA(ContainerType
const& S, std::size_t k, ContainerType& L, ContainerType& H)
256 double med = median(S, k);
257 ContainerType La, Lb, Ha, Hb;
258 for (std::size_t i=0; i<S.size(); i++)
260 double v = S[i]->obj[k];
277 if (Lb.size() < Ha.size())
301 void ndHelperB(ContainerType
const& L, ContainerType& H, std::size_t k)
303 if (L.empty() || H.empty())
return;
304 if (L.size() == 1 || H.size() == 1)
306 for (std::size_t j=0; j<H.size(); j++)
308 for (std::size_t i=0; i<L.size(); i++)
313 H[j]->frt = std::max(H[j]->frt, L[i]->frt + 1);
324 double minLk = L[0]->obj[k-1];
325 double maxLk = L[0]->obj[k-1];
326 for (std::size_t i=1; i<L.size(); i++)
328 double v = L[i]->obj[k-1];
329 minLk = std::min(minLk, v);
330 maxLk = std::max(maxLk, v);
332 double minHk = H[0]->obj[k-1];
333 double maxHk = H[0]->obj[k-1];
334 for (std::size_t i=1; i<H.size(); i++)
336 double v = H[i]->obj[k-1];
337 minHk = std::min(minHk, v);
338 maxHk = std::max(maxHk, v);
342 ndHelperB(L, H, k-1);
347 ContainerType L1, L2, H1, H2;
348 splitB(L, H, k, L1, L2, H1, H2);
349 ndHelperB(L1, H1, k);
350 ndHelperB(L1, H2, k - 1);
351 ndHelperB(L2, H2, k);
359 void sweepB(ContainerType
const& L, ContainerType& H)
363 for (std::size_t j=0; j<H.size(); j++)
367 if (L[i]->obj[0] > H[j]->obj[0])
break;
368 if (L[i]->obj[0] == H[j]->obj[0] && L[i]->obj[1] > H[j]->obj[1])
break;
369 auto it = T.find(L[i]->frt);
370 if (it == T.end() || L[i]->obj[1] < it->second)
372 T[L[i]->frt] = L[i]->obj[1];
381 if (p.second <= H[j]->obj[1]) r = std::max(r, p.first);
386 H[j]->frt = std::max(H[j]->frt, r + 1);
397 void splitB(ContainerType
const& L, ContainerType
const& H, std::size_t k,
398 ContainerType& L1, ContainerType& L2, ContainerType& H1, ContainerType& H2)
401 double pivot = median((L.size() > H.size()) ? L : H, k);
403 ContainerType L1a, L1b, L2a, L2b;
404 for (std::size_t i=0; i<L.size(); i++)
406 double v = L[i]->obj[k];
424 ContainerType H1a, H1b, H2a, H2b;
425 for (std::size_t i=0; i<H.size(); i++)
427 double v = H[i]->obj[k];
445 if (L1b.size() + H1b.size() <= L2a.size() + H2a.size())
465 template<
class Po
intRange,
class RankRange>
468 sorter(points,ranks);