55
66#include < limits>
77
8+ #include < range/v3/view/enumerate.hpp>
9+
810#include " utils/scoring/ScoringCriterion.h"
911
1012namespace cura
@@ -33,11 +35,11 @@ std::optional<size_t> cura::BestElementFinder::findBestElement(const size_t cand
3335 const auto begin = best_candidates.begin ();
3436 auto end = best_candidates.end ();
3537
36- // Now run the criteria passes until we have a single outsider or no more cirteria
37- for (const CriteriaPass& criteria_pass : criteria_)
38+ // Now run the criteria passes until we have a single outsider or no more criteria
39+ for (const auto & [pass_index, criteria_pass] : criteria_ | ranges::views::enumerate )
3840 {
3941 // For each element, reset score, process each criterion and apply weights to get the global score
40- double best_score = 0.0 ;
42+ auto best_candidate_iterator = end ;
4143 for (auto iterator = begin; iterator != end; ++iterator)
4244 {
4345 iterator->score = 0.0 ;
@@ -47,17 +49,32 @@ std::optional<size_t> cura::BestElementFinder::findBestElement(const size_t cand
4749 iterator->score += weighed_criterion.criterion ->computeScore (iterator->candidate_index ) * weighed_criterion.weight ;
4850 }
4951
50- best_score = std::max (best_score, iterator->score );
52+ if (best_candidate_iterator == end || iterator->score > best_candidate_iterator->score )
53+ {
54+ best_candidate_iterator = iterator;
55+ }
56+ }
57+
58+ if (best_candidate_iterator == end)
59+ {
60+ // Something went wrong, we don't have a best candidate
61+ return std::nullopt ;
62+ }
63+
64+ // Early out for last pass, just keep the best candidate
65+ if (pass_index == criteria_.size () - 1 )
66+ {
67+ return best_candidate_iterator->candidate_index ;
5168 }
5269
5370 // Skip candidates that have a score too far from the actual best one
5471 const double delta_threshold = criteria_pass.outsider_delta_threshold + std::numeric_limits<double >::epsilon ();
5572 end = std::remove_if (
5673 begin,
5774 end,
58- [&best_score , &delta_threshold](const Candidate& candidate)
75+ [&best_candidate_iterator , &delta_threshold](const Candidate& candidate)
5976 {
60- return best_score - candidate.score > delta_threshold;
77+ return best_candidate_iterator-> score - candidate.score > delta_threshold;
6178 });
6279
6380 if (std::distance (begin, end) == 1 )
0 commit comments