From e1986e4658019f01f4ba48192b38c56322e4dc54 Mon Sep 17 00:00:00 2001 From: jcoupey Date: Thu, 12 Dec 2024 15:21:16 +0100 Subject: [PATCH 1/4] Add helper function for vector hash. --- src/utils/helpers.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/utils/helpers.h b/src/utils/helpers.h index 4eb10fd5..a7aba6d5 100644 --- a/src/utils/helpers.h +++ b/src/utils/helpers.h @@ -38,6 +38,18 @@ inline UserCost add_without_overflow(UserCost a, UserCost b) { return a + b; } +// Taken from https://stackoverflow.com/a/72073933. +inline uint32_t get_vector_hash(const std::vector& vec) { + uint32_t seed = vec.size(); + for (auto x : vec) { + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = (x >> 16) ^ x; + seed ^= x + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + return seed; +} + inline unsigned get_depth(unsigned exploration_level) { return exploration_level; } From 85212f9d2e85f47efa2f91bdee6bbb03bd1e6418 Mon Sep 17 00:00:00 2001 From: jcoupey Date: Thu, 12 Dec 2024 15:22:54 +0100 Subject: [PATCH 2/4] Add route-based hash in SolutionIndicators. --- src/structures/vroom/solution_indicators.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/structures/vroom/solution_indicators.h b/src/structures/vroom/solution_indicators.h index af96ac36..540718a8 100644 --- a/src/structures/vroom/solution_indicators.h +++ b/src/structures/vroom/solution_indicators.h @@ -10,6 +10,7 @@ All rights reserved (see LICENSE). */ +#include #include #include "structures/typedefs.h" @@ -23,6 +24,8 @@ struct SolutionIndicators { unsigned assigned{0}; Eval eval; unsigned used_vehicles{0}; + // Hash based on the ordered sizes of routes in the solution. + uint32_t routes_hash; SolutionIndicators() = default; @@ -41,6 +44,14 @@ struct SolutionIndicators { used_vehicles += 1; } } + + std::vector routes_sizes; + routes_sizes.reserve(sol.size()); + std::ranges::transform(sol, + std::back_inserter(routes_sizes), + [](const auto& r) { return r.size(); }); + std::ranges::sort(routes_sizes); + routes_hash = get_vector_hash(routes_sizes); } friend bool operator<(const SolutionIndicators& lhs, From e5f23203a02539d91aed1822107a1aca8746b5ac Mon Sep 17 00:00:00 2001 From: jcoupey Date: Thu, 12 Dec 2024 15:23:19 +0100 Subject: [PATCH 3/4] Adjust SolutionIndicators comparison operators to account for hash value. --- CHANGELOG.md | 1 + src/structures/vroom/solution_indicators.h | 32 ++++++++++++---------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf55170f..3e070152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ - Crash when input is valid JSON but not an object (#1172) - Capacity array check consistency (#1086) - Segfault when using the C++ API with empty vehicles (#1187) +- Solution "shadowing" when only comparing indicators (#1199) #### Internals diff --git a/src/structures/vroom/solution_indicators.h b/src/structures/vroom/solution_indicators.h index 540718a8..d102f80e 100644 --- a/src/structures/vroom/solution_indicators.h +++ b/src/structures/vroom/solution_indicators.h @@ -61,28 +61,32 @@ struct SolutionIndicators { lhs.eval.cost, lhs.used_vehicles, lhs.eval.duration, - lhs.eval.distance) < std::tie(lhs.priority_sum, - lhs.assigned, - rhs.eval.cost, - rhs.used_vehicles, - rhs.eval.duration, - rhs.eval.distance); + lhs.eval.distance, + lhs.routes_hash) < std::tie(lhs.priority_sum, + lhs.assigned, + rhs.eval.cost, + rhs.used_vehicles, + rhs.eval.duration, + rhs.eval.distance, + rhs.routes_hash); } #ifdef LOG_LS friend bool operator==(const SolutionIndicators& lhs, const SolutionIndicators& rhs) { - return std::tie(rhs.priority_sum, - rhs.assigned, + return std::tie(lhs.priority_sum, + lhs.assigned, lhs.eval.cost, lhs.used_vehicles, lhs.eval.duration, - lhs.eval.distance) == std::tie(lhs.priority_sum, - lhs.assigned, - rhs.eval.cost, - rhs.used_vehicles, - rhs.eval.duration, - rhs.eval.distance); + lhs.eval.distance, + lhs.routes_hash) == std::tie(rhs.priority_sum, + rhs.assigned, + rhs.eval.cost, + rhs.used_vehicles, + rhs.eval.duration, + rhs.eval.distance, + rhs.routes_hash); } #endif }; From 924c22867adcfeccae295d6dadaa299dc3d225d7 Mon Sep 17 00:00:00 2001 From: jcoupey Date: Fri, 13 Dec 2024 16:14:45 +0100 Subject: [PATCH 4/4] Use free function for size on template param. --- src/structures/vroom/solution_indicators.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structures/vroom/solution_indicators.h b/src/structures/vroom/solution_indicators.h index d102f80e..d8c35af2 100644 --- a/src/structures/vroom/solution_indicators.h +++ b/src/structures/vroom/solution_indicators.h @@ -49,7 +49,7 @@ struct SolutionIndicators { routes_sizes.reserve(sol.size()); std::ranges::transform(sol, std::back_inserter(routes_sizes), - [](const auto& r) { return r.size(); }); + [](const auto& r) { return std::size(r); }); std::ranges::sort(routes_sizes); routes_hash = get_vector_hash(routes_sizes); }