Skip to content

Expose diving hyper parameters#1364

Merged
rapids-bot[bot] merged 5 commits into
NVIDIA:mainfrom
nguidotti:hyper-param-diving
Jun 9, 2026
Merged

Expose diving hyper parameters#1364
rapids-bot[bot] merged 5 commits into
NVIDIA:mainfrom
nguidotti:hyper-param-diving

Conversation

@nguidotti

Copy link
Copy Markdown
Contributor

Similar to #993, this PR exposes the diving hyper parameters to cuopt_cli and to the public API in order to be easier to tune. They are hidden by default in cuopt_cli.

Checklist

  • I am familiar with the Contributing Guidelines.
  • Testing
    • New or existing tests cover these changes
    • Added tests
    • Created an issue to follow-up
    • NA
  • Documentation
    • The documentation is up to date with these changes
    • Added new documentation
    • NA

…udo_costs, worker and diving_heuristics.

Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
@nguidotti nguidotti self-assigned this Jun 2, 2026
@nguidotti
nguidotti requested a review from a team as a code owner June 2, 2026 10:41
@nguidotti
nguidotti requested review from Bubullzz and akifcorduk June 2, 2026 10:41
@nguidotti nguidotti added non-breaking Introduces a non-breaking change improvement Improves an existing functionality mip P2 labels Jun 2, 2026
@nguidotti nguidotti added this to the 26.08 milestone Jun 2, 2026
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR centralizes MIP diving hyperparameters into a templated mip_diving_hyper_params_t, exposes them via solver settings, switches diving-type logging to a runtime show_type flag, updates strategy enablement and worker allocation to use the new type, and adds debug logs in diving heuristics.

Changes

Diving Heuristic Parameters

Layer / File(s) Summary
Diving parameter contract definition
cpp/include/cuopt/linear_programming/constants.h, cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp
New templated mip_diving_hyper_params_t<i_t,f_t> with flags for line-search/pseudocost/guided/coefficient diving, min_node_depth, node_limit, backtrack_limit (i_t), iteration_limit_factor (f_t), and show_type logging flag. String macros added for parameter keys.
Public settings integration & heuristics template
cpp/include/cuopt/linear_programming/mip/heuristics_hyper_params.hpp, cpp/include/cuopt/linear_programming/mip/solver_settings.hpp, cpp/tests/mip/heuristics_hyper_params_test.cu
mip_heuristics_hyper_params_t converted to template <i_t,f_t>; mip_solver_settings_t exposes mip_diving_hyper_params_t<i_t,f_t> diving_params; tests updated to instantiate templated type.
Simplex diving settings replacement
cpp/src/dual_simplex/simplex_solver_settings.hpp
Removed in-header diving_heuristics_settings_t and changed simplex_solver_settings_t::diving_settings to mip_diving_hyper_params_t<i_t,f_t>.
Diving heuristics utilities
cpp/src/branch_and_bound/diving_heuristics.hpp
Added feasible_solution_symbol(search_strategy_t, bool log_diving_type) mapping symbols (collapsed or per-strategy) and is_search_strategy_enabled(search_strategy_t, const mip_diving_hyper_params_t<i_t,f_t>&) that enables strategies by non-zero numeric fields (BEST_FIRST always enabled).
Worker and pseudo-costs refactor
cpp/src/branch_and_bound/pseudo_costs.hpp, cpp/src/branch_and_bound/worker.hpp
Removed include from pseudo_costs.hpp and added forward declarations; worker.hpp now includes diving heuristics utilities, removed header-local enable helper, and updated bfs_worker_t::calculate_num_diving_workers to accept const mip_diving_hyper_params_t& and use is_search_strategy_enabled().
Branch-and-bound logging and search integration
cpp/src/branch_and_bound/branch_and_bound.cpp
Replaced compile-time symbol mapping with runtime show_type flag; add_feasible_solution() threads show_type into debug logging and reporting; best_first_search_with() copies diving settings, disables/re-enables guided diving based on incumbent and recalculates worker counts.
Configuration registration and wiring
cpp/src/math_optimization/solver_settings.cu, cpp/src/mip_heuristics/solver.cu
Registered new float and numeric diving hyperparameters (including iteration_limit_factor, per-strategy toggles, min_node_depth, node_limit, backtrack_limit) and bool show_type in solver param catalog; mip_solver_t::run_solver() wires context.settings.diving_params into branch_and_bound_settings.diving_settings.
Diving heuristics debug instrumentation
cpp/src/branch_and_bound/diving_heuristics.cpp
Added log.debug() messages in pseudocost_diving and guided_diving reporting selected branch variable, its value, rounding direction, and computed score.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Expose diving hyper parameters' directly matches the main objective of the PR: exposing diving hyperparameters to the public API and cuopt_cli.
Description check ✅ Passed The description clearly explains the PR's purpose: exposing diving hyperparameters to cuopt_cli and public API for easier tuning, following a similar approach to #993.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp (1)

