Skip to content

Commit affe870

Browse files
Copilotszmyty
andauthored
fix: deduplicate paths with identical objectives in pareto_frontier
Agent-Logs-Url: https://github.com/egohygiene/renderflow/sessions/5c27cf14-d7aa-4746-9457-cd8f0d99b693 Co-authored-by: szmyty <14865041+szmyty@users.noreply.github.com>
1 parent f56e7c2 commit affe870

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

src/optimization.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,19 @@ pub fn pareto_frontier(paths: &[TransformPath], cap: Option<usize>) -> Vec<Trans
105105
}
106106

107107
// Sort by total_cost ascending (cheapest first).
108+
// Paths with NaN metrics sort as equal to each other due to partial_cmp fallback.
108109
frontier.sort_by(|a, b| {
109110
a.total_cost
110111
.partial_cmp(&b.total_cost)
111112
.unwrap_or(std::cmp::Ordering::Equal)
112113
});
113114

115+
// Deduplicate paths with identical objectives: two paths that share both
116+
// total_cost and total_quality represent the same trade-off point and only
117+
// one needs to be kept in the frontier.
118+
let mut seen = std::collections::HashSet::new();
119+
frontier.retain(|p| seen.insert((p.total_cost.to_bits(), p.total_quality.to_bits())));
120+
114121
if let Some(limit) = cap {
115122
frontier.truncate(limit);
116123
}
@@ -339,12 +346,11 @@ mod tests {
339346
}
340347

341348
#[test]
342-
fn test_pareto_frontier_equal_paths_not_dominated() {
343-
// Two identical paths: neither dominates the other (no strict improvement).
349+
fn test_pareto_frontier_equal_paths_deduplicated() {
350+
// Two paths with identical objectives: only one should be kept.
344351
let paths = vec![make_path(1.0, 0.9), make_path(1.0, 0.9)];
345352
let frontier = pareto_frontier(&paths, None);
346-
// Both are kept since neither strictly dominates the other.
347-
assert_eq!(frontier.len(), 2);
353+
assert_eq!(frontier.len(), 1);
348354
}
349355

350356
#[test]

0 commit comments

Comments
 (0)