Skip to content

Commit

Permalink
Fix wrong scoring tendancy
Browse files Browse the repository at this point in the history
CURA-12324
When processing the last criterion pass, we used to keep all the best candidates in regard to the scoring threshold, then the first one of them would be returned, which is not always the one with the actual best score. Now we just early-out with the best candidate in case of the last pass. This is also more efficient.
  • Loading branch information
wawanbreton committed Nov 22, 2024
1 parent ffe59a8 commit 6b20571
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
3 changes: 2 additions & 1 deletion include/utils/scoring/BestElementFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ScoringCriterion;

/*!
* This class implements an algorithm to find an element amongst a list, regarding one or multiple scoring criteria. The
* criteria are implemented by subclassing the CriterionScoring class. It is also possible to setup multiple passes of
* criteria are implemented by subclassing the CriterionScoring class. It is also possible to set up multiple passes of
* criteria. Thus, if the first pass gives a few best candidates that are too close to each other, we keep only the best
* candidates and process a second pass with different criteria, and so on until we have a single outsider, or no more
* criteria.
Expand Down Expand Up @@ -60,6 +60,7 @@ class BestElementFinder
* Once we have calculated the global scores of each element for this pass, we calculate the score difference
* between the best candidate and the following ones. If the following ones have a score close enough to the
* best, within this threshold, they will also be considered outsiders and will be run for the next pass.
* This value will be ignored for the last pass.
*/
double outsider_delta_threshold{ 0.0 };
};
Expand Down
29 changes: 23 additions & 6 deletions src/utils/scoring/BestElementFinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <limits>

#include <range/v3/view/enumerate.hpp>

#include "utils/scoring/ScoringCriterion.h"

namespace cura
Expand Down Expand Up @@ -33,11 +35,11 @@ std::optional<size_t> cura::BestElementFinder::findBestElement(const size_t cand
const auto begin = best_candidates.begin();
auto end = best_candidates.end();

// Now run the criteria passes until we have a single outsider or no more cirteria
for (const CriteriaPass& criteria_pass : criteria_)
// Now run the criteria passes until we have a single outsider or no more criteria
for (const auto& [pass_index, criteria_pass] : criteria_ | ranges::views::enumerate)
{
// For each element, reset score, process each criterion and apply weights to get the global score
double best_score = 0.0;
auto best_candidate_iterator = end;
for (auto iterator = begin; iterator != end; ++iterator)
{
iterator->score = 0.0;
Expand All @@ -47,17 +49,32 @@ std::optional<size_t> cura::BestElementFinder::findBestElement(const size_t cand
iterator->score += weighed_criterion.criterion->computeScore(iterator->candidate_index) * weighed_criterion.weight;
}

best_score = std::max(best_score, iterator->score);
if (best_candidate_iterator == end || iterator->score > best_candidate_iterator->score)
{
best_candidate_iterator = iterator;
}
}

if (best_candidate_iterator == end)
{
// Something got wrong, we have not best candidate
return std::nullopt;
}

// Early out for last pass, just keep the best candidate
if (pass_index == criteria_.size() - 1)
{
return best_candidate_iterator->candidate_index;
}

// Skip candidates that have a score too far from the actual best one
const double delta_threshold = criteria_pass.outsider_delta_threshold + std::numeric_limits<double>::epsilon();
end = std::remove_if(
begin,
end,
[&best_score, &delta_threshold](const Candidate& candidate)
[&best_candidate_iterator, &delta_threshold](const Candidate& candidate)
{
return best_score - candidate.score > delta_threshold;
return best_candidate_iterator->score - candidate.score > delta_threshold;
});

if (std::distance(begin, end) == 1)
Expand Down

0 comments on commit 6b20571

Please sign in to comment.