8-8: ⚡ Quick win

Use a macro guard here instead of only #pragma once.

The new C++ header does not follow the repository header-guard convention. Please add a normal #define guard and keep #pragma once only if you want it as a secondary optimization.

As per coding guidelines, "Use #define guards on C++ headers".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp` at line 8,
The header currently only has `#pragma once`; add a standard include guard macro
around the file to follow project convention: introduce a unique macro like
CPP_INCLUDE_CUOPT_LINEAR_PROGRAMMING_MIP_DIVING_HYPER_PARAMS_HPP (or similar
uppercase, path-based name) with `#ifndef ... `#define` ...` at the top and a
matching `#endif` at the bottom of diving_hyper_params.hpp, keeping `#pragma
once` if you want it as a secondary optimization; ensure the macro name is
unique and consistent with other headers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/src/branch_and_bound/branch_and_bound.cpp`:
- Around line 1758-1760: The code unconditionally sets
diving_settings.guided_diving = 1 before calling
worker->calculate_num_diving_workers(...), overwriting the caller's intended
mode; change this to preserve and reuse the original mode by assigning
diving_settings.guided_diving = settings_.diving_settings.guided_diving (so
guided_diving keeps -1 for automatic or 1 for enabled) before invoking
worker->calculate_num_diving_workers.

In `@cpp/src/branch_and_bound/diving_heuristics.hpp`:
- Around line 42-43: The declaration of is_search_strategy_enabled in
diving_heuristics.hpp uses the type mip_diving_hyper_params_t but the header
doesn't directly include the header that defines that type; make the header
self-contained by adding an `#include` for the header that introduces
mip_diving_hyper_params_t (the file that defines the mip_diving_hyper_params_t
type) to diving_heuristics.hpp so the declaration compiles without relying on
transitive includes.

In `@cpp/src/math_optimization/solver_settings.cu`:
- Around line 118-119: The registration passes
&mip_settings.diving_params.iteration_limit_factor (declared as double in
diving_hyper_params.hpp) into a parameter_info_t<f_t> (used by
solver_settings_t<int, float>), causing a double* vs float* mismatch; fix by
changing the type of iteration_limit_factor in diving_hyper_params.hpp to f_t so
it matches parameter_info_t<f_t>, or alternatively add a specialized
registration path that accepts a double-typed parameter (i.e., a
parameter_info_t<double> entry) for
CUOPT_MIP_HYPER_DIVING_ITERATION_LIMIT_FACTOR and ensure solver_settings
registration logic handles that specialization.

---

Nitpick comments:
In `@cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp`:
- Line 8: The header currently only has `#pragma once`; add a standard include
guard macro around the file to follow project convention: introduce a unique
macro like CPP_INCLUDE_CUOPT_LINEAR_PROGRAMMING_MIP_DIVING_HYPER_PARAMS_HPP (or
similar uppercase, path-based name) with `#ifndef ... `#define` ...` at the top
and a matching `#endif` at the bottom of diving_hyper_params.hpp, keeping
`#pragma once` if you want it as a secondary optimization; ensure the macro name
is unique and consistent with other headers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 877a2203-2924-4ddf-bcb2-d88a2e40efd0

📥 Commits

Reviewing files that changed from the base of the PR and between fa67d5e and fc1ab19.

📒 Files selected for processing (11)
  • cpp/include/cuopt/linear_programming/constants.h
  • cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp
  • cpp/include/cuopt/linear_programming/mip/solver_settings.hpp
  • cpp/src/branch_and_bound/branch_and_bound.cpp
  • cpp/src/branch_and_bound/diving_heuristics.cpp
  • cpp/src/branch_and_bound/diving_heuristics.hpp
  • cpp/src/branch_and_bound/pseudo_costs.hpp
  • cpp/src/branch_and_bound/worker.hpp
  • cpp/src/dual_simplex/simplex_solver_settings.hpp
  • cpp/src/math_optimization/solver_settings.cu
  • cpp/src/mip_heuristics/solver.cu

Comment thread cpp/src/branch_and_bound/branch_and_bound.cpp
Comment thread cpp/src/branch_and_bound/diving_heuristics.hpp Outdated
Comment thread cpp/src/math_optimization/solver_settings.cu

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
cpp/src/branch_and_bound/branch_and_bound.cpp (1)

