From b94b2e35036f1512153d5a97653d10e83326a6fe Mon Sep 17 00:00:00 2001 From: edolix Date: Wed, 21 Oct 2026 10:58:18 +0200 Subject: [PATCH 1/3] expose best_objective_bound --- ext/or-tools/constraint.cpp | 1 + lib/or_tools/cp_solver.rb | 2 +- lib/or_tools/cp_solver_solution_callback.rb | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/or-tools/constraint.cpp b/ext/or-tools/constraint.cpp index 74ae9f6..5d7bc2c 100644 --- a/ext/or-tools/constraint.cpp +++ b/ext/or-tools/constraint.cpp @@ -927,6 +927,7 @@ void init_constraint(Rice::Module& m) { Rice::define_class_under(m, "CpSolverResponse") .define_method("objective_value", &CpSolverResponse::objective_value) + .define_method("best_objective_bound", &CpSolverResponse::best_objective_bound) .define_method("num_conflicts", &CpSolverResponse::num_conflicts) .define_method("num_branches", &CpSolverResponse::num_branches) .define_method("wall_time", &CpSolverResponse::wall_time) diff --git a/lib/or_tools/cp_solver.rb b/lib/or_tools/cp_solver.rb index 99d482a..8e710e3 100644 --- a/lib/or_tools/cp_solver.rb +++ b/lib/or_tools/cp_solver.rb @@ -4,7 +4,7 @@ module ORTools class CpSolver extend Forwardable - def_delegators :@response, :objective_value, :num_conflicts, :num_branches, :wall_time + def_delegators :@response, :objective_value, :best_objective_bound, :num_conflicts, :num_branches, :wall_time def solve(model, observer = nil) @response = _solve(model, parameters, observer) diff --git a/lib/or_tools/cp_solver_solution_callback.rb b/lib/or_tools/cp_solver_solution_callback.rb index bf2b742..91721ed 100644 --- a/lib/or_tools/cp_solver_solution_callback.rb +++ b/lib/or_tools/cp_solver_solution_callback.rb @@ -17,6 +17,10 @@ def objective_value @response&.objective_value end + def best_objective_bound + @response&.best_objective_bound + end + def stop_search @stopped = true end From 9fbf24ec4d8130ee27d04941899e90d2152985b7 Mon Sep 17 00:00:00 2001 From: edolix Date: Wed, 21 Oct 2026 10:58:30 +0200 Subject: [PATCH 2/3] add tests --- test/constraint_test.rb | 1 + test/solution_printer_test.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/test/constraint_test.rb b/test/constraint_test.rb index fdad09d..b73c325 100644 --- a/test/constraint_test.rb +++ b/test/constraint_test.rb @@ -141,6 +141,7 @@ def test_optimization y = 3 z = 5 EOS + assert_equal 35, solver.best_objective_bound end # https://developers.google.com/optimization/cp/cryptarithmetic diff --git a/test/solution_printer_test.rb b/test/solution_printer_test.rb index e3129c0..9fb6cb3 100644 --- a/test/solution_printer_test.rb +++ b/test/solution_printer_test.rb @@ -11,6 +11,7 @@ def test_objective_solution_printer solver.parameters.enumerate_all_solutions = true solution_printer = ORTools::ObjectiveSolutionPrinter.new assert_nil solution_printer.objective_value + assert_nil solution_printer.best_objective_bound stdout, _ = capture_io do solver.solve(model, solution_printer) From fb8ef468a005ac717ac31a509f4a0e70788b1709 Mon Sep 17 00:00:00 2001 From: edolix Date: Wed, 21 Oct 2026 10:58:39 +0200 Subject: [PATCH 3/3] changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ec7b30..b6e79be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.18.2 (unreleased) + +- Added `best_objective_bound` method to `CpSolver` and `CpSolverSolutionCallback` + ## 0.18.1 (2026-10-02) - Added support for breaks for routing