gtopt::SDDPOptions struct

Configuration options for the SDDP iterative solver.

Public variables

double alpha_max
Upper bound for future cost variable a ($)
double alpha_min
Lower bound for future cost variable a ($)
double aperture_timeout
std::optional<std::vector<Uid>> apertures
std::string api_status_file
std::string api_stop_request_file
std::chrono::milliseconds api_update_interval
std::optional<SolverOptions> backward_solver_options
std::string boundary_cuts_file
BoundaryCutsMode boundary_cuts_mode
int boundary_max_iterations
double convergence_confidence
ConvergenceMode convergence_mode
double convergence_tol
Relative gap tolerance for convergence.
double cut_coeff_eps
double cut_coeff_max
CutCoeffMode cut_coeff_mode
int cut_prune_interval
HotStartMode cut_recovery_mode
CutSharingMode cut_sharing
Cut sharing mode.
std::string cuts_input_file
File path for loading initial cuts (empty = no load / cold start)
std::string cuts_output_file
File path for saving cuts (empty = no save)
ElasticFilterMode elastic_filter_mode
double elastic_penalty
Penalty for elastic slack variables.
bool enable_api
std::optional<SolverOptions> forward_solver_options
std::string log_directory
bool lp_debug
std::string lp_debug_compression
OptInt lp_debug_phase_max
OptInt lp_debug_phase_min
OptInt lp_debug_scene_max
OptInt lp_debug_scene_min
bool lp_only
int max_cuts_per_phase
int max_iterations
Maximum forward/backward iterations.
int max_stored_cuts
int min_iterations
Minimum iterations before convergence.
MissingCutVarMode missing_cut_var_mode
How to handle cut rows referencing state variables not in the model.
int multi_cut_threshold
std::string named_cuts_file
double prune_dual_threshold
RecoveryMode recovery_mode
bool save_aperture_lp
bool save_per_iteration
bool save_simulation_cuts
double scale_alpha
Scale divisor for a (PLP varphi)
std::string sentinel_file
bool single_cut_storage
double solve_timeout
double stationary_tol
Default: 0.01 (1%). Set to 0.0 to disable.
int stationary_window
bool use_clone_pool
bool warm_start

Variable documentation

double gtopt::SDDPOptions::aperture_timeout

Timeout in seconds for individual aperture LP solves in the backward pass. When an aperture LP exceeds this time, it is treated as infeasible (skipped), a WARNING is logged, and the solver continues with the remaining apertures. 0 = no timeout (default).

std::optional<std::vector<Uid>> gtopt::SDDPOptions::apertures

Number of apertures (hydrological realisations) to solve in each backward-pass phase. Each aperture clones the phase LP and updates the flow column bounds to the corresponding scenario's discharge values, then solves the clone to obtain an independent Benders cut. The final cut added to the previous phase is the probability-weighted average of all aperture cuts (expected cut). Aperture UIDs for the backward pass.

nullopt – use per-phase Phase::apertures or simulation-level aperture_array (default behaviour). empty – no apertures; use pure Benders backward pass. [1,2,3] – use exactly these aperture UIDs, overriding per-phase sets.

When a non-empty list is given but no matching Aperture definitions exist in simulation.aperture_array, synthetic apertures are built from scenarios whose UIDs match.

Note: apertures only update flow column bounds (affluent values). Other stochastic parameters (demand, generator profiles) are not updated. State variable bounds remain fixed at the forward-pass trial values.

std::string gtopt::SDDPOptions::api_status_file

Path for the JSON status file. If empty, the solver writes to "<output_directory>/sddp_status.json" (derived at solve time from the PlanningLP options).

std::string gtopt::SDDPOptions::api_stop_request_file

Path for the monitoring API stop-request file. When this file exists the solver stops gracefully after the current iteration and saves cuts, exactly like the sentinel_file mechanism. The file is written by the webservice soft-stop endpoint as part of the bidirectional monitoring API. Use sddp_file::stop_request ("sddp_stop_request.json") as the filename in the output directory. Empty = feature disabled.

std::chrono::milliseconds gtopt::SDDPOptions::api_update_interval

Interval at which the background monitoring thread refreshes real-time workpool statistics (CPU load, active workers) in the status file.

std::optional<SolverOptions> gtopt::SDDPOptions::backward_solver_options

Optional LP solver options for the backward pass. When set, these override the global solver options for backward-pass solves. The options are pre-merged with the global solver options at construction time (backward takes precedence).

std::string gtopt::SDDPOptions::boundary_cuts_file

CSV file with boundary (future-cost) cuts for the last phase.