1755-1761: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Preserve the original guided-diving mode when re-enabling.

Line 1758 hardcodes diving_settings.guided_diving = 1, but the original setting might have been -1 (automatic) rather than 1 (enabled). Restoring the original value from settings_.diving_settings.guided_diving preserves the caller's intended mode.

Suggested fix
-        diving_settings.guided_diving = 1;
+        diving_settings.guided_diving = settings_.diving_settings.guided_diving;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/branch_and_bound/branch_and_bound.cpp` around lines 1755 - 1761, The
code currently forces diving_settings.guided_diving = 1 when re-enabling guided
diving; instead restore the original mode from
settings_.diving_settings.guided_diving so automatic (-1) vs enabled (1) is
preserved. Update the block that checks diving_worker_pool_.size() and
settings_.diving_settings.guided_diving to assign diving_settings.guided_diving
= settings_.diving_settings.guided_diving (not literal 1) before calling
worker->calculate_num_diving_workers(bfs_worker_pool_.size(),
diving_worker_pool_.size(), diving_settings), keeping the
has_solver_space_incumbent() check unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@cpp/src/branch_and_bound/branch_and_bound.cpp`:
- Around line 1755-1761: The code currently forces diving_settings.guided_diving
= 1 when re-enabling guided diving; instead restore the original mode from
settings_.diving_settings.guided_diving so automatic (-1) vs enabled (1) is
preserved. Update the block that checks diving_worker_pool_.size() and
settings_.diving_settings.guided_diving to assign diving_settings.guided_diving
= settings_.diving_settings.guided_diving (not literal 1) before calling
worker->calculate_num_diving_workers(bfs_worker_pool_.size(),
diving_worker_pool_.size(), diving_settings), keeping the
has_solver_space_incumbent() check unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 69c1430e-729e-4b5e-ab18-aa8abd5151ec

📥 Commits

Reviewing files that changed from the base of the PR and between fc1ab19 and c385de1.

📒 Files selected for processing (10)
  • cpp/include/cuopt/linear_programming/constants.h
  • cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp
  • cpp/include/cuopt/linear_programming/mip/heuristics_hyper_params.hpp
  • cpp/include/cuopt/linear_programming/mip/solver_settings.hpp
  • cpp/src/branch_and_bound/branch_and_bound.cpp
  • cpp/src/branch_and_bound/diving_heuristics.hpp
  • cpp/src/branch_and_bound/worker.hpp
  • cpp/src/dual_simplex/simplex_solver_settings.hpp
  • cpp/src/math_optimization/solver_settings.cu
  • cpp/tests/mip/heuristics_hyper_params_test.cu
✅ Files skipped from review due to trivial changes (1)
  • cpp/src/math_optimization/solver_settings.cu
🚧 Files skipped from review as they are similar to previous changes (5)
  • cpp/src/branch_and_bound/diving_heuristics.hpp
  • cpp/include/cuopt/linear_programming/mip/solver_settings.hpp
  • cpp/include/cuopt/linear_programming/constants.h
  • cpp/src/dual_simplex/simplex_solver_settings.hpp
  • cpp/src/branch_and_bound/worker.hpp

Comment thread cpp/src/branch_and_bound/branch_and_bound.cpp
Comment thread cpp/src/branch_and_bound/diving_heuristics.hpp Outdated
Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp (2)

22-26: ⚡ Quick win

Add per-member documentation for heuristic enable flags.

The tri-state semantics (-1 automatic, 0 disabled, 1 enabled) are documented only in a single-line comment. For a public API, consider adding inline documentation for each flag explaining what "automatic" mode does for that specific heuristic.

📝 Example documentation pattern
-  // -1 automatic, 0 disabled, 1 enabled
-  i_t line_search_diving = -1;
+  /// Enable line-search diving heuristic: -1 (automatic, enabled based on problem characteristics), 0 (disabled), 1 (enabled).
+  i_t line_search_diving = -1;

