refactor(planning): extract applyPenalties helper to unify score formula

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 15:08:49 +02:00
parent 49ed75a989
commit 116e400a91

View File

@@ -216,10 +216,6 @@ public class PlanningService {
private double scoreFromSimulatedSlots(List<SimulatedSlot> slots, VarietyScoreConfig config, private double scoreFromSimulatedSlots(List<SimulatedSlot> slots, VarietyScoreConfig config,
Set<UUID> recentlyCookedIds) { Set<UUID> recentlyCookedIds) {
List<String> checkedTagTypes = config.getRepeatTagTypes(); List<String> checkedTagTypes = config.getRepeatTagTypes();
double wTagRepeat = config.getWTagRepeat().doubleValue();
double wIngredientOverlap = config.getWIngredientOverlap().doubleValue();
double wRecentRepeat = config.getWRecentRepeat().doubleValue();
double wPlanDuplicate = config.getWPlanDuplicate().doubleValue();
// 1. Tag-type repeats on consecutive days // 1. Tag-type repeats on consecutive days
Map<String, List<LocalDate>> tagDays = new LinkedHashMap<>(); Map<String, List<LocalDate>> tagDays = new LinkedHashMap<>();
@@ -259,11 +255,16 @@ public class PlanningService {
.mapToLong(c -> c - 1) .mapToLong(c -> c - 1)
.sum(); .sum();
return applyPenalties(tagRepeatCount, ingredientOverlapCount, recentRepeatCount, duplicatePenaltyCount, config);
}
private double applyPenalties(long tagRepeats, long ingredientOverlaps, long recentRepeats,
long duplicates, VarietyScoreConfig config) {
double score = MAX_VARIETY_SCORE; double score = MAX_VARIETY_SCORE;
score -= tagRepeatCount * wTagRepeat; score -= tagRepeats * config.getWTagRepeat().doubleValue();
score -= ingredientOverlapCount * wIngredientOverlap; score -= ingredientOverlaps * config.getWIngredientOverlap().doubleValue();
score -= recentRepeatCount * wRecentRepeat; score -= recentRepeats * config.getWRecentRepeat().doubleValue();
score -= duplicatePenaltyCount * wPlanDuplicate; score -= duplicates * config.getWPlanDuplicate().doubleValue();
return Math.max(0, Math.min(MAX_VARIETY_SCORE, score)); return Math.max(0, Math.min(MAX_VARIETY_SCORE, score));
} }
@@ -281,10 +282,6 @@ public class PlanningService {
.orElse(VarietyScoreConfig.defaults(plan.getHousehold())); .orElse(VarietyScoreConfig.defaults(plan.getHousehold()));
List<String> checkedTagTypes = config.getRepeatTagTypes(); List<String> checkedTagTypes = config.getRepeatTagTypes();
double wTagRepeat = config.getWTagRepeat().doubleValue();
double wIngredientOverlap = config.getWIngredientOverlap().doubleValue();
double wRecentRepeat = config.getWRecentRepeat().doubleValue();
double wPlanDuplicate = config.getWPlanDuplicate().doubleValue();
int historyDays = config.getHistoryDays(); int historyDays = config.getHistoryDays();
// 1. Tag-type repeats on consecutive days // 1. Tag-type repeats on consecutive days
@@ -352,13 +349,7 @@ public class PlanningService {
} }
} }
// Calculate score double score = applyPenalties(tagRepeats.size(), overlaps.size(), recentRepeats.size(), duplicatePenaltyCount, config);
double score = MAX_VARIETY_SCORE;
score -= tagRepeats.size() * wTagRepeat;
score -= overlaps.size() * wIngredientOverlap;
score -= recentRepeats.size() * wRecentRepeat;
score -= duplicatePenaltyCount * wPlanDuplicate;
score = Math.max(0, Math.min(MAX_VARIETY_SCORE, score));
return new VarietyScoreResponse(score, tagRepeats, overlaps, recentRepeats, duplicatesInPlan); return new VarietyScoreResponse(score, tagRepeats, overlaps, recentRepeats, duplicatesInPlan);
} }