BendersCut class
#include <gtopt/benders_cut.hpp>
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
AdaptiveWorkPoolused 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().