As per coding guidelines, public C++ headers should document algorithm parameters clearly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp` around
lines 22 - 26, Add inline Doxygen-style comments for each public member
(line_search_diving, pseudocost_diving, guided_diving, coefficient_diving) that
state the tri-state semantics (-1 = automatic, 0 = disabled, 1 = enabled) and
briefly explain what "automatic" chooses for that specific heuristic (e.g.,
select based on problem size/LP relaxation info, use historical pseudocosts,
enable guided branching when strong inference exists, or pick coefficient-based
rules respectively). Place these short comments immediately above each member
declaration in diving_hyper_params.hpp so the public API documents behavior
per-flag.

12-21: ⚡ Quick win

Document template parameters.

The template parameters i_t and f_t are not documented. Consider adding @tparam tags to clarify expected types and constraints (e.g., i_t must be a signed integer type to support the -1 automatic mode).

📝 Suggested documentation enhancement
 /**
  * `@brief` Tuning knobs for the dual-simplex diving heuristics used in MIP B&B.
  *
+ * `@tparam` i_t  Signed integer type for counts, limits, and tri-state flags.
+ * `@tparam` f_t  Floating-point type for scaling factors.
+ *
  * Used directly as simplex_solver_settings_t::diving_settings and copied into

As per coding guidelines, public C++ headers should document parameters and types for API clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp` around
lines 12 - 21, Add Doxygen `@tparam` documentation for the template parameters on
the mip_diving_hyper_params_t template: document i_t as the integer index/size
type (must be a signed integer type because -1 is used for "automatic" mode) and
document f_t as the floating-point type used for numeric thresholds/weights
(e.g., double/float). Place the `@tparam` entries in the existing comment block
immediately above the template<typename i_t, typename f_t> struct
mip_diving_hyper_params_t so the API docs clearly state the expected types and
any constraints.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp`:
- Around line 22-26: Add inline Doxygen-style comments for each public member
(line_search_diving, pseudocost_diving, guided_diving, coefficient_diving) that
state the tri-state semantics (-1 = automatic, 0 = disabled, 1 = enabled) and
briefly explain what "automatic" chooses for that specific heuristic (e.g.,
select based on problem size/LP relaxation info, use historical pseudocosts,
enable guided branching when strong inference exists, or pick coefficient-based
rules respectively). Place these short comments immediately above each member
declaration in diving_hyper_params.hpp so the public API documents behavior
per-flag.
- Around line 12-21: Add Doxygen `@tparam` documentation for the template
parameters on the mip_diving_hyper_params_t template: document i_t as the
integer index/size type (must be a signed integer type because -1 is used for
"automatic" mode) and document f_t as the floating-point type used for numeric
thresholds/weights (e.g., double/float). Place the `@tparam` entries in the
existing comment block immediately above the template<typename i_t, typename
f_t> struct mip_diving_hyper_params_t so the API docs clearly state the expected
types and any constraints.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c64e4a8f-3405-47c1-a6e9-11eff3ac628b

📥 Commits

Reviewing files that changed from the base of the PR and between c385de1 and 1da6200.

📒 Files selected for processing (2)
  • cpp/include/cuopt/linear_programming/mip/diving_hyper_params.hpp
  • cpp/src/branch_and_bound/diving_heuristics.hpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • cpp/src/branch_and_bound/diving_heuristics.hpp

@nguidotti
nguidotti requested review from aliceb-nv and removed request for Bubullzz June 8, 2026 08:36
@nguidotti

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 8e3cfe7 into NVIDIA:main Jun 9, 2026
158 of 160 checks passed
@nguidotti
nguidotti deleted the hyper-param-diving branch June 9, 2026 11:48
rapids-bot Bot pushed a commit that referenced this pull request Jun 12, 2026
Implemented Farkas [1] and vector length [Section 9.2.6, 2] diving heuristics.  It includes #1364.

Farkas diving is designed to move the current LP relaxation in direction to a valid Farkas proof. It pushes all variables towards the so-called pseudo solution, in which each variable assumes the best bound with respect to its objective coefficient as the solution value. Generally, this is very optimistic and most of the time, it will violate the constraints of the problem. Yet, if this finds a feasible solution, then it is expected to be very good.

Vector length diving is tailored for set partitioning and set covering. It chooses a rounding that coverst the largest number of constraints with the smallest objective value deterioration.

## Benchmark Results
MIPLIB2017, 10min, GH200

### All

```
================================================================================
 main-2026-06-01 (1) vs new-diving-heuristics (2)
================================================================================

------------------------------------------------------------------------------------------------------------------------------
|                                        |       Run 1        |       Run 2        |     Abs. Diff.     |   Rel. Diff. (%)   |
------------------------------------------------------------------------------------------------------------------------------
| Imported                                                 240                  240                   +0                 --- |
| Feasible                                                 226                  227                   +1                 --- |
| Optimal                                                   83                   84                   +1                 --- |
| Solutions with <0.1% primal gap                          134                  139                   +5                 --- |
| Nodes explored (mean)                              1.329e+07            1.295e+07           -3.335e+05               -2.51 |
| Nodes explored (shifted geomean)                   1.426e+04            1.372e+04               -539.2               -3.78 |
| Relative MIP gap (mean)                               0.2893               0.2854            -0.003857               -1.33 |
| Relative MIP gap (shifted geomean)                   0.09705              0.09449            -0.002568               -2.65 |
| Solve time (mean)                                      426.6                428.7               +2.022              +0.474 |
| Solve time (shifted geomean)                           202.4                207.1               +4.726               +2.33 |
| Primal gap (mean)                                      11.31                10.89              -0.4276               -3.78 |
| Primal gap (shifted geomean)                          0.5319               0.4957             -0.03619                -6.8 |
| Primal integral (mean)                                 32.45                31.21               -1.242               -3.83 |
| Primal integral (shifted geomean)                      6.582                6.147              -0.4357               -6.62 |
------------------------------------------------------------------------------------------------------------------------------
```

### Vector length diving

```
================================================================================
 main-2026-06-01 (1) vs vector-length-diving (2)
================================================================================

------------------------------------------------------------------------------------------------------------------------------
|                                        |       Run 1        |       Run 2        |     Abs. Diff.     |   Rel. Diff. (%)   |
------------------------------------------------------------------------------------------------------------------------------
| Imported                                                 240                  240                   +0                 --- |
| Feasible                                                 226                  228                   +2                 --- |
| Optimal                                                   83                   84                   +1                 --- |
| Solutions with <0.1% primal gap                          134                  136                   +2                 --- |
| Nodes explored (mean)                              1.329e+07            1.285e+07           -4.331e+05               -3.26 |
| Nodes explored (shifted geomean)                   1.426e+04            1.312e+04                -1134               -7.95 |
| Relative MIP gap (mean)                               0.2893               0.3086             +0.01929               +6.67 |
| Relative MIP gap (shifted geomean)                   0.09705              0.09751            +0.000458              +0.472 |
| Solve time (mean)                                      426.6                421.3               -5.318               -1.25 |
| Solve time (shifted geomean)                           202.4                195.7                -6.75               -3.33 |
| Primal gap (mean)                                      11.31                10.47              -0.8411               -7.43 |
| Primal gap (shifted geomean)                          0.5319               0.5132             -0.01875               -3.53 |
| Primal integral (mean)                                 32.45                33.07              +0.6235               +1.92 |
| Primal integral (shifted geomean)                      6.582                 6.62             +0.03761              +0.571 |
------------------------------------------------------------------------------------------------------------------------------
```

### Farkas diving

```
================================================================================
 main-2026-06-01 (1) vs farkas-diving (2)
================================================================================

------------------------------------------------------------------------------------------------------------------------------
|                                        |       Run 1        |       Run 2        |     Abs. Diff.     |   Rel. Diff. (%)   |
------------------------------------------------------------------------------------------------------------------------------
| Imported                                                 240                  240                   +0                 --- |
| Feasible                                                 226                  228                   +2                 --- |
| Optimal                                                   83                   84                   +1                 --- |
| Solutions with <0.1% primal gap                          134                  132                   -2                 --- |
| Nodes explored (mean)                              1.329e+07            1.322e+07            -6.36e+04              -0.479 |
| Nodes explored (shifted geomean)                   1.426e+04            1.436e+04               +107.1              +0.751 |
| Relative MIP gap (mean)                               0.2893                0.291            +0.001754              +0.606 |
| Relative MIP gap (shifted geomean)                   0.09705              0.09512            -0.001935               -1.99 |
| Solve time (mean)                                      426.6                429.4               +2.721              +0.638 |
| Solve time (shifted geomean)                           202.4                205.5                 +3.1               +1.53 |
| Primal gap (mean)                                      11.31                10.46              -0.8573               -7.58 |
| Primal gap (shifted geomean)                          0.5319               0.5099             -0.02204               -4.14 |
| Primal integral (mean)                                 32.45                33.11              +0.6652               +2.05 |
| Primal integral (shifted geomean)                      6.582                6.342              -0.2408               -3.66 |
------------------------------------------------------------------------------------------------------------------------------
```

## References

[1] J. Witzig and A. Gleixner, “Conflict-Driven Heuristics for Mixed Integer Programming,” Feb. 07, 2019, arXiv: arXiv:1902.02615. doi: [10.48550/arXiv.1902.02615](https://doi.org/10.48550/arXiv.1902.02615).

[2] T. Achterberg, “Constraint Integer Programming,” PhD, Technischen Universität Berlin, Berlin, 2007. doi: [10.14279/depositonce-1634](https://doi.org/10.14279/depositonce-1634).

Authors:
  - Nicolas L. Guidotti (https://github.com/nguidotti)

Approvers:
  - Akif ÇÖRDÜK (https://github.com/akifcorduk)
  - Chris Maes (https://github.com/chris-maes)

URL: #1401
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality mip non-breaking Introduces a non-breaking change P2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants