Conversation
Extract DFS-with-backtracking machinery shared by Greedy and Tabu into a new BacktrackingDiveAlgorithm base, owning path_, dive primitives (extend_label, backtrack), path lifecycle, and a child_comparator hook. Pull tabu-list bookkeeping shared by TabuSearchAlgorithm and DiversificationSearch (arc_id->tenure map, adaptive extra tenure with optional jitter, aging with optional on-expire callback, grow/shrink) into a new TabuList helper used by composition in both. New TabuSearchAlgorithm: peer of GreedyAlgorithm, episodic dives with arc tabu memory + aspiration. Customises only select_children and main_loop. child_comparator on the base: when graph_->are_nodes_sorted(), prefer forward arcs (destination pos > parent pos) before backward ones; within each group, cost-ascending. Both Greedy and Tabu inherit this so dives follow the user-supplied node ordering's intended tour layout instead of jumping cheaply but late and having to backtrack to early required. Slim refactor of GreedyAlgorithm onto the new base. DiversificationSearch now uses TabuList. Minor tweaks in dominance_algorithm.hpp and pulling_dominance_algorithm.hpp to align with the refactor. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…er based on size, Add a solver status, Add a pointer to the previous label with a ref count to easily rebuild a path.
- Replace std::list<size_t> with std::vector<size_t> for Solution::path_node_ids/path_arc_ids and VRP Path::visited_nodes, eliminating cache-hostile linked-list traversal on the hot path. - Extend CI matrix to test Python 3.11/3.12/3.13 on macOS and Linux with pytest --tb=short; exclude Debug builds for 3.11 and 3.13. - Add py.typed PEP 561 marker and _core/*.pyi stub files so IDEs provide autocompletion for all C++-backed types. - Update CMakeLists.txt to copy and install .pyi and py.typed alongside the Python package. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Four improvements to LabelBuckets<BucketResource, SortResource, ResourceType>: 1. buckets_ list → vector: cache-friendly bucket iteration and random-access indexing required by the binary search helpers below. 2. O(log B) bucket lookup: find_first_not_after / find_first_before binary- search helpers replace the O(B) linear scans in add_label (find insertion bucket), remove_dominated_labels (find first relevant bucket), and is_dominated (find last relevant bucket). 3. O(1) erase_label: begin_label_to_bucket_idx_ (unordered_map<Label*, size_t>) maps each current bucket-begin label to its bucket index. A single map lookup replaces the O(B) std::find_if scan over all bucket begins. The map is maintained by insert_bucket / remove_bucket / update_bucket_begin (O(B) index-shift cost there, but bucket operations are O(B) total vs. O(N) erase_label calls). 4. Symmetric instrumentation: num_dom_labels_ / num_dom_visited_ counters added to is_dominated (mirroring the existing remove_dominated stats). print_labels reports both visit ratios. Also exposes suggest_range(target_buckets) which uses the peak simultaneous bucket count to estimate the resource spread and suggest a calibrated range_buckets for subsequent phases. Bug fixed during implementation: the ++removed increment in remove_dominated_labels was placed after the break that fires when a full bucket is emptied, causing dominated labels to go uncounted in that path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add four unit tests covering binary-search and map-maintenance code paths (RemoveDominatedMultiBucket, IsDominatedMultiBucket, EraseBeginMultiBucket, SuggestRange). Add BucketS and BucketP benchmark columns by running a second independent solve per instance with LabelBuckets + SimpleDominanceAlgorithm and PullingDominanceAlgorithm. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r_each_arc non-const overload - ExtraSolver type-erased struct + run_algorithm public wrapper enable bucket-container algorithms to participate in the same CG solve as list-container algorithms, sharing duals and cross-checking costs - run_boost normalized at top of solve; warns + disables if Boost not compiled in; drives num_total_algos and algo_index correctly - collect_solutions cross-checks costs (not counts) between optimal algos - benchmark uses --boost flag; bucket algorithms run as ExtraSolvers - Graph::for_each_arc gains non-const overload for update_reduced_costs - CMakeLists: Boost optional at compile time via RCSPP_VRP_HAS_BOOST Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…container Parent-pointer O(hops) reconstruction: - Label gains public parent_ and child_refcount_ fields (initialized to null/0 in both constructors and reset_label) - LabelPool::release_label checks child_refcount_; if > 0, defers recycling. do_release() cascades up the parent chain when a label's last child is gone, avoiding any zombie memory retention - DominanceAlgorithm::extend_label sets parent_ and bumps child_refcount_ only when the child survives feasibility and dominance checks - get_path_arc_ids replaced with a simple parent-pointer walk - GreedyAlgorithm unaffected: never calls DominanceAlgorithm::extend_label AlgorithmBaseParams::with_container: - Forward-declare AlgorithmParams before AlgorithmBaseParams so the member function template can name its return type - Define with_container out-of-line after AlgorithmParams is complete - Allows: base.with_container<LabelList<RT>>() or base.with_container(std::move(bucket_container)) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace ternary-constructed vector with a base vector + conditional insert, making the Boost column addition easier to read. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rkflow
SolveResult:
- Template VRP::solve() now returns SolveResult{timers, lp_cost} instead
of a bare vector; lp_cost is the final master LP objective after CG
benchmark_common.hpp (new, shared by both benchmark binaries):
- kSolomonBKS: inline map of BKS values for C1/R1/RC1/C2/R2/RC2
- format_benchmark_table(): prints Instance | LP Cost | Gap% | per-algo HH:MM:SS
Gap% = (lp_cost - bks) / bks * 100; flags FAIL if lp_cost > bks + 1e-3
Total row accumulates timers; cost/gap columns show '-' there
benchmark_main.cpp (C1/R1/RC1, formerly print_timer_table):
- Uses structured binding auto [timers, lp_cost] = vrp.solve<...>(...)
- Collects rows and prints one table at the end via format_benchmark_table
benchmark_large_main.cpp (new, C2/R2/RC2 + Gehring & Homberger):
- run_vrp() helper avoids duplication; shares all algorithm setup
- --r2-max N: override R2 instance count (R2 has 11, C2/RC2 have 8)
- --gh-dir path: scan a directory of Solomon-format .txt files for
Gehring & Homberger 200-1000-customer instances
CMakeLists.txt: add rcspp-vrp-benchmark-large target; exclude both
benchmark_*_main.cpp from the shared SOURCE_FILES glob
.github/workflows/benchmark.yml (new):
- workflow_dispatch with inputs: max_instances, run_large, max_large_instances
- Builds Release, runs small and optionally large benchmark
- Uploads results as artifacts keyed by commit SHA
- NOTE: Gurobi must be available on the runner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add MemoryInfo struct (cross-platform RSS / available / total RAM) - Add MemoryLimitHelper struct (resolve + is_exceeded + is_under_pressure) both live in utils/memory.hpp; MemoryLimitHelper takes plain values so it has no dependency on AlgorithmBaseParams - Add kKB / kMB / kGB / kDefaultMemoryPressureFraction to memory.hpp - Add AlgorithmBaseParams memory fields: max_memory_gb, limit_to_available_ram, limit_to_total_ram, memory_limit_fraction, memory_check_interval, memory_pressure_fraction, memory_pressure_max_labels_per_node - Add effective_max_labels_per_node_ and memory_pressure_triggered_ to Algorithm - Add virtual on_memory_pressure() and release_label_memory() hooks - Implement on_memory_pressure() in Simple / Pushing / Pulling algorithms: tightens per-node cap, two-phase trim (store aside then release) - Call release_label_memory() at end of every solve() to reclaim RSS - Add LabelPool::release() (clear + shrink_to_fit) - Add ResourceGraph::solve(AlgorithmBaseParams, ...) overload - Add 12 new tests (4 templates x 3 algorithm types): MemoryLimitImmediateStop, MemoryLimitAvailableRam, MemoryLimitTotalRam, MemoryPressurePruning - Extend .gitignore to cover build_*/ directories - Exclude build directories from markdownlint pre-commit hook - Move fstream/string includes to top of memory.hpp for cpplint IWYU Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the per-row std::vector<Row>{one_element} construction pattern
(N malloc/free pairs) with a single-pass approach over arc_id runs:
- Rows array arrives pre-sorted by arc_id (guaranteed by the Python caller).
- Loop advances j to find the end of each run, reserves capacity once
per arc (dr.reserve), then push_back-fills directly — no temporary
vector, no repeated heap allocations.
For N_rows rows across N_arcs arcs this reduces:
old: N_rows × (1 malloc + 1 free + 1 push_back + bounds check)
new: N_arcs × 1 reserve + N_rows × 1 push_back
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MemoryLimitHelper::resolve() is called on every G.solve() invocation. With LOG_INFO, a run with thousands of pricing calls emits an identical 'Memory limit: X GB (explicit).' line for each one, flooding the logs. Demote all resolve() log messages to LOG_DEBUG — they remain visible when debug logging is enabled but are silent in normal operation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each resolve() debug message now appends the current process RSS (from MemoryInfo::process_bytes()): 'Memory limit: 2 GB (explicit); process RSS: 312 MB.' This makes the message immediately actionable when debugging OOM or early-exit situations — no need to correlate with an external profiler. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolved merge conflicts between quick-improvements (HEAD) and tight-lb, preferring HEAD's changes when uncertain: - Keep HEAD's memory-limit infrastructure (MemoryLimitHelper, max_memory_gb, memory_check_interval, memory_pressure_fraction, etc.) - Keep HEAD's AlgorithmBaseParams / AlgorithmParams struct hierarchy - Keep HEAD's ResourcePrototype-based Resource class architecture - Adopt tight-lb's prev_label/ref_count/pending_release label tracking (replacing parent_/child_refcount_) to match staged code - Adopt tight-lb's release_with_ref_count() cascade in LabelPool - Integrate tight-lb's new algorithms: BacktrackingDiveAlgorithm, TabuList, TabuSearch (added files) - Keep HEAD's DiversificationSearch logic, use tight-lb's TabuList member - Fix duplicate fast_check_dominance overload in dominance_function.hpp - Fix stray tolerance field usage in dominance_algorithm.hpp All 46 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uick-improvements
…lve to algorithm - Introduce AlgorithmStatus enum (COMPLETE, TIMEOUT, MAX_SOLUTIONS, MAX_PHASES, INTERRUPTED, MEMORY_LIMIT) and SolveResult struct wrapping solutions + status - Add timeout_s, tolerance, and release_after_solve to AlgorithmBaseParams; release_after_solve=false avoids shrink_to_fit overhead in tight inner loops (e.g. DiversificationSearch) - Add is_time_out() and should_stop(iteration) helpers to Algorithm base class - Update ResourceGraph::solve() to return SolveResult; fix backtracking_dive get_path_arc_ids return type (std::list -> std::vector); rename vrp SolveResult to CGSolveResult to avoid namespace collision - Expose AlgorithmStatus, SolveResult, timeout_s, tolerance, release_after_solve in Python bindings; add sequence protocol to SolveResult for backward compat Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add cmake-build-*/ for CLion build directories - Add *.so / *.dylib for macOS/Linux shared library outputs - Add .venv/, .pytest_cache/, .claude/ (were relying on self-ignoring .gitignore inside those dirs; make project intent explicit) - Remove 306 previously-tracked files from build_asan/ and build_py/ that were committed before the build_*/ ignore rule was in place Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The tabu while-loop checked max_iterations, stop_after_X_solutions and is_interrupted() but not is_time_out(), so params.timeout_s had no effect on the tabu search. Add !is_time_out() to the condition so a wall-clock deadline (e.g. tabu_timeout_s=0.5s) is honoured inside the loop rather than only after main_loop() returns. Without this fix the tabu solver could run indefinitely on pathological graph configurations, blocking worker processes and stalling the parent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements A*-style label-correcting that replaces the FIFO frontier with a min-heap ordered by f = g + h, where h is a per-node admissible lower bound computed via a backward Bellman-Ford pass using arc costs. The heuristic is resource-type-agnostic to avoid template instantiation issues with mixed resource compositions (int+bitset, int+set, etc.). Registers the algorithm as Algorithm.AStar / "astar" in the Python bindings and adds it to both VRP benchmarks and the full test suite. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AStarDominanceAlgorithm now uses the same cost resource as the labeling algorithm (via a new CostResourceType 3rd template param) to compute the backward Bellman-Ford heuristic h(n). This puts g and h on the same scale — both use reduced costs — making f = g + h a meaningful lower bound on the total path cost. Key changes: - BellmanFordAlgorithm: extract the loop into run_relaxations(); add a clean arc-cost-only solve(graph, ids, bool) overload that avoids the CostResourceType template constraint issue across all compositions - AStarDominanceAlgorithm: add CostResourceType as 3rd template param (default RealResource); use if constexpr + is_cost_in_composition_v to call the resource-based Bellman-Ford when the type is present, arc-cost fallback otherwise; catch negative-weight cycles (possible with reduced costs) and fall back to arc.cost - graph_impl.hpp: AStarAlgoBound<CostRC> presents the 3-param algo as a 2-param template; AStarAlgoEntry injects cost_index into params and binds the correct CostRC at dispatch time - algorithm.hpp: add heuristic_cost_index to AlgorithmBaseParams - resource_traits.hpp: add is_cost_in_composition_v trait and the missing resource_type_composition.hpp include Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AStarDominanceAlgorithm now has 3 template params so it no longer satisfies template<typename,typename>; replace with the 2-param wrapper. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tar flag
New ImprovingTabuSearch algorithm (two-phase):
1. GreedyAlgorithm with infinite upper bound finds an initial feasible
solution and its cost
2. TabuSearchAlgorithm uses that cost as the upper bound and improves
Benchmark changes (both benchmark_main and benchmark_large_main):
- Replace the single "Diversif" extra solver with two named heuristics:
ConstructiveTabu = DiversificationSearch (arc-removal diversification)
Tabu = ImprovingTabuSearch (greedy init + tabu improvement)
- AStar is now optional behind --astar (off by default because it is slow);
it runs as an extra solver rather than a main CG algorithm so it does
not penalise the default benchmark run
- Remove AStarAlgoBound from the vrp.solve<> template pack; main CG
algorithms are back to Simple / Pushing / Pulling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rewrites ImprovingTabuSearch as a self-contained BacktrackingDiveAlgorithm
subclass (same base as TabuSearchAlgorithm) rather than a sequenced pair of
separate algorithm objects:
Phase 1 — construction (tabu inactive):
A pure greedy dive finds the initial feasible solution and records its
cost as the starting upper bound for the improvement phase.
Phase 2 — improvement (tabu active):
Repeated tabu-filtered dives constrained to the current best cost.
Classical TS mechanisms:
- Tabu list: arcs of the last found path are forbidden for tabu_tenure
iterations to prevent cycling.
- Aspiration criterion: when all extensions from a node are tabu, the
cheapest tabu extension is used anyway (last-resort fallback).
- Intensification: on a strictly improving solution, shrink_extra() is
called so the search stays near the good region.
- Diversification: after diversification_tenure consecutive non-improving
dives, grow_extra() forces exploration of new regions.
Adds AlgorithmBaseParams::diversification_tenure (default 10) to control
the diversification threshold.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace manual loop conditions with the unified should_stop(i) helper in both TabuSearchAlgorithm and ImprovingTabuSearch, and remove stray blank lines in the latter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> # Conflicts: # src/rcspp/algorithm/tabu_search.hpp
# Conflicts: # src/python_interface/CMakeLists.txt # src/rcspp/algorithm/algorithm.hpp # src/rcspp/algorithm/dominance_algorithm.hpp # src/rcspp/algorithm/solution.hpp # src/rcspp/rcspp.hpp
dive_to_sink() in the tabu searches (and greedy extend) is a DFS with backtracking; on pathological (demand, duals) combos a single dive enumerates exponentially many partial paths, and all per-iteration should_stop() checks sit between dives, so timeout_s/max_iterations never fire — one solve wedged a pricing worker for 15+ minutes. - greedy.hpp, tabu_search.hpp, improving_tabu_search.hpp: poll is_time_out() || is_interrupted() every 4096 dive steps. - pulling_dominance_algorithm.hpp: main_loop now uses should_stop(i) (timeout + interrupt + budgets) like the base DominanceAlgorithm. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each dive extension allocates a label, so a pathological dive is an RSS runaway as well as a time sink: a setB-01 pricing worker grew 4 to 8 GB in 11 s while its max_memory_gb was 2.67 GB, because only the dominance main loops consulted MemoryLimitHelper. The every-4096-steps poll in greedy/tabu/improving-tabu dives now also checks is_exceeded(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR expands the RCSPP/VRP stack with new solver variants (A* dominance, tabu heuristics), adds memory-limit/timeout-aware stopping with explicit solve status reporting, and updates the VRP benchmarking harnesses and Python bindings to expose the new capabilities.
Changes:
- Introduces
SolveResult/AlgorithmStatusand memory/timeout-based early-stop mechanics across algorithms, plus new heuristic algorithms (tabu variants) and an A*-ordered dominance algorithm. - Updates VRP column-generation plumbing (optional Boost build, heterogeneous “extra solvers”, richer
VRP::solve()result) and adds/extends benchmark executables and formatting. - Extends Python bindings/stubs and CI workflows to cover new algorithms and runtime features.
Reviewed changes
Copilot reviewed 56 out of 58 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/rcspp/vrp_subproblem/vrp_subproblem.hpp | Passes base algorithm parameters into test VRP subproblem RCSPP solves and guards empty solution logging. |
| tests/rcspp/test_rcspp.hpp | Adds A* dominance coverage plus new memory-limit behavior tests. |
| tests/rcspp/test_label_buckets.hpp | Adds multi-bucket correctness tests and suggest_range() coverage for LabelBuckets. |
| src/vrp/vrp.hpp | Adds CGSolveResult, optional Boost execution, extra solver support, and a run_algorithm() helper. |
| src/vrp/vrp.cpp | Makes Boost subproblem compilation optional and adjusts path container type. |
| src/vrp/main.cpp | Makes Boost include optional for builds without Boost. |
| src/vrp/CMakeLists.txt | Makes Boost optional, filters Boost-only sources when absent, and adds a large benchmark target. |
| src/vrp/cg/path.hpp | Switches Path::visited_nodes from std::list to std::vector. |
| src/vrp/cg/path.cpp | Updates Path constructor signature to accept std::vector. |
| src/vrp/benchmark_main.cpp | Refactors benchmarking to shared formatting, adds optional Boost/A* flags, and integrates extra solvers. |
| src/vrp/benchmark_large_main.cpp | Adds a large-instance benchmark driver for Solomon C2/R2/RC2 and optional GH instances. |
| src/vrp/benchmark_common.hpp | Adds shared benchmark table formatting and Solomon BKS-based gap reporting. |
| src/rcspp/utils/memory.hpp | Adds cross-platform memory queries and a helper for resolving/enforcing memory limits. |
| src/rcspp/resource/resource_traits.hpp | Adds a trait to detect whether a cost resource is present in a composition. |
| src/rcspp/resource/resource_graph.hpp | Changes solve() to return SolveResult and adds an overload accepting AlgorithmBaseParams. |
| src/rcspp/resource/concrete/numerical_resource.hpp | Adds delta-aware comparisons and simplifies self-type references. |
| src/rcspp/rcspp.hpp | Exposes new algorithms and memory utilities via the umbrella include. |
| src/rcspp/preprocessor/connectivity_matrix.hpp | Extends SCC adjacency construction to include in-arc origins. |
| src/rcspp/preprocessor/bellman_ford_algorithm.hpp | Refactors Bellman–Ford into reusable relaxation logic and overloads for arc-cost vs resource-cost. |
| src/rcspp/label/label.hpp | Adds predecessor pointer + ref-count based pinning for path reconstruction. |
| src/rcspp/label/label_pool.hpp | Implements ref-count-aware release cascading and adds full pool release() reclamation. |
| src/rcspp/label/label_factory.hpp | Resets new predecessor/ref-count fields on label reset. |
| src/rcspp/graph/graph.hpp | Adds a mutable for_each_arc overload. |
| src/rcspp/algorithm/tabu_search.hpp | Adds a constructive tabu-search algorithm based on backtracking dives. |
| src/rcspp/algorithm/tabu_list.hpp | Adds reusable tabu tenure bookkeeping shared by tabu-style algorithms. |
| src/rcspp/algorithm/simple_dominance_algorithm.hpp | Adds memory-pressure trimming behavior and uses an effective per-node cap. |
| src/rcspp/algorithm/pushing_dominance_algorithm.hpp | Adds memory-pressure trimming and uses effective per-node caps; includes missing <list>. |
| src/rcspp/algorithm/pulling_dominance_algorithm.hpp | Adds stop-condition coverage and periodic memory checks + trimming. |
| src/rcspp/algorithm/label_buckets.hpp | Refactors LabelBuckets to vector-backed buckets with O(log B) search, O(1) erase bookkeeping, and instrumentation. |
| src/rcspp/algorithm/improving_tabu_search.hpp | Adds a two-phase improving tabu search heuristic with diversification control. |
| src/rcspp/algorithm/greedy.hpp | Uses unified stop checks and adds periodic timeout/interrupt/memory polling in deep backtracking. |
| src/rcspp/algorithm/dominance_algorithm.hpp | Adds memory checks, ref-count-aware label release, and O(hops) path reconstruction via predecessor pointers. |
| src/rcspp/algorithm/diversification_search.hpp | Replaces bespoke tabu bookkeeping with TabuList and adapts to SolveResult. |
| src/rcspp/algorithm/backtracking_dive_algorithm.hpp | Adds shared DFS/backtracking machinery for constructive heuristics. |
| src/rcspp/algorithm/astar_dominance_algorithm.hpp | Adds A*-ordered dominance algorithm with Bellman–Ford heuristic and memory-pressure trimming. |
| src/rcspp/algorithm/algorithm.hpp | Introduces SolveResult/AlgorithmStatus, timeout/memory-limit parameters, and unified stop logic with optional pool release. |
| src/python/test_vrp.py | Makes Python tests import the interface via stable paths relative to the test file. |
| src/python/test_rcspp.py | Adds A* usage examples and bucket params position-based API tests; stabilizes import paths. |
| src/python/test_rcspp_networkx.py | Stabilizes import paths for networkx integration tests. |
| src/python/test_graph.py | Makes numpy optional via pytest.importorskip and stabilizes import paths. |
| src/python/test_clone.py | Makes numpy optional via pytest.importorskip, renames dual-rows wording to rows, and stabilizes import paths. |
| src/python_interface/rcspp/solution_pool.cpp | Clarifies control flow in pruning predicate with explicit braces. |
| src/python_interface/rcspp/rcspp.cpp | Exposes process/available memory byte helpers in the Python extension module. |
| src/python_interface/rcspp/py.typed | Marks the Python package as typed. |
| src/python_interface/rcspp/graph.py | Adds algorithm aliases, returns SolveResult, and introduces a Python BucketAlgorithmParams wrapper with pos-based resource selection. |
| src/python_interface/rcspp/graph.cpp | Exposes new enums (AlgorithmStatus) and SolveResult, and binds new algorithm params fields. |
| src/python_interface/rcspp/graph_impl.hpp | Updates dispatch to return SolveResult, adds Tabu/A* dispatch entries, and optimizes bulk row insertion. |
| src/python_interface/rcspp/_core/resource.pyi | Adds typing stubs for resource-related extension/feasibility/cost/dominance helpers. |
| src/python_interface/rcspp/_core/logger.pyi | Adds typing stubs for logger API. |
| src/python_interface/rcspp/_core/graph.pyi | Adds typing stubs for graph API including SolveResult and algorithm parameters. |
| src/python_interface/rcspp/_core/init.pyi | Adds typing stub package exports for _core. |
| src/python_interface/rcspp/init.py | Re-exports AlgorithmStatus, SolveResult, and memory helper functions from the extension. |
| src/python_interface/CMakeLists.txt | Installs .pyi and py.typed files and ensures they are copied during builds. |
| instances/RC201_12.txt | Adds a Git LFS pointer for a new instance artifact. |
| .pre-commit-config.yaml | Excludes build directories from markdownlint hook. |
| .gitignore | Expands ignore rules for build artifacts and Python caches/venvs. |
| .github/workflows/ci.yml | Expands test matrix to Python 3.11–3.13 and tweaks pytest output. |
| .github/workflows/benchmark.yml | Adds a manually-triggered benchmark workflow (small + optional large benchmark). |
Suppressed comments (4)
src/vrp/vrp.hpp:146
- Same issue here: prefer
std::absfor double differences to avoid relying on unqualified overload resolution.
src/rcspp/algorithm/astar_dominance_algorithm.hpp:186 - When trimming under memory pressure, labels are released via
release_labelbut may still be referenced as predecessors. Userelease_with_ref_countconsistently for any label allocated in DominanceAlgorithm-derived runs.
if (this->memory_pressure_triggered_) {
for (auto& [label_ptr, label_iter] : unprocessed_truncated_labels_) {
this->remove_label(label_iter);
this->label_pool_.release_label(label_ptr);
}
src/rcspp/algorithm/astar_dominance_algorithm.hpp:220
- Dominated excess labels are recycled with
release_label, which ignores the new predecessor pinning mechanism. Userelease_with_ref_counthere as well.
for (size_t i = max_total; i < flat.size(); ++i) {
auto& p = flat[i];
if (p.first->dominated) {
this->label_pool_.release_label(p.first);
} else {
src/vrp/vrp.hpp:113
- Unqualified
abs(diff)on adoublecan resolve to the integer overload depending on headers/toolchain. Preferstd::abs(and include<cmath>).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+6
to
9
| #include <functional> | ||
| #include <limits> | ||
| #include <optional> | ||
|
|
Comment on lines
+134
to
+136
| if (label_iterator_pair.first->dominated) { | ||
| this->label_pool_.release_label(label_iterator_pair.first); | ||
| } else { |
Comment on lines
+85
to
+88
| Label<ResourceType>* prev_label = nullptr; | ||
| // Number of alive successors that reference this label as their predecessor. | ||
| uint8_t ref_count = 0; | ||
| // True when the algorithm wanted to release this label but ref_count was > 0. |
Comment on lines
+6
to
+12
| #include <cmath> | ||
| #include <iomanip> | ||
| #include <sstream> | ||
| #include <string> | ||
| #include <tuple> | ||
| #include <unordered_map> | ||
| #include <vector> |
Comment on lines
+8
to
+14
| class Algorithm(Enum): | ||
| Simple: Algorithm | ||
| Pushing: Algorithm | ||
| Pulling: Algorithm | ||
| Greedy: Algorithm | ||
| Tabu: Algorithm | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.