gtopt::BendersCut class

Class-based interface for Benders cut construction with work-pool support and infeasibility monitoring.

Wraps the free functions declared above as member functions and adds:

  • An optional AdaptiveWorkPool used for LP solve/resolve operations. When a pool is provided, the elastic-filter clone LP solve is submitted to the pool (rather than run synchronously on the calling thread). This allows the solver's work pool to track and schedule elastic-filter solves alongside other LP subproblems.
  • An infeasible-cut counter: every successful elastic-filter solve (i.e. every LP infeasibility event handled by the filter) increments the counter. The counter can be reset per-iteration and queried for monitoring-API integration (e.g. logged to the SDDP JSON status file).

Usage

// In SDDPMethod::solve():
auto pool = make_solver_work_pool();
m_benders_cut_.set_pool(pool.get());

// In elastic_solve():
auto result = m_benders_cut_.elastic_filter_solve(li, links, penalty, opts);

// After each iteration:
ir.infeasible_cuts_added = m_benders_cut_.infeasible_cut_count();
m_benders_cut_.reset_infeasible_cut_count();

Constructors, destructors, conversion operators

BendersCut(AdaptiveWorkPool* pool = nullptr) explicit noexcept
BendersCut(BendersCut&&) deleted
BendersCut(const BendersCut&) deleted
~BendersCut() defaulted

Public functions

auto build_feasibility_cut(const LinearInterface& li, ColIndex alpha_col, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::string_view name, double scale_alpha = 1.0) -> std::optional< FeasibilityCutResult > -> auto
auto elastic_filter_solve(const LinearInterface& li, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::span<const double> forward_col_sol = {}, std::span<const double> forward_row_dual = {}) -> std::optional< ElasticSolveResult > -> auto
auto infeasible_cut_count() const -> int noexcept
auto operator=(BendersCut&&) -> BendersCut& deleted
auto operator=(const BendersCut&) -> BendersCut& deleted
auto pool() const -> AdaptiveWorkPool* noexcept
Access the current work pool (may be nullptr).
auto reset_infeasible_cut_count() -> void noexcept
auto set_pool(AdaptiveWorkPool* pool) -> void noexcept

Function documentation

gtopt::BendersCut::BendersCut(AdaptiveWorkPool* pool = nullptr) explicit noexcept

Construct with an optional work pool for LP solve/resolve operations. If pool is nullptr, LP solves are performed synchronously on the calling thread (same behaviour as the standalone free functions).

auto gtopt::BendersCut::build_feasibility_cut(const LinearInterface& li, ColIndex alpha_col, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::string_view name, double scale_alpha = 1.0) -> std::optional< FeasibilityCutResult >

Returns A feasibility cut and the ElasticSolveResult, or nullopt if the elastic solve fails.

Build a Benders feasibility cut using this object's elastic_filter_solve. Equivalent to the free function build_feasibility_cut() but uses the work pool (if set) for the internal LP solve.

auto gtopt::BendersCut::elastic_filter_solve(const LinearInterface& li, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::span<const double> forward_col_sol = {}, std::span<const double> forward_row_dual = {}) -> std::optional< ElasticSolveResult >

Returns Solved elastic clone and per-link slack info, or nullopt if no columns were fixed or the clone solve failed.

Clone li, apply elastic relaxation on fixed state-variable columns, and solve the clone. When a work pool is set, the LP solve is submitted to the pool (allowing the pool's scheduling and monitoring to observe it); otherwise the solve is performed synchronously.

Increments the infeasible-cut counter on each successful solve.

int gtopt::BendersCut::infeasible_cut_count() const noexcept

Number of successful elastic-filter solves since construction (or last reset). Each such solve corresponds to an LP infeasibility event; in the backward pass these become feasibility cuts.

void gtopt::BendersCut::reset_infeasible_cut_count() noexcept

Reset the infeasible-cut counter (typically called at the start of each SDDP iteration to obtain per-iteration counts).

void gtopt::BendersCut::set_pool(AdaptiveWorkPool* pool) noexcept

Update the work pool used for LP solves. Must be called from a single thread (e.g. before starting the parallel solve loop). Not safe to call concurrently with elastic_filter_solve().