solver: select skyline candidate policy

Make candidate ordering an explicit deterministic policy and benchmark ascending, descending, and exact-width-first choices. Keep ascending as the default because it produces the best measured time to first solution despite best-fit's slightly smaller tree.

Retain the benchmark v1 interface and document why randomized and duplicate-work portfolio policies are deferred.

Tests: Release and Debug CTest (10 passed each)

Refs: #12
This commit was merged in pull request #24.
This commit is contained in:
Codex instance
2026-07-30 18:07:29 +01:00
parent d751d1b13e
commit 74bde266d0
6 changed files with 141 additions and 49 deletions
+20 -4
View File
@@ -249,8 +249,10 @@ namespace {
auto test_odd_solver_route() -> int {
SearchCounters even_counters;
SearchCounters odd_counters;
auto const even = find_solution_instrumented(8, even_counters);
auto const odd = find_solution_instrumented(9, odd_counters);
auto const even =
find_solution_instrumented(8, even_counters, SearchPolicy::best_fit);
auto const odd =
find_solution_instrumented(9, odd_counters, SearchPolicy::best_fit);
int failures = 0;
failures += expect(
@@ -358,7 +360,7 @@ namespace {
SearchCounters descending_counters;
auto const descending = search_solution_instrumented(
8, descending_counters, CandidateOrder::descending);
8, descending_counters, SearchPolicy::descending);
auto validation = validate(8, descending);
failures += expect(
validation.valid(),
@@ -367,7 +369,7 @@ namespace {
SearchCounters direct_nine_counters;
auto const direct_nine = search_solution_instrumented(
9, direct_nine_counters, CandidateOrder::ascending);
9, direct_nine_counters, SearchPolicy::ascending);
validation = validate(9, direct_nine);
failures += expect(
validation.valid(),
@@ -376,6 +378,20 @@ namespace {
failures += expect(
direct_nine_counters.search_nodes != descending_counters.search_nodes,
"direct order-9 coverage unexpectedly reused predecessor construction");
SearchCounters ascending_exhaustive;
SearchCounters descending_exhaustive;
SearchCounters best_fit_exhaustive;
static_cast<void>(search_solution_instrumented(
5, ascending_exhaustive, SearchPolicy::ascending));
static_cast<void>(search_solution_instrumented(
5, descending_exhaustive, SearchPolicy::descending));
static_cast<void>(search_solution_instrumented(
5, best_fit_exhaustive, SearchPolicy::best_fit));
failures += expect(
ascending_exhaustive.search_nodes == descending_exhaustive.search_nodes &&
ascending_exhaustive.search_nodes == best_fit_exhaustive.search_nodes,
"candidate policy changed the exhaustive skyline search space");
return failures;
}