These cuts approximate the expected future cost beyond the planning horizon, analogous to PLP's "planos de embalse" (reservoir future-cost function). Each cut has the form: a >= rhs + S_i coeff_i . state_var_i

The CSV header row names the state variables (reservoirs / batteries). The solver maps these names to LP columns in the last phase and adds each cut as a lower-bound constraint on the future cost variable a. Empty = no boundary cuts.

BoundaryCutsMode gtopt::SDDPOptions::boundary_cuts_mode

How boundary cuts are loaded:

  • "noload" – skip loading even if a file is specified
  • "separated" – assign each cut to the scene matching its scene column (scene UID); unmatched UIDs are skipped
  • "combined" – broadcast all cuts to all scenes Default: "separated".

int gtopt::SDDPOptions::boundary_max_iterations

Maximum number of SDDP iterations to load from the boundary cuts file. Only cuts from the last N distinct iterations (by the iteration column / PLP IPDNumIte) are retained. 0 = load all.

double gtopt::SDDPOptions::convergence_confidence

Confidence level for statistical convergence criterion (0-1). When > 0 and multiple scenes exist, convergence is also checked via confidence interval: UB - LB <= z_{a/2} * s (PLP-style). Combined with stationary_tol, also declares convergence when the gap stabilises above the CI threshold (non-zero gap case). Default: 0.95 (95% CI).

ConvergenceMode gtopt::SDDPOptions::convergence_mode

Tolerance for the secondary stationary-gap convergence criterion.

When the relative change in the convergence gap over the last stationary_window iterations falls below this value, the solver declares convergence even if the gap is above convergence_tol. This handles problems where the SDDP gap converges to a non-zero stationary value due to stochastic noise or problem structure (a known theoretical limitation of SDDP/Benders on certain programs).

Criterion (after min_iterations and stationary_window iters done): gap_change = |gap[i] - gap[i - window]| / max(1e-10, gap[i - window]) gap_change < stationary_tol -> declare convergence

Convergence criterion mode. Default: statistical (PLP-style).

double gtopt::SDDPOptions::cut_coeff_eps

Absolute tolerance for filtering tiny Benders cut coefficients. Coefficients with |value| < cut_coeff_eps are dropped from the cut. 0.0 = no filtering (default).

double gtopt::SDDPOptions::cut_coeff_max

Maximum allowed absolute coefficient in a Benders cut row. When max|coeff| exceeds this, the entire row is rescaled uniformly. 0.0 = disabled (default).

CutCoeffMode gtopt::SDDPOptions::cut_coeff_mode

How Benders cut coefficients are extracted from solved subproblems. reduced_cost (default): reduced costs of fixed dependent columns. row_dual: row duals of explicit coupling constraint rows (PLP-style).

int gtopt::SDDPOptions::cut_prune_interval

Number of iterations between cut pruning passes. Only used when max_cuts_per_phase > 0. Default: 10.

HotStartMode gtopt::SDDPOptions::cut_recovery_mode

Hot-start mode: controls both cut loading and output file handling.

  • none: cold start – no cuts loaded (default)
  • keep: load cuts; keep original output file unchanged
  • append: load cuts; append new cuts to original file
  • replace: load cuts; replace original file with all cuts

ElasticFilterMode gtopt::SDDPOptions::elastic_filter_mode

Elastic filter mode: how to handle backward-pass infeasibility. single_cut (default) adds a single Benders feasibility cut to the previous phase. multi_cut adds the same cut plus one bound-constraint cut per activated slack variable. backpropagate updates the source column bounds to match the elastic-clone solution (PLP mechanism).

bool gtopt::SDDPOptions::enable_api

Enable the monitoring API: write a JSON status file after each iteration and periodically update real-time workpool statistics. Consumers (e.g. sddp_monitor.py) can poll this file to display live charts. Default: true.

std::optional<SolverOptions> gtopt::SDDPOptions::forward_solver_options

Optional LP solver options for the forward pass. When set, these override the global solver options for forward-pass solves. The options are pre-merged with the global solver options at construction time (forward takes precedence).

std::string gtopt::SDDPOptions::log_directory

Directory for log and error LP files (default: "logs"). Error LP files for infeasible scenes are saved here.

bool gtopt::SDDPOptions::lp_debug

When true, save a debug LP file for every (iteration, scene, phase) during the forward pass to log_directory. Files are named using sddp_file::debug_lp_fmt.

std::string gtopt::SDDPOptions::lp_debug_compression

Compression format for LP debug files ("gzip" / "uncompressed" / ""). Empty or "uncompressed" means no compression; any other value uses gzip.

OptInt gtopt::SDDPOptions::lp_debug_scene_min

Selective LP debug filters: when set, only save LP files whose scene/phase UIDs fall within [min, max] (inclusive).

bool gtopt::SDDPOptions::lp_only

When true, build all scene x phase LP matrices and exit immediately – no solving of any kind is performed. Applies to both the monolithic and SDDP solvers. If lp_debug is also true, every LP file is saved before returning. Useful for profiling LP build time without solver overhead.

int gtopt::SDDPOptions::max_cuts_per_phase

Maximum number of retained cuts per (scene, phase) LP after pruning. 0 = unlimited (default, no pruning). When non-zero, at every cut_prune_interval iterations the solver removes inactive cuts (|dual| < prune_dual_threshold) until at most max_cuts_per_phase active cuts remain.

int gtopt::SDDPOptions::max_stored_cuts

Maximum total stored cuts per scene (0 = unlimited). When non-zero, the oldest cuts beyond this limit are dropped after each iteration. Default: 0 (no cap).

int gtopt::SDDPOptions::multi_cut_threshold

Forward-pass infeasibility counter threshold for automatic switching from single_cut to multi_cut. When the forward pass has encountered infeasibility at (scene, phase) more than this many times without recovery, the backward-pass infeasibility handler switches to multi_cut mode for that (scene, phase). = 0 always use multi_cut for any infeasibility (force multi_cut).

0 switch to multi_cut after the counter exceeds this threshold. < 0 never auto-switch (disabled; use explicit mode only).

Default: 10.

std::string gtopt::SDDPOptions::named_cuts_file

CSV file with named-variable hot-start cuts for all phases.

Unlike boundary cuts (which apply only to the last phase), these cuts include a phase column indicating which phase they belong to. The solver resolves named state-variable headers (reservoir / battery / junction) to LP column indices in the specified phase, then adds each cut as a lower-bound constraint on the corresponding a variable: a_phase >= rhs + S_i coeff_i . state_var_i[phase]

Format: name,iteration,scene,phase,rhs,StateVar1,StateVar2,...

Empty = no named hot-start cuts.

double gtopt::SDDPOptions::prune_dual_threshold

Dual-value threshold for considering a cut inactive. Cuts with |dual| below this value are candidates for removal. Default: 1e-8.

RecoveryMode gtopt::SDDPOptions::recovery_mode

Controls what is recovered from a previous SDDP run:

  • none: no recovery (cold start)
  • cuts: recover only Benders cuts
  • full: recover cuts + state variable solutions (default)

bool gtopt::SDDPOptions::save_aperture_lp

Save LP files for infeasible apertures to log_directory (default: false).

bool gtopt::SDDPOptions::save_per_iteration

Save cuts to CSV after each training iteration (default: true). When false, cuts are only saved at the end of the solve or on stop.

bool gtopt::SDDPOptions::save_simulation_cuts

Save feasibility cuts produced during the simulation pass (default: false). When false, only training-iteration cuts are persisted, ensuring hot-start reproducibility.

std::string gtopt::SDDPOptions::sentinel_file

Path to a sentinel file: if the file exists, the solver stops gracefully after the current iteration (analogous to PLP's userstop). All accumulated cuts are saved before stopping.

bool gtopt::SDDPOptions::single_cut_storage

Use single cut storage: store cuts only in per-scene vectors. Combined storage for persistence is built on demand from the per-scene vectors. Halves the memory cost of stored cuts. Default: false (backward compatible).

double gtopt::SDDPOptions::solve_timeout

Global solve timeout in seconds (0 = no timeout). When non-zero, each forward-pass LP solve is given this time limit; if exceeded, the LP is saved to a debug file, a CRITICAL message is logged, and the scene is marked as failed.

int gtopt::SDDPOptions::stationary_window

Number of iterations to look back when checking gap stationarity. Only used when stationary_tol > 0.0. Default: 10.

bool gtopt::SDDPOptions::use_clone_pool

Reuse a cached LP clone for aperture solves instead of cloning anew each time. The clone's column bounds are reset from the source LP before each solve; rows beyond the base count are deleted. Avoids repeated heap allocations for the CLP solver internal matrix. Default: true.

bool gtopt::SDDPOptions::warm_start

Enable warm-start optimizations for SDDP resolves (forward pass, backward pass, apertures, elastic filter). When true, resolves use dual simplex + no presolve, pivoting from the saved forward-pass solution. Especially important when the initial solve uses barrier (the default).