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
+16 -13
View File
@@ -27,7 +27,7 @@ namespace {
};
auto solve(std::uint64_t order, bool instrument,
CandidateOrder candidate_order, bool direct_search,
SearchPolicy policy, bool direct_search,
SearchCounters &counters)
-> TimedSolution {
auto const predecessor_order =
@@ -36,8 +36,8 @@ namespace {
auto predecessor =
instrument
? search_solution_instrumented(predecessor_order, counters,
candidate_order)
: search_solution(predecessor_order, candidate_order);
policy)
: search_solution(predecessor_order, policy);
auto const search_end = Clock::now();
auto const construction_begin = Clock::now();
@@ -95,7 +95,7 @@ namespace {
int main(int argc, char **argv) {
if (argc < 3 || argc > 5) {
std::cerr << "usage: partridge_benchmark ORDER counters|plain "
"[ascending|descending] [public|direct]\n";
"[ascending|descending|best-fit] [public|direct]\n";
return 2;
}
auto const order = static_cast<std::uint64_t>(std::strtoull(argv[1], nullptr, 10));
@@ -104,13 +104,16 @@ int main(int argc, char **argv) {
std::cerr << "counter mode must be counters or plain\n";
return 2;
}
auto const candidate_order =
auto const policy =
argc < 4 || std::string_view(argv[3]) == "ascending"
? CandidateOrder::ascending
: CandidateOrder::descending;
? SearchPolicy::ascending
: std::string_view(argv[3]) == "descending"
? SearchPolicy::descending
: SearchPolicy::best_fit;
if (argc >= 4 && std::string_view(argv[3]) != "ascending" &&
std::string_view(argv[3]) != "descending") {
std::cerr << "candidate order must be ascending or descending\n";
std::string_view(argv[3]) != "descending" &&
std::string_view(argv[3]) != "best-fit") {
std::cerr << "search policy must be ascending, descending, or best-fit\n";
return 2;
}
auto const direct_search =
@@ -122,8 +125,7 @@ int main(int argc, char **argv) {
}
SearchCounters counters;
auto timed =
solve(order, instrument, candidate_order, direct_search, counters);
auto timed = solve(order, instrument, policy, direct_search, counters);
auto const validation_begin = Clock::now();
auto const validation_ok = valid(order, timed.result);
@@ -142,8 +144,9 @@ int main(int argc, char **argv) {
<< ",\"order\":" << order
<< ",\"instrumented\":" << boolean(instrument)
<< ",\"candidate_order\":\""
<< (candidate_order == CandidateOrder::ascending ? "ascending"
: "descending")
<< (policy == SearchPolicy::ascending
? "ascending"
: policy == SearchPolicy::descending ? "descending" : "best-fit")
<< "\""
<< ",\"search_route\":\""
<< (direct_search ? "direct" : "public") << "\""