@@ -339,18 +339,16 @@ find_nondominated_set_2d_(const double * restrict points, size_t size,
339339 D. Jesus, Luís Paquete, A software library for archiving nondominated
340340 points, GECCO 2021. https://github.com/TLDart/nondLib/blob/main/nondlib.hpp
341341
342- rows will be sorted by cmp_ppdouble_asc_rev_3d().
343- max_dim will be != 3 only if the rows pointers have been shifted.
342+ rows should be already sorted by cmp_ppdouble_asc_rev_3d().
343+
344+ When find_one_dominated, return as soon as it finds one dominated point.
344345*/
345- static inline size_t
346- find_nondominated_set_3d_helper (const double * restrict points ,
347- const double * * rows ,
348- size_t size , dimension_t max_dim ,
349- const bool keep_weakly , boolvec * restrict nondom )
346+ static __force_inline__ size_t
347+ find_nondominated_3d_impl_sorted (const double * * restrict rows , size_t size ,
348+ const bool keep_weakly ,
349+ const bool find_one_dominated )
350350{
351351 ASSUME (size > 1 );
352- // Sort in ascending lexicographic order from the last dimension.
353- qsort_typesafe (rows , size , cmp_ppdouble_asc_rev_3d );
354352
355353 avl_tree_t tree ;
356354 avl_init_tree (& tree , qsort_cmp_pdouble_asc_x_nonzero );
@@ -428,16 +426,13 @@ find_nondominated_set_3d_helper(const double * restrict points,
428426 DEBUG2 (printf_point ("weakly dominated by pk: " , pk , 3 , "\n" ));
429427 }
430428 if (dominated ) { // pj is dominated by a point in the tree or by prev.
431- /* Map the order in rows[], which is sorted, to the original order
432- in points. */
433- size_t pos_last_dom = row_index_from_ptr (points , pj , max_dim );
434- if (unlikely (nondom == NULL )) {
429+ if (find_one_dominated ) {
435430 // In this context, it means "position of the first dominated solution found".
436- new_size = pos_last_dom ;
431+ new_size = j ;
437432 goto early_end ;
438433 }
439- nondom [pos_last_dom ] = false;
440434 last_dom = pj ;
435+ rows [j ] = NULL ;
441436 new_size -- ;
442437 } else {
443438 pk = pj ;
@@ -450,13 +445,30 @@ find_nondominated_set_3d_helper(const double * restrict points,
450445 return new_size ;
451446}
452447
448+ static __force_inline__ size_t
449+ find_nondominated_3d_impl (const double * * restrict rows , size_t size ,
450+ const bool keep_weakly ,
451+ const bool find_one_dominated )
452+ {
453+ // Sort in ascending lexicographic order from the last dimension.
454+ qsort_typesafe (rows , size , cmp_ppdouble_asc_rev_3d );
455+ // Help GCC generate all possible specializations of this function.
456+ return find_one_dominated
457+ ? (keep_weakly
458+ ? find_nondominated_3d_impl_sorted (rows , size , true, true)
459+ : find_nondominated_3d_impl_sorted (rows , size , false, true))
460+ : (keep_weakly
461+ ? find_nondominated_3d_impl_sorted (rows , size , true, false)
462+ : find_nondominated_3d_impl_sorted (rows , size , false, false));
463+ }
464+
453465static inline size_t
454466find_dominated_3d_ (const double * restrict points , size_t size , bool keep_weakly )
455467{
456468 const double * * rows = generate_row_pointers (points , size , 3 );
457- size_t pos = keep_weakly
458- ? find_nondominated_set_3d_helper ( points , rows , size , 3 , true, /* nondom=*/ NULL )
459- : find_nondominated_set_3d_helper (points , rows , size , 3 , false, /* nondom=*/ NULL );
469+ size_t pos = find_nondominated_3d_impl ( rows , size , keep_weakly , /* find_one_dominated=*/ true);
470+ if ( pos < size )
471+ pos = row_index_from_ptr (points , rows [ pos ], 3 );
460472 free (rows );
461473 return pos ;
462474}
@@ -469,11 +481,20 @@ static inline size_t
469481find_nondominated_set_3d_ (const double * restrict points , size_t size ,
470482 const bool keep_weakly , boolvec * restrict nondom )
471483{
472- const double * * rows = generate_row_pointers (points , size , 3 );
473484 ASSUME (nondom != NULL );
474- size_t new_size = keep_weakly
475- ? find_nondominated_set_3d_helper (points , rows , size , 3 , true, nondom )
476- : find_nondominated_set_3d_helper (points , rows , size , 3 , false, nondom );
485+ const double * * rows = generate_row_pointers (points , size , 3 );
486+ size_t new_size = find_nondominated_3d_impl (rows , size , keep_weakly , /* find_one_dominated=*/ false);
487+
488+ if (new_size < size ) {
489+ memset (nondom , 0 , size * sizeof (* nondom ));
490+ size_t k = 0 , n = 0 ;
491+ do {
492+ while (rows [k ] == NULL ) k ++ ; // Find next nondominated (there must be at least one).
493+ nondom [row_index_from_ptr (points , rows [k ], 3 )] = true;
494+ n ++ ;
495+ k ++ ;
496+ } while (n < new_size );
497+ }
477498 free (rows );
478499 return new_size ;
479500}
@@ -675,7 +696,7 @@ find_nondominated_set_(const double * restrict points, size_t size, dimension_t
675696 } else if (dim == 3 ) {
676697 new_size = find_nondominated_set_3d_ (pp , size , keep_weakly , nondom );
677698 } else {
678- new_size = find_nondominated_set_agree_kung (pp , size , dim , keep_weakly , nondom );
699+ new_size = find_nondominated_set_kung (pp , size , dim , keep_weakly , nondom );
679700 }
680701 if (pp != points )
681702 free ((void * ) pp );
0 commit comments