diff --git a/previews/PR811/.documenter-siteinfo.json b/previews/PR811/.documenter-siteinfo.json index 4194f5c5f..4f5a36329 100644 --- a/previews/PR811/.documenter-siteinfo.json +++ b/previews/PR811/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-03T02:40:32","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-03T02:54:00","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/previews/PR811/apireference/index.html b/previews/PR811/apireference/index.html index 7b11da475..888978ccf 100644 --- a/previews/PR811/apireference/index.html +++ b/previews/PR811/apireference/index.html @@ -25,7 +25,7 @@ Nodes {} Arcs - {}source
SDDP.add_nodeFunction
add_node(graph::Graph{T}, node::T) where {T}

Add a node to the graph graph.

Examples

julia> graph = SDDP.Graph(:root);
+ {}
source
SDDP.add_nodeFunction
add_node(graph::Graph{T}, node::T) where {T}

Add a node to the graph graph.

Examples

julia> graph = SDDP.Graph(:root);
 
 julia> SDDP.add_node(graph, :A)
 
@@ -45,7 +45,7 @@
 Nodes
  2
 Arcs
- {}
source
SDDP.add_edgeFunction
add_edge(graph::Graph{T}, edge::Pair{T, T}, probability::Float64) where {T}

Add an edge to the graph graph.

Examples

julia> graph = SDDP.Graph(0);
+ {}
source
SDDP.add_edgeFunction
add_edge(graph::Graph{T}, edge::Pair{T, T}, probability::Float64) where {T}

Add an edge to the graph graph.

Examples

julia> graph = SDDP.Graph(0);
 
 julia> SDDP.add_node(graph, 1)
 
@@ -69,7 +69,7 @@
 Nodes
  A
 Arcs
- root => A w.p. 1.0
source
SDDP.add_ambiguity_setFunction
add_ambiguity_set(
+ root => A w.p. 1.0
source
SDDP.add_ambiguity_setFunction
add_ambiguity_set(
     graph::Graph{T},
     set::Vector{T},
     lipschitz::Vector{Float64},
@@ -102,7 +102,7 @@
  2 => 3 w.p. 1.0
 Partitions
  {1, 2}
- {3}
source
add_ambiguity_set(graph::Graph{T}, set::Vector{T}, lipschitz::Float64)

Add set to the belief partition of graph.

lipschitz is a Lipschitz constant for each node in set. The Lipschitz constant is the maximum slope of the cost-to-go function with respect to the belief state associated with each node at any point in the state-space.

Examples

julia> graph = SDDP.LinearGraph(3);
+ {3}
source
add_ambiguity_set(graph::Graph{T}, set::Vector{T}, lipschitz::Float64)

Add set to the belief partition of graph.

lipschitz is a Lipschitz constant for each node in set. The Lipschitz constant is the maximum slope of the cost-to-go function with respect to the belief state associated with each node at any point in the state-space.

Examples

julia> graph = SDDP.LinearGraph(3);
 
 julia> SDDP.add_ambiguity_set(graph, [1, 2], 1e3)
 
@@ -121,7 +121,7 @@
  2 => 3 w.p. 1.0
 Partitions
  {1, 2}
- {3}
source
SDDP.LinearGraphFunction
LinearGraph(stages::Int)

Create a linear graph with stages number of nodes.

Examples

julia> graph = SDDP.LinearGraph(3)
+ {3}
source
SDDP.LinearGraphFunction
LinearGraph(stages::Int)

Create a linear graph with stages number of nodes.

Examples

julia> graph = SDDP.LinearGraph(3)
 Root
  0
 Nodes
@@ -131,7 +131,7 @@
 Arcs
  0 => 1 w.p. 1.0
  1 => 2 w.p. 1.0
- 2 => 3 w.p. 1.0
source
SDDP.MarkovianGraphFunction
MarkovianGraph(transition_matrices::Vector{Matrix{Float64}})

Construct a Markovian graph from the vector of transition matrices.

transition_matrices[t][i, j] gives the probability of transitioning from Markov state i in stage t - 1 to Markov state j in stage t.

The dimension of the first transition matrix should be (1, N), and transition_matrics[1][1, i] is the probability of transitioning from the root node to the Markov state i.

Examples

julia> graph = SDDP.MarkovianGraph([ones(1, 1), [0.5 0.5], [0.8 0.2; 0.2 0.8]])
+ 2 => 3 w.p. 1.0
source
SDDP.MarkovianGraphFunction
MarkovianGraph(transition_matrices::Vector{Matrix{Float64}})

Construct a Markovian graph from the vector of transition matrices.

transition_matrices[t][i, j] gives the probability of transitioning from Markov state i in stage t - 1 to Markov state j in stage t.

The dimension of the first transition matrix should be (1, N), and transition_matrics[1][1, i] is the probability of transitioning from the root node to the Markov state i.

Examples

julia> graph = SDDP.MarkovianGraph([ones(1, 1), [0.5 0.5], [0.8 0.2; 0.2 0.8]])
 Root
  (0, 1)
 Nodes
@@ -147,7 +147,7 @@
  (2, 1) => (3, 1) w.p. 0.8
  (2, 1) => (3, 2) w.p. 0.2
  (2, 2) => (3, 1) w.p. 0.2
- (2, 2) => (3, 2) w.p. 0.8
source
MarkovianGraph(;
+ (2, 2) => (3, 2) w.p. 0.8
source
MarkovianGraph(;
     stages::Int,
     transition_matrix::Matrix{Float64},
     root_node_transition::Vector{Float64},
@@ -175,11 +175,11 @@
  (2, 1) => (3, 1) w.p. 0.8
  (2, 1) => (3, 2) w.p. 0.2
  (2, 2) => (3, 1) w.p. 0.2
- (2, 2) => (3, 2) w.p. 0.8
source
MarkovianGraph(
+ (2, 2) => (3, 2) w.p. 0.8
source
MarkovianGraph(
     simulator::Function;
     budget::Union{Int,Vector{Int}},
     scenarios::Int = 1000,
-)

Construct a Markovian graph by fitting Markov chain to scenarios generated by simulator().

budget is the total number of nodes in the resulting Markov chain. This can either be specified as a single Int, in which case we will attempt to intelligently distributed the nodes between stages. Alternatively, budget can be a Vector{Int}, which details the number of Markov state to have in each stage.

source
SDDP.UnicyclicGraphFunction
UnicyclicGraph(discount_factor::Float64; num_nodes::Int = 1)

Construct a graph composed of num_nodes nodes that form a single cycle, with a probability of discount_factor of continuing the cycle.

Examples

julia> graph = SDDP.UnicyclicGraph(0.9; num_nodes = 2)
+)

Construct a Markovian graph by fitting Markov chain to scenarios generated by simulator().

budget is the total number of nodes in the resulting Markov chain. This can either be specified as a single Int, in which case we will attempt to intelligently distributed the nodes between stages. Alternatively, budget can be a Vector{Int}, which details the number of Markov state to have in each stage.

source
SDDP.UnicyclicGraphFunction
UnicyclicGraph(discount_factor::Float64; num_nodes::Int = 1)

Construct a graph composed of num_nodes nodes that form a single cycle, with a probability of discount_factor of continuing the cycle.

Examples

julia> graph = SDDP.UnicyclicGraph(0.9; num_nodes = 2)
 Root
  0
 Nodes
@@ -188,7 +188,7 @@
 Arcs
  0 => 1 w.p. 1.0
  1 => 2 w.p. 1.0
- 2 => 1 w.p. 0.9
source
SDDP.LinearPolicyGraphFunction
LinearPolicyGraph(builder::Function; stages::Int, kwargs...)

Create a linear policy graph with stages number of stages.

Keyword arguments

  • stages: the number of stages in the graph

  • kwargs: other keyword arguments are passed to SDDP.PolicyGraph.

Examples

julia> SDDP.LinearPolicyGraph(; stages = 2, lower_bound = 0.0) do sp, t
+ 2 => 1 w.p. 0.9
source
SDDP.LinearPolicyGraphFunction
LinearPolicyGraph(builder::Function; stages::Int, kwargs...)

Create a linear policy graph with stages number of stages.

Keyword arguments

  • stages: the number of stages in the graph

  • kwargs: other keyword arguments are passed to SDDP.PolicyGraph.

Examples

julia> SDDP.LinearPolicyGraph(; stages = 2, lower_bound = 0.0) do sp, t
     # ... build model ...
 end
 A policy graph with 2 nodes.
@@ -198,7 +198,7 @@
     # ... build model ...
 end
 A policy graph with 2 nodes.
-Node indices: 1, 2
source
SDDP.MarkovianPolicyGraphFunction
MarkovianPolicyGraph(
+Node indices: 1, 2
source
SDDP.MarkovianPolicyGraphFunction
MarkovianPolicyGraph(
     builder::Function;
     transition_matrices::Vector{Array{Float64,2}},
     kwargs...
@@ -215,7 +215,7 @@
     # ... build model ...
 end
 A policy graph with 5 nodes.
- Node indices: (1, 1), (2, 1), (2, 2), (3, 1), (3, 2)
source
SDDP.PolicyGraphType
PolicyGraph(
+ Node indices: (1, 1), (2, 1), (2, 2), (3, 1), (3, 2)
source
SDDP.PolicyGraphType
PolicyGraph(
     builder::Function,
     graph::Graph{T};
     sense::Symbol = :Min,
@@ -237,28 +237,28 @@
     optimizer = HiGHS.Optimizer,
 ) do subproblem, index
     # ... subproblem definitions ...
-end
source

Subproblem definition

SDDP.@stageobjectiveMacro
@stageobjective(subproblem, expr)

Set the stage-objective of subproblem to expr.

Examples

@stageobjective(subproblem, 2x + y)
source
SDDP.parameterizeFunction
parameterize(
+end
source

Subproblem definition

SDDP.@stageobjectiveMacro
@stageobjective(subproblem, expr)

Set the stage-objective of subproblem to expr.

Examples

@stageobjective(subproblem, 2x + y)
source
SDDP.parameterizeFunction
parameterize(
     modify::Function,
     subproblem::JuMP.Model,
     realizations::Vector{T},
     probability::Vector{Float64} = fill(1.0 / length(realizations))
 ) where {T}

Add a parameterization function modify to subproblem. The modify function takes one argument and modifies subproblem based on the realization of the noise sampled from realizations with corresponding probabilities probability.

In order to conduct an out-of-sample simulation, modify should accept arguments that are not in realizations (but still of type T).

Examples

SDDP.parameterize(subproblem, [1, 2, 3], [0.4, 0.3, 0.3]) do ω
     JuMP.set_upper_bound(x, ω)
-end
source
parameterize(node::Node, noise)

Parameterize node node with the noise noise.

source
SDDP.add_objective_stateFunction
add_objective_state(update::Function, subproblem::JuMP.Model; kwargs...)

Add an objective state variable to subproblem.

Required kwargs are:

  • initial_value: The initial value of the objective state variable at the root node.
  • lipschitz: The lipschitz constant of the objective state variable.

Setting a tight value for the lipschitz constant can significantly improve the speed of convergence.

Optional kwargs are:

  • lower_bound: A valid lower bound for the objective state variable. Can be -Inf.
  • upper_bound: A valid upper bound for the objective state variable. Can be +Inf.

Setting tight values for these optional variables can significantly improve the speed of convergence.

If the objective state is N-dimensional, each keyword argument must be an NTuple{N,Float64}. For example, initial_value = (0.0, 1.0).

source
SDDP.objective_stateFunction
objective_state(subproblem::JuMP.Model)

Return the current objective state of the problem.

Can only be called from SDDP.parameterize.

source
SDDP.NoiseType
Noise(support, probability)

An atom of a discrete random variable at the point of support support and associated probability probability.

source

Training the policy

SDDP.numerical_stability_reportFunction
numerical_stability_report(
+end
source
parameterize(node::Node, noise)

Parameterize node node with the noise noise.

source
SDDP.add_objective_stateFunction
add_objective_state(update::Function, subproblem::JuMP.Model; kwargs...)

Add an objective state variable to subproblem.

Required kwargs are:

  • initial_value: The initial value of the objective state variable at the root node.
  • lipschitz: The lipschitz constant of the objective state variable.

Setting a tight value for the lipschitz constant can significantly improve the speed of convergence.

Optional kwargs are:

  • lower_bound: A valid lower bound for the objective state variable. Can be -Inf.
  • upper_bound: A valid upper bound for the objective state variable. Can be +Inf.

Setting tight values for these optional variables can significantly improve the speed of convergence.

If the objective state is N-dimensional, each keyword argument must be an NTuple{N,Float64}. For example, initial_value = (0.0, 1.0).

source
SDDP.objective_stateFunction
objective_state(subproblem::JuMP.Model)

Return the current objective state of the problem.

Can only be called from SDDP.parameterize.

source
SDDP.NoiseType
Noise(support, probability)

An atom of a discrete random variable at the point of support support and associated probability probability.

source

Training the policy

SDDP.numerical_stability_reportFunction
numerical_stability_report(
     [io::IO = stdout,]
     model::PolicyGraph;
     by_node::Bool = false,
     print::Bool = true,
     warn::Bool = true,
-)

Print a report identifying possible numeric stability issues.

Keyword arguments

  • If by_node, print a report for each node in the graph.

  • If print, print to io.

  • If warn, warn if the coefficients may cause numerical issues.

source
SDDP.trainFunction
SDDP.train(model::PolicyGraph; kwargs...)

Train the policy for model.

Keyword arguments

  • iteration_limit::Int: number of iterations to conduct before termination.

  • time_limit::Float64: number of seconds to train before termination.

  • stoping_rules: a vector of SDDP.AbstractStoppingRules. Defaults to SimulationStoppingRule.

  • print_level::Int: control the level of printing to the screen. Defaults to 1. Set to 0 to disable all printing.

  • log_file::String: filepath at which to write a log of the training progress. Defaults to SDDP.log.

  • log_frequency::Int: control the frequency with which the logging is outputted (iterations/log). It must be at least 1. Defaults to 1.

  • log_every_seconds::Float64: control the frequency with which the logging is outputted (seconds/log). Defaults to 0.0.

  • log_every_iteration::Bool; over-rides log_frequency and log_every_seconds to force every iteration to be printed. Defaults to false.

  • run_numerical_stability_report::Bool: generate (and print) a numerical stability report prior to solve. Defaults to true.

  • refine_at_similar_nodes::Bool: if SDDP can detect that two nodes have the same children, it can cheaply add a cut discovered at one to the other. In almost all cases this should be set to true.

  • cut_deletion_minimum::Int: the minimum number of cuts to cache before deleting cuts from the subproblem. The impact on performance is solver specific; however, smaller values result in smaller subproblems (and therefore quicker solves), at the expense of more time spent performing cut selection.

  • risk_measure: the risk measure to use at each node. Defaults to Expectation.

  • root_node_risk_measure::AbstractRiskMeasure: the risk measure to use at the root node when computing the Bound column. Note that the choice of this option does not change the primal policy, and it applies only if the transition from the root node to the first stage is stochastic. Defaults to Expectation.

  • sampling_scheme: a sampling scheme to use on the forward pass of the algorithm. Defaults to InSampleMonteCarlo.

  • backward_sampling_scheme: a backward pass sampling scheme to use on the backward pass of the algorithm. Defaults to CompleteSampler.

  • cut_type: choose between SDDP.SINGLE_CUT and SDDP.MULTI_CUT versions of SDDP.

  • dashboard::Bool: open a visualization of the training over time. Defaults to false.

  • parallel_scheme::AbstractParallelScheme: specify a scheme for solving in parallel. Defaults to Threaded().

  • forward_pass::AbstractForwardPass: specify a scheme to use for the forward passes.

  • forward_pass_resampling_probability::Union{Nothing,Float64}: set to a value in (0, 1) to enable RiskAdjustedForwardPass. Defaults to nothing (disabled).

  • add_to_existing_cuts::Bool: set to true to allow training a model that was previously trained. Defaults to false.

  • duality_handler::AbstractDualityHandler: specify a duality handler to use when creating cuts.

  • post_iteration_callback::Function: a callback with the signature post_iteration_callback(::IterationResult) that is evaluated after each iteration of the algorithm.

There is also a special option for infinite horizon problems

  • cycle_discretization_delta: the maximum distance between states allowed on the forward pass. This is for advanced users only and needs to be used in conjunction with a different sampling_scheme.
source
SDDP.termination_statusFunction
termination_status(model::PolicyGraph)::Symbol

Query the reason why the training stopped.

source
SDDP.write_cuts_to_fileFunction
write_cuts_to_file(
+)

Print a report identifying possible numeric stability issues.

Keyword arguments

  • If by_node, print a report for each node in the graph.

  • If print, print to io.

  • If warn, warn if the coefficients may cause numerical issues.

source
SDDP.trainFunction
SDDP.train(model::PolicyGraph; kwargs...)

Train the policy for model.

Keyword arguments

  • iteration_limit::Int: number of iterations to conduct before termination.

  • time_limit::Float64: number of seconds to train before termination.

  • stoping_rules: a vector of SDDP.AbstractStoppingRules. Defaults to SimulationStoppingRule.

  • print_level::Int: control the level of printing to the screen. Defaults to 1. Set to 0 to disable all printing.

  • log_file::String: filepath at which to write a log of the training progress. Defaults to SDDP.log.

  • log_frequency::Int: control the frequency with which the logging is outputted (iterations/log). It must be at least 1. Defaults to 1.

  • log_every_seconds::Float64: control the frequency with which the logging is outputted (seconds/log). Defaults to 0.0.

  • log_every_iteration::Bool; over-rides log_frequency and log_every_seconds to force every iteration to be printed. Defaults to false.

  • run_numerical_stability_report::Bool: generate (and print) a numerical stability report prior to solve. Defaults to true.

  • refine_at_similar_nodes::Bool: if SDDP can detect that two nodes have the same children, it can cheaply add a cut discovered at one to the other. In almost all cases this should be set to true.

  • cut_deletion_minimum::Int: the minimum number of cuts to cache before deleting cuts from the subproblem. The impact on performance is solver specific; however, smaller values result in smaller subproblems (and therefore quicker solves), at the expense of more time spent performing cut selection.

  • risk_measure: the risk measure to use at each node. Defaults to Expectation.

  • root_node_risk_measure::AbstractRiskMeasure: the risk measure to use at the root node when computing the Bound column. Note that the choice of this option does not change the primal policy, and it applies only if the transition from the root node to the first stage is stochastic. Defaults to Expectation.

  • sampling_scheme: a sampling scheme to use on the forward pass of the algorithm. Defaults to InSampleMonteCarlo.

  • backward_sampling_scheme: a backward pass sampling scheme to use on the backward pass of the algorithm. Defaults to CompleteSampler.

  • cut_type: choose between SDDP.SINGLE_CUT and SDDP.MULTI_CUT versions of SDDP.

  • dashboard::Bool: open a visualization of the training over time. Defaults to false.

  • parallel_scheme::AbstractParallelScheme: specify a scheme for solving in parallel. Defaults to Threaded().

  • forward_pass::AbstractForwardPass: specify a scheme to use for the forward passes.

  • forward_pass_resampling_probability::Union{Nothing,Float64}: set to a value in (0, 1) to enable RiskAdjustedForwardPass. Defaults to nothing (disabled).

  • add_to_existing_cuts::Bool: set to true to allow training a model that was previously trained. Defaults to false.

  • duality_handler::AbstractDualityHandler: specify a duality handler to use when creating cuts.

  • post_iteration_callback::Function: a callback with the signature post_iteration_callback(::IterationResult) that is evaluated after each iteration of the algorithm.

There is also a special option for infinite horizon problems

  • cycle_discretization_delta: the maximum distance between states allowed on the forward pass. This is for advanced users only and needs to be used in conjunction with a different sampling_scheme.
source
SDDP.termination_statusFunction
termination_status(model::PolicyGraph)::Symbol

Query the reason why the training stopped.

source
SDDP.write_cuts_to_fileFunction
write_cuts_to_file(
     model::PolicyGraph{T},
     filename::String;
     kwargs...,
-) where {T}

Write the cuts that form the policy in model to filename in JSON format.

Keyword arguments

  • node_name_parser is a function which converts the name of each node into a string representation. It has the signature: node_name_parser(::T)::String.

  • write_only_selected_cuts write only the selected cuts to the json file. Defaults to false.

See also SDDP.read_cuts_from_file.

source
SDDP.read_cuts_from_fileFunction
read_cuts_from_file(
+) where {T}

Write the cuts that form the policy in model to filename in JSON format.

Keyword arguments

  • node_name_parser is a function which converts the name of each node into a string representation. It has the signature: node_name_parser(::T)::String.

  • write_only_selected_cuts write only the selected cuts to the json file. Defaults to false.

See also SDDP.read_cuts_from_file.

source
SDDP.read_cuts_from_fileFunction
read_cuts_from_file(
     model::PolicyGraph{T},
     filename::String;
     kwargs...,
-) where {T}

Read cuts (saved using SDDP.write_cuts_to_file) from filename into model.

Since T can be an arbitrary Julia type, the conversion to JSON is lossy. When reading, read_cuts_from_file only supports T=Int, T=NTuple{N, Int}, and T=Symbol. If you have manually created a policy graph with a different node type T, provide a function node_name_parser with the signature

Keyword arguments

  • node_name_parser(T, name::String)::T where {T} that returns the name of each node given the string name name. If node_name_parser returns nothing, those cuts are skipped.

  • cut_selection::Bool run or not the cut selection algorithm when adding the cuts to the model.

See also SDDP.write_cuts_to_file.

source
SDDP.write_log_to_csvFunction
write_log_to_csv(model::PolicyGraph, filename::String)

Write the log of the most recent training to a csv for post-analysis.

Assumes that the model has been trained via SDDP.train.

source
SDDP.set_numerical_difficulty_callbackFunction
set_numerical_difficulty_callback(
+) where {T}

Read cuts (saved using SDDP.write_cuts_to_file) from filename into model.

Since T can be an arbitrary Julia type, the conversion to JSON is lossy. When reading, read_cuts_from_file only supports T=Int, T=NTuple{N, Int}, and T=Symbol. If you have manually created a policy graph with a different node type T, provide a function node_name_parser with the signature

Keyword arguments

  • node_name_parser(T, name::String)::T where {T} that returns the name of each node given the string name name. If node_name_parser returns nothing, those cuts are skipped.

  • cut_selection::Bool run or not the cut selection algorithm when adding the cuts to the model.

See also SDDP.write_cuts_to_file.

source
SDDP.write_log_to_csvFunction
write_log_to_csv(model::PolicyGraph, filename::String)

Write the log of the most recent training to a csv for post-analysis.

Assumes that the model has been trained via SDDP.train.

source
SDDP.set_numerical_difficulty_callbackFunction
set_numerical_difficulty_callback(
     model::PolicyGraph,
     callback::Function,
 )

Set a callback function callback(::PolicyGraph, ::Node; require_dual::Bool) that is run when the optimizer terminates without finding a primal solution (and dual solution if require_dual is true).

Default callback

The default callback is a small variation of:

function callback(::PolicyGraph, node::Node; require_dual::Bool)
@@ -274,29 +274,29 @@
     end
     return
 end
-SDDP.set_numerical_difficulty_callback(model, callback)
source

Stopping rules

SDDP.AbstractStoppingRuleType
AbstractStoppingRule

The abstract type for the stopping-rule interface.

You need to define the following methods:

source
SDDP.stopping_rule_statusFunction
stopping_rule_status(::AbstractStoppingRule)::Symbol

Return a symbol describing the stopping rule.

source
SDDP.convergence_testFunction
convergence_test(
+SDDP.set_numerical_difficulty_callback(model, callback)
source

Stopping rules

SDDP.AbstractStoppingRuleType
AbstractStoppingRule

The abstract type for the stopping-rule interface.

You need to define the following methods:

source
SDDP.stopping_rule_statusFunction
stopping_rule_status(::AbstractStoppingRule)::Symbol

Return a symbol describing the stopping rule.

source
SDDP.convergence_testFunction
convergence_test(
     model::PolicyGraph,
     log::Vector{Log},
     ::AbstractStoppingRule,
-)::Bool

Return a Bool indicating if the algorithm should terminate the training.

source
SDDP.IterationLimitType
IterationLimit(limit::Int)

Teriminate the algorithm after limit number of iterations.

source
SDDP.TimeLimitType
TimeLimit(limit::Float64)

Teriminate the algorithm after limit seconds of computation.

source
SDDP.StatisticalType
Statistical(;
+)::Bool

Return a Bool indicating if the algorithm should terminate the training.

source
SDDP.IterationLimitType
IterationLimit(limit::Int)

Teriminate the algorithm after limit number of iterations.

source
SDDP.TimeLimitType
TimeLimit(limit::Float64)

Teriminate the algorithm after limit seconds of computation.

source
SDDP.StatisticalType
Statistical(;
     num_replications::Int,
     iteration_period::Int = 1,
     z_score::Float64 = 1.96,
     verbose::Bool = true,
     disable_warning::Bool = false,
-)

Perform an in-sample Monte Carlo simulation of the policy with num_replications replications every iteration_periods and terminate if the deterministic bound (lower if minimizing) falls into the confidence interval for the mean of the simulated cost.

If verbose = true, print the confidence interval.

If disable_warning = true, disable the warning telling you not to use this stopping rule (see below).

Why this stopping rule is not good

This stopping rule is one of the most common stopping rules seen in the literature. Don't follow the crowd. It is a poor choice for your model, and should be rarely used. Instead, you should use the default stopping rule, or use a fixed limit like a time or iteration limit.

To understand why this stopping rule is a bad idea, assume we have conducted num_replications simulations and the objectives are in a vector objectives::Vector{Float64}.

Our mean is μ = mean(objectives) and the half-width of the confidence interval is w = z_score * std(objectives) / sqrt(num_replications).

Many papers suggest terminating the algorithm once the deterministic bound (lower if minimizing, upper if maximizing) is contained within the confidence interval. That is, if μ - w <= bound <= μ + w. Even worse, some papers define an optimization gap of (μ + w) / bound (if minimizing) or (μ - w) / bound (if maximizing), and they terminate once the gap is less than a value like 1%.

Both of these approaches are misleading, and more often than not, they will result in terminating with a sub-optimal policy that performs worse than expected. There are two main reasons for this:

  1. The half-width depends on the number of replications. To reduce the computational cost, users are often tempted to choose a small number of replications. This increases the half-width and makes it more likely that the algorithm will stop early. But if we choose a large number of replications, then the computational cost is high, and we would have been better off to run a fixed number of iterations and use that computational time to run extra training iterations.
  2. The confidence interval assumes that the simulated values are normally distributed. In infinite horizon models, this is almost never the case. The distribution is usually closer to exponential or log-normal.

There is a third, more technical reason which relates to the conditional dependence of constructing multiple confidence intervals.

The default value of z_score = 1.96 corresponds to a 95% confidence interval. You should interpret the interval as "if we re-run this simulation 100 times, then the true mean will lie in the confidence interval 95 times out of 100." But if the bound is within the confidence interval, then we know the true mean cannot be better than the bound. Therfore, there is a more than 95% chance that the mean is within the interval.

A separate problem arises if we simulate, find that the bound is outside the confidence interval, keep training, and then re-simulate to compute a new confidence interval. Because we will terminate when the bound enters the confidence interval, the repeated construction of a confidence interval means that the unconditional probability that we terminate with a false positive is larger than 5% (there are now more chances that the sample mean is optimistic and that the confidence interval includes the bound but not the true mean). One fix is to simulate with a sequentially increasing number of replicates, so that the unconditional probability stays at 95%, but this runs into the problem of computational cost. For more information on sequential sampling, see, for example, Güzin Bayraksan, David P. Morton, (2011) A Sequential Sampling Procedure for Stochastic Programming. Operations Research 59(4):898-913.

source
SDDP.BoundStallingType
BoundStalling(num_previous_iterations::Int, tolerance::Float64)

Teriminate the algorithm once the deterministic bound (lower if minimizing, upper if maximizing) fails to improve by more than tolerance in absolute terms for more than num_previous_iterations consecutve iterations, provided it has improved relative to the bound after the first iteration.

Checking for an improvement relative to the first iteration avoids early termination in a situation where the bound fails to improve for the first N iterations. This frequently happens in models with a large number of stages, where it takes time for the cuts to propogate backward enough to modify the bound of the root node.

source
SDDP.StoppingChainType
StoppingChain(rules::AbstractStoppingRule...)

Terminate once all of the rules are statified.

This stopping rule short-circuits, so subsequent rules are only tested if the previous pass.

Examples

A stopping rule that runs 100 iterations, then checks for the bound stalling:

StoppingChain(IterationLimit(100), BoundStalling(5, 0.1))
source
SDDP.SimulationStoppingRuleType
SimulationStoppingRule(;
+)

Perform an in-sample Monte Carlo simulation of the policy with num_replications replications every iteration_periods and terminate if the deterministic bound (lower if minimizing) falls into the confidence interval for the mean of the simulated cost.

If verbose = true, print the confidence interval.

If disable_warning = true, disable the warning telling you not to use this stopping rule (see below).

Why this stopping rule is not good

This stopping rule is one of the most common stopping rules seen in the literature. Don't follow the crowd. It is a poor choice for your model, and should be rarely used. Instead, you should use the default stopping rule, or use a fixed limit like a time or iteration limit.

To understand why this stopping rule is a bad idea, assume we have conducted num_replications simulations and the objectives are in a vector objectives::Vector{Float64}.

Our mean is μ = mean(objectives) and the half-width of the confidence interval is w = z_score * std(objectives) / sqrt(num_replications).

Many papers suggest terminating the algorithm once the deterministic bound (lower if minimizing, upper if maximizing) is contained within the confidence interval. That is, if μ - w <= bound <= μ + w. Even worse, some papers define an optimization gap of (μ + w) / bound (if minimizing) or (μ - w) / bound (if maximizing), and they terminate once the gap is less than a value like 1%.

Both of these approaches are misleading, and more often than not, they will result in terminating with a sub-optimal policy that performs worse than expected. There are two main reasons for this:

  1. The half-width depends on the number of replications. To reduce the computational cost, users are often tempted to choose a small number of replications. This increases the half-width and makes it more likely that the algorithm will stop early. But if we choose a large number of replications, then the computational cost is high, and we would have been better off to run a fixed number of iterations and use that computational time to run extra training iterations.
  2. The confidence interval assumes that the simulated values are normally distributed. In infinite horizon models, this is almost never the case. The distribution is usually closer to exponential or log-normal.

There is a third, more technical reason which relates to the conditional dependence of constructing multiple confidence intervals.

The default value of z_score = 1.96 corresponds to a 95% confidence interval. You should interpret the interval as "if we re-run this simulation 100 times, then the true mean will lie in the confidence interval 95 times out of 100." But if the bound is within the confidence interval, then we know the true mean cannot be better than the bound. Therfore, there is a more than 95% chance that the mean is within the interval.

A separate problem arises if we simulate, find that the bound is outside the confidence interval, keep training, and then re-simulate to compute a new confidence interval. Because we will terminate when the bound enters the confidence interval, the repeated construction of a confidence interval means that the unconditional probability that we terminate with a false positive is larger than 5% (there are now more chances that the sample mean is optimistic and that the confidence interval includes the bound but not the true mean). One fix is to simulate with a sequentially increasing number of replicates, so that the unconditional probability stays at 95%, but this runs into the problem of computational cost. For more information on sequential sampling, see, for example, Güzin Bayraksan, David P. Morton, (2011) A Sequential Sampling Procedure for Stochastic Programming. Operations Research 59(4):898-913.

source
SDDP.BoundStallingType
BoundStalling(num_previous_iterations::Int, tolerance::Float64)

Teriminate the algorithm once the deterministic bound (lower if minimizing, upper if maximizing) fails to improve by more than tolerance in absolute terms for more than num_previous_iterations consecutve iterations, provided it has improved relative to the bound after the first iteration.

Checking for an improvement relative to the first iteration avoids early termination in a situation where the bound fails to improve for the first N iterations. This frequently happens in models with a large number of stages, where it takes time for the cuts to propogate backward enough to modify the bound of the root node.

source
SDDP.StoppingChainType
StoppingChain(rules::AbstractStoppingRule...)

Terminate once all of the rules are statified.

This stopping rule short-circuits, so subsequent rules are only tested if the previous pass.

Examples

A stopping rule that runs 100 iterations, then checks for the bound stalling:

StoppingChain(IterationLimit(100), BoundStalling(5, 0.1))
source
SDDP.SimulationStoppingRuleType
SimulationStoppingRule(;
     sampling_scheme::AbstractSamplingScheme = SDDP.InSampleMonteCarlo(),
     replications::Int = -1,
     period::Int = -1,
     distance_tol::Float64 = 1e-2,
     bound_tol::Float64 = 1e-4,
-)

Terminate the algorithm using a mix of heuristics. Unless you know otherwise, this is typically a good default.

Termination criteria

First, we check that the deterministic bound has stabilized. That is, over the last five iterations, the deterministic bound has changed by less than an absolute or relative tolerance of bound_tol.

Then, if we have not done one in the last period iterations, we perform a primal simulation of the policy using replications out-of-sample realizations from sampling_scheme. The realizations are stored and re-used in each simulation. From each simulation, we record the value of the stage objective. We terminate the policy if each of the trajectories in two consecutive simulations differ by less than distance_tol.

By default, replications and period are -1, and SDDP.jl will guess good values for these. Over-ride the default behavior by setting an appropriate value.

Example

SDDP.train(model; stopping_rules = [SimulationStoppingRule()])
source
SDDP.FirstStageStoppingRuleType
FirstStageStoppingRule(; atol::Float64 = 1e-3, iterations::Int = 50)

Terminate the algorithm when the outgoing values of the first-stage state variables have not changed by more than atol for iterations number of consecutive iterations.

Example

SDDP.train(model; stopping_rules = [FirstStageStoppingRule()])
source

Sampling schemes

SDDP.AbstractSamplingSchemeType
AbstractSamplingScheme

The abstract type for the sampling-scheme interface.

You need to define the following methods:

source
SDDP.sample_scenarioFunction
sample_scenario(graph::PolicyGraph{T}, ::AbstractSamplingScheme) where {T}

Sample a scenario from the policy graph graph based on the sampling scheme.

Returns ::Tuple{Vector{Tuple{T, <:Any}}, Bool}, where the first element is the scenario, and the second element is a Boolean flag indicating if the scenario was terminated due to the detection of a cycle.

The scenario is a list of tuples (type Vector{Tuple{T, <:Any}}) where the first component of each tuple is the index of the node, and the second component is the stagewise-independent noise term observed in that node.

source
SDDP.InSampleMonteCarloType
InSampleMonteCarlo(;
+)

Terminate the algorithm using a mix of heuristics. Unless you know otherwise, this is typically a good default.

Termination criteria

First, we check that the deterministic bound has stabilized. That is, over the last five iterations, the deterministic bound has changed by less than an absolute or relative tolerance of bound_tol.

Then, if we have not done one in the last period iterations, we perform a primal simulation of the policy using replications out-of-sample realizations from sampling_scheme. The realizations are stored and re-used in each simulation. From each simulation, we record the value of the stage objective. We terminate the policy if each of the trajectories in two consecutive simulations differ by less than distance_tol.

By default, replications and period are -1, and SDDP.jl will guess good values for these. Over-ride the default behavior by setting an appropriate value.

Example

SDDP.train(model; stopping_rules = [SimulationStoppingRule()])
source
SDDP.FirstStageStoppingRuleType
FirstStageStoppingRule(; atol::Float64 = 1e-3, iterations::Int = 50)

Terminate the algorithm when the outgoing values of the first-stage state variables have not changed by more than atol for iterations number of consecutive iterations.

Example

SDDP.train(model; stopping_rules = [FirstStageStoppingRule()])
source

Sampling schemes

SDDP.AbstractSamplingSchemeType
AbstractSamplingScheme

The abstract type for the sampling-scheme interface.

You need to define the following methods:

source
SDDP.sample_scenarioFunction
sample_scenario(graph::PolicyGraph{T}, ::AbstractSamplingScheme) where {T}

Sample a scenario from the policy graph graph based on the sampling scheme.

Returns ::Tuple{Vector{Tuple{T, <:Any}}, Bool}, where the first element is the scenario, and the second element is a Boolean flag indicating if the scenario was terminated due to the detection of a cycle.

The scenario is a list of tuples (type Vector{Tuple{T, <:Any}}) where the first component of each tuple is the index of the node, and the second component is the stagewise-independent noise term observed in that node.

source
SDDP.InSampleMonteCarloType
InSampleMonteCarlo(;
     max_depth::Int = 0,
     terminate_on_cycle::Function = false,
     terminate_on_dummy_leaf::Function = true,
     rollout_limit::Function = (i::Int) -> typemax(Int),
     initial_node::Any = nothing,
-)

A Monte Carlo sampling scheme using the in-sample data from the policy graph definition.

If terminate_on_cycle, terminate the forward pass once a cycle is detected. If max_depth > 0, return once max_depth nodes have been sampled. If terminate_on_dummy_leaf, terminate the forward pass with 1 - probability of sampling a child node.

Note that if terminate_on_cycle = false and terminate_on_dummy_leaf = false then max_depth must be set > 0.

Control which node the trajectories start from using initial_node. If it is left as nothing, the root node is used as the starting node.

You can use rollout_limit to set iteration specific depth limits. For example:

InSampleMonteCarlo(rollout_limit = i -> 2 * i)
source
SDDP.OutOfSampleMonteCarloType
OutOfSampleMonteCarlo(
+)

A Monte Carlo sampling scheme using the in-sample data from the policy graph definition.

If terminate_on_cycle, terminate the forward pass once a cycle is detected. If max_depth > 0, return once max_depth nodes have been sampled. If terminate_on_dummy_leaf, terminate the forward pass with 1 - probability of sampling a child node.

Note that if terminate_on_cycle = false and terminate_on_dummy_leaf = false then max_depth must be set > 0.

Control which node the trajectories start from using initial_node. If it is left as nothing, the root node is used as the starting node.

You can use rollout_limit to set iteration specific depth limits. For example:

InSampleMonteCarlo(rollout_limit = i -> 2 * i)
source
SDDP.OutOfSampleMonteCarloType
OutOfSampleMonteCarlo(
     f::Function,
     graph::PolicyGraph;
     use_insample_transition::Bool = false,
@@ -315,7 +315,7 @@
     end
 end

Given linear policy graph graph with T stages:

sampler = OutOfSampleMonteCarlo(graph, use_insample_transition=true) do node
     return [SDDP.Noise(node, 0.3), SDDP.Noise(node + 1, 0.7)]
-end
source
SDDP.HistoricalType
Historical(
+end
source
SDDP.HistoricalType
Historical(
     scenarios::Vector{Vector{Tuple{T,S}}},
     probability::Vector{Float64};
     terminate_on_cycle::Bool = false,
@@ -326,17 +326,17 @@
         [(1, 1.0), (2, 0.0), (3, 0.0)]
     ],
     [0.2, 0.5, 0.3],
-)
source
Historical(
+)
source
Historical(
     scenarios::Vector{Vector{Tuple{T,S}}};
     terminate_on_cycle::Bool = false,
 ) where {T,S}

A deterministic sampling scheme that iterates through the vector of provided scenarios.

Examples

Historical([
     [(1, 0.5), (2, 1.0), (3, 0.5)],
     [(1, 0.5), (2, 0.0), (3, 1.0)],
     [(1, 1.0), (2, 0.0), (3, 0.0)],
-])
source
Historical(
+])
source
Historical(
     scenario::Vector{Tuple{T,S}};
     terminate_on_cycle::Bool = false,
-) where {T,S}

A deterministic sampling scheme that always samples scenario.

Examples

Historical([(1, 0.5), (2, 1.5), (3, 0.75)])
source
SDDP.PSRSamplingSchemeType
PSRSamplingScheme(N::Int; sampling_scheme = InSampleMonteCarlo())

A sampling scheme with N scenarios, similar to how PSR does it.

source
SDDP.SimulatorSamplingSchemeType
SimulatorSamplingScheme(simulator::Function)

Create a sampling scheme based on a univariate scenario generator simulator, which returns a Vector{Float64} when called with no arguments like simulator().

This sampling scheme must be used with a Markovian graph constructed from the same simulator.

The sample space for SDDP.parameterize must be a tuple with 1 or 2 values, value is the Markov state and the second value is the random variable for the current node. If the node is deterministic, use Ω = [(markov_state,)].

This sampling scheme generates a new scenario by calling simulator(), and then picking the sequence of nodes in the Markovian graph that is closest to the new trajectory.

Example

julia> using SDDP
+) where {T,S}

A deterministic sampling scheme that always samples scenario.

Examples

Historical([(1, 0.5), (2, 1.5), (3, 0.75)])
source
SDDP.PSRSamplingSchemeType
PSRSamplingScheme(N::Int; sampling_scheme = InSampleMonteCarlo())

A sampling scheme with N scenarios, similar to how PSR does it.

source
SDDP.SimulatorSamplingSchemeType
SimulatorSamplingScheme(simulator::Function)

Create a sampling scheme based on a univariate scenario generator simulator, which returns a Vector{Float64} when called with no arguments like simulator().

This sampling scheme must be used with a Markovian graph constructed from the same simulator.

The sample space for SDDP.parameterize must be a tuple with 1 or 2 values, value is the Markov state and the second value is the random variable for the current node. If the node is deterministic, use Ω = [(markov_state,)].

This sampling scheme generates a new scenario by calling simulator(), and then picking the sequence of nodes in the Markovian graph that is closest to the new trajectory.

Example

julia> using SDDP
 
 julia> import HiGHS
 
@@ -368,50 +368,50 @@
            iteration_limit = 10,
            sampling_scheme = SDDP.SimulatorSamplingScheme(simulator),
        )
-
source

Parallel schemes

SDDP.AbstractParallelSchemeType
AbstractParallelScheme

Abstract type for different parallelism schemes.

source
SDDP.SerialType
Serial()

Run SDDP in serial mode.

source
SDDP.ThreadedType
Threaded()

Run SDDP in multi-threaded mode.

Use julia --threads N to start Julia with N threads. In most cases, you should pick N to be the number of physical cores on your machine.

Danger

This plug-in is experimental, and parts of SDDP.jl may not be threadsafe. If you encounter any problems or crashes, please open a GitHub issue.

Example

SDDP.train(model; parallel_scheme = SDDP.Threaded())
-SDDP.simulate(model; parallel_scheme = SDDP.Threaded())
source
SDDP.AsynchronousType
Asynchronous(
+
source

Parallel schemes

SDDP.AbstractParallelSchemeType
AbstractParallelScheme

Abstract type for different parallelism schemes.

source
SDDP.SerialType
Serial()

Run SDDP in serial mode.

source
SDDP.ThreadedType
Threaded()

Run SDDP in multi-threaded mode.

Use julia --threads N to start Julia with N threads. In most cases, you should pick N to be the number of physical cores on your machine.

Danger

This plug-in is experimental, and parts of SDDP.jl may not be threadsafe. If you encounter any problems or crashes, please open a GitHub issue.

Example

SDDP.train(model; parallel_scheme = SDDP.Threaded())
+SDDP.simulate(model; parallel_scheme = SDDP.Threaded())
source
SDDP.AsynchronousType
Asynchronous(
     [init_callback::Function,]
     slave_pids::Vector{Int} = workers();
     use_master::Bool = true,
-)

Run SDDP in asynchronous mode workers with pid's slave_pids.

After initializing the models on each worker, call init_callback(model). Note that init_callback is run locally on the worker and not on the master thread.

If use_master is true, iterations are also conducted on the master process.

source
Asynchronous(
+)

Run SDDP in asynchronous mode workers with pid's slave_pids.

After initializing the models on each worker, call init_callback(model). Note that init_callback is run locally on the worker and not on the master thread.

If use_master is true, iterations are also conducted on the master process.

source
Asynchronous(
     solver::Any,
     slave_pids::Vector{Int} = workers();
     use_master::Bool = true,
-)

Run SDDP in asynchronous mode workers with pid's slave_pids.

Set the optimizer on each worker by calling JuMP.set_optimizer(model, solver).

source

Forward passes

SDDP.AbstractForwardPassType
AbstractForwardPass

Abstract type for different forward passes.

source
SDDP.DefaultForwardPassType
DefaultForwardPass(; include_last_node::Bool = true)

The default forward pass.

If include_last_node = false and the sample terminated due to a cycle, then the last node (which forms the cycle) is omitted. This can be useful option to set when training, but it comes at the cost of not knowing which node formed the cycle (if there are multiple possibilities).

source
SDDP.RevisitingForwardPassType
RevisitingForwardPass(
+)

Run SDDP in asynchronous mode workers with pid's slave_pids.

Set the optimizer on each worker by calling JuMP.set_optimizer(model, solver).

source

Forward passes

SDDP.AbstractForwardPassType
AbstractForwardPass

Abstract type for different forward passes.

source
SDDP.DefaultForwardPassType
DefaultForwardPass(; include_last_node::Bool = true)

The default forward pass.

If include_last_node = false and the sample terminated due to a cycle, then the last node (which forms the cycle) is omitted. This can be useful option to set when training, but it comes at the cost of not knowing which node formed the cycle (if there are multiple possibilities).

source
SDDP.RevisitingForwardPassType
RevisitingForwardPass(
     period::Int = 500;
     sub_pass::AbstractForwardPass = DefaultForwardPass(),
-)

A forward pass scheme that generate period new forward passes (using sub_pass), then revisits all previously explored forward passes. This can be useful to encourage convergence at a diversity of points in the state-space.

Set period = typemax(Int) to disable.

For example, if period = 2, then the forward passes will be revisited as follows: 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, ....

source
SDDP.RiskAdjustedForwardPassType
RiskAdjustedForwardPass(;
+)

A forward pass scheme that generate period new forward passes (using sub_pass), then revisits all previously explored forward passes. This can be useful to encourage convergence at a diversity of points in the state-space.

Set period = typemax(Int) to disable.

For example, if period = 2, then the forward passes will be revisited as follows: 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, ....

source
SDDP.RiskAdjustedForwardPassType
RiskAdjustedForwardPass(;
     forward_pass::AbstractForwardPass,
     risk_measure::AbstractRiskMeasure,
     resampling_probability::Float64,
     rejection_count::Int = 5,
-)

A forward pass that resamples a previous forward pass with resampling_probability probability, and otherwise samples a new forward pass using forward_pass.

The forward pass to revisit is chosen based on the risk-adjusted (using risk_measure) probability of the cumulative stage objectives.

Note that this objective corresponds to the first time we visited the trajectory. Subsequent visits may have improved things, but we don't have the mechanisms in-place to update it. Therefore, remove the forward pass from resampling consideration after rejection_count revisits.

source
SDDP.AlternativeForwardPassType
AlternativeForwardPass(
+)

A forward pass that resamples a previous forward pass with resampling_probability probability, and otherwise samples a new forward pass using forward_pass.

The forward pass to revisit is chosen based on the risk-adjusted (using risk_measure) probability of the cumulative stage objectives.

Note that this objective corresponds to the first time we visited the trajectory. Subsequent visits may have improved things, but we don't have the mechanisms in-place to update it. Therefore, remove the forward pass from resampling consideration after rejection_count revisits.

source
SDDP.AlternativeForwardPassType
AlternativeForwardPass(
     forward_model::SDDP.PolicyGraph{T};
     forward_pass::AbstractForwardPass = DefaultForwardPass(),
-)

A forward pass that simulates using forward_model, which may be different to the model used in the backwards pass.

When using this forward pass, you should almost always pass SDDP.AlternativePostIterationCallback to the post_iteration_callback argument of SDDP.train.

This forward pass is most useful when the forward_model is non-convex and we use a convex approximation of the model in the backward pass.

For example, in optimal power flow models, we can use an AC-OPF formulation as the forward_model and a DC-OPF formulation as the backward model.

For more details see the paper:

Rosemberg, A., and Street, A., and Garcia, J.D., and Valladão, D.M., and Silva, T., and Dowson, O. (2021). Assessing the cost of network simplifications in long-term hydrothermal dispatch planning models. IEEE Transactions on Sustainable Energy. 13(1), 196-206.

source
SDDP.AlternativePostIterationCallbackType
AlternativePostIterationCallback(forward_model::PolicyGraph)

A post-iteration callback that should be used whenever SDDP.AlternativeForwardPass is used.

source
SDDP.RegularizedForwardPassType
RegularizedForwardPass(;
+)

A forward pass that simulates using forward_model, which may be different to the model used in the backwards pass.

When using this forward pass, you should almost always pass SDDP.AlternativePostIterationCallback to the post_iteration_callback argument of SDDP.train.

This forward pass is most useful when the forward_model is non-convex and we use a convex approximation of the model in the backward pass.

For example, in optimal power flow models, we can use an AC-OPF formulation as the forward_model and a DC-OPF formulation as the backward model.

For more details see the paper:

Rosemberg, A., and Street, A., and Garcia, J.D., and Valladão, D.M., and Silva, T., and Dowson, O. (2021). Assessing the cost of network simplifications in long-term hydrothermal dispatch planning models. IEEE Transactions on Sustainable Energy. 13(1), 196-206.

source
SDDP.AlternativePostIterationCallbackType
AlternativePostIterationCallback(forward_model::PolicyGraph)

A post-iteration callback that should be used whenever SDDP.AlternativeForwardPass is used.

source
SDDP.RegularizedForwardPassType
RegularizedForwardPass(;
     rho::Float64 = 0.05,
     forward_pass::AbstractForwardPass = DefaultForwardPass(),
-)

A forward pass that regularizes the outgoing first-stage state variables with an L-infty trust-region constraint about the previous iteration's solution. Specifically, the bounds of the outgoing state variable x are updated from (l, u) to max(l, x^k - rho * (u - l)) <= x <= min(u, x^k + rho * (u - l)), where x^k is the optimal solution of x in the previous iteration. On the first iteration, the value of the state at the root node is used.

By default, rho is set to 5%, which seems to work well empirically.

Pass a different forward_pass to control the forward pass within the regularized forward pass.

This forward pass is largely intended to be used for investment problems in which the first stage makes a series of capacity decisions that then influence the rest of the graph. An error is thrown if the first stage problem is not deterministic, and states are silently skipped if they do not have finite bounds.

source

Risk Measures

SDDP.AbstractRiskMeasureType
AbstractRiskMeasure

The abstract type for the risk measure interface.

You need to define the following methods:

source
SDDP.adjust_probabilityFunction
adjust_probability(
+)

A forward pass that regularizes the outgoing first-stage state variables with an L-infty trust-region constraint about the previous iteration's solution. Specifically, the bounds of the outgoing state variable x are updated from (l, u) to max(l, x^k - rho * (u - l)) <= x <= min(u, x^k + rho * (u - l)), where x^k is the optimal solution of x in the previous iteration. On the first iteration, the value of the state at the root node is used.

By default, rho is set to 5%, which seems to work well empirically.

Pass a different forward_pass to control the forward pass within the regularized forward pass.

This forward pass is largely intended to be used for investment problems in which the first stage makes a series of capacity decisions that then influence the rest of the graph. An error is thrown if the first stage problem is not deterministic, and states are silently skipped if they do not have finite bounds.

source

Risk Measures

SDDP.AbstractRiskMeasureType
AbstractRiskMeasure

The abstract type for the risk measure interface.

You need to define the following methods:

source
SDDP.adjust_probabilityFunction
adjust_probability(
     measure::Expectation
     risk_adjusted_probability::Vector{Float64},
     original_probability::Vector{Float64},
     noise_support::Vector{Noise{T}},
     objective_realizations::Vector{Float64},
     is_minimization::Bool,
-) where {T}
source

Duality handlers

SDDP.AbstractDualityHandlerType
AbstractDualityHandler

The abstract type for the duality handler interface.

source
SDDP.ContinuousConicDualityType
ContinuousConicDuality()

Compute dual variables in the backward pass using conic duality, relaxing any binary or integer restrictions as necessary.

Theory

Given the problem

min Cᵢ(x̄, u, w) + θᵢ
+) where {T}
source

Duality handlers

SDDP.AbstractDualityHandlerType
AbstractDualityHandler

The abstract type for the duality handler interface.

source
SDDP.ContinuousConicDualityType
ContinuousConicDuality()

Compute dual variables in the backward pass using conic duality, relaxing any binary or integer restrictions as necessary.

Theory

Given the problem

min Cᵢ(x̄, u, w) + θᵢ
  st (x̄, x′, u) in Xᵢ(w) ∩ S
     x̄ - x == 0          [λ]

where S ⊆ ℝ×ℤ, we relax integrality and using conic duality to solve for λ in the problem:

min Cᵢ(x̄, u, w) + θᵢ
  st (x̄, x′, u) in Xᵢ(w)
-    x̄ - x == 0          [λ]
source
SDDP.LagrangianDualityType
LagrangianDuality(;
+    x̄ - x == 0          [λ]
source
SDDP.LagrangianDualityType
LagrangianDuality(;
     method::LocalImprovementSearch.AbstractSearchMethod =
         LocalImprovementSearch.BFGS(100),
 )

Obtain dual variables in the backward pass using Lagrangian duality.

Arguments

  • method: the LocalImprovementSearch method for maximizing the Lagrangian dual problem.

Theory

Given the problem

min Cᵢ(x̄, u, w) + θᵢ
  st (x̄, x′, u) in Xᵢ(w) ∩ S
     x̄ - x == 0          [λ]

where S ⊆ ℝ×ℤ, we solve the problem max L(λ), where:

L(λ) = min Cᵢ(x̄, u, w) + θᵢ - λ' h(x̄)
-        st (x̄, x′, u) in Xᵢ(w) ∩ S

and where h(x̄) = x̄ - x.

source
SDDP.StrengthenedConicDualityType
StrengthenedConicDuality()

Obtain dual variables in the backward pass using strengthened conic duality.

Theory

Given the problem

min Cᵢ(x̄, u, w) + θᵢ
+        st (x̄, x′, u) in Xᵢ(w) ∩ S

and where h(x̄) = x̄ - x.

source
SDDP.StrengthenedConicDualityType
StrengthenedConicDuality()

Obtain dual variables in the backward pass using strengthened conic duality.

Theory

Given the problem

min Cᵢ(x̄, u, w) + θᵢ
  st (x̄, x′, u) in Xᵢ(w) ∩ S
     x̄ - x == 0          [λ]

we first obtain an estimate for λ using ContinuousConicDuality.

Then, we evaluate the Lagrangian function:

L(λ) = min Cᵢ(x̄, u, w) + θᵢ - λ' (x̄ - x`)
-        st (x̄, x′, u) in Xᵢ(w) ∩ S

to obtain a better estimate of the intercept.

source
SDDP.BanditDualityType
BanditDuality()

Formulates the problem of choosing a duality handler as a multi-armed bandit problem. The arms to choose between are:

Our problem isn't a typical multi-armed bandit for a two reasons:

  1. The reward distribution is non-stationary (each arm converges to 0 as it keeps getting pulled.
  2. The distribution of rewards is dependent on the history of the arms that were chosen.

We choose a very simple heuristic: pick the arm with the best mean + 1 standard deviation. That should ensure we consistently pick the arm with the best likelihood of improving the value function.

In future, we should consider discounting the rewards of earlier iterations, and focus more on the more-recent rewards.

source

Simulating the policy

SDDP.simulateFunction
simulate(
+        st (x̄, x′, u) in Xᵢ(w) ∩ S

to obtain a better estimate of the intercept.

source
SDDP.BanditDualityType
BanditDuality()

Formulates the problem of choosing a duality handler as a multi-armed bandit problem. The arms to choose between are:

Our problem isn't a typical multi-armed bandit for a two reasons:

  1. The reward distribution is non-stationary (each arm converges to 0 as it keeps getting pulled.
  2. The distribution of rewards is dependent on the history of the arms that were chosen.

We choose a very simple heuristic: pick the arm with the best mean + 1 standard deviation. That should ensure we consistently pick the arm with the best likelihood of improving the value function.

In future, we should consider discounting the rewards of earlier iterations, and focus more on the more-recent rewards.

source

Simulating the policy

SDDP.simulateFunction
simulate(
     model::PolicyGraph,
     number_replications::Int = 1,
     variables::Vector{Symbol} = Symbol[];
@@ -426,65 +426,65 @@
     custom_recorders = Dict{Symbol, Function}(
         :constraint_dual => sp -> JuMP.dual(sp[:my_constraint])
     )
-)

The value of the dual in the first stage of the second replication can be accessed as:

simulation_results[2][1][:constraint_dual]
source
SDDP.calculate_boundFunction
SDDP.calculate_bound(
+)

The value of the dual in the first stage of the second replication can be accessed as:

simulation_results[2][1][:constraint_dual]
source
SDDP.calculate_boundFunction
SDDP.calculate_bound(
     model::PolicyGraph,
     state::Dict{Symbol,Float64} = model.initial_root_state;
     risk_measure::AbstractRiskMeasure = Expectation(),
-)

Calculate the lower bound (if minimizing, otherwise upper bound) of the problem model at the point state, assuming the risk measure at the root node is risk_measure.

source
SDDP.add_all_cutsFunction
add_all_cuts(model::PolicyGraph)

Add all cuts that may have been deleted back into the model.

Explanation

During the solve, SDDP.jl may decide to remove cuts for a variety of reasons.

These can include cuts that define the optimal value function, particularly around the extremes of the state-space (e.g., reservoirs empty).

This function ensures that all cuts discovered are added back into the model.

You should call this after train and before simulate.

source

Decision rules

SDDP.DecisionRuleType
DecisionRule(model::PolicyGraph{T}; node::T)

Create a decision rule for node node in model.

Example

rule = SDDP.DecisionRule(model; node = 1)
source
SDDP.evaluateFunction
evaluate(
+)

Calculate the lower bound (if minimizing, otherwise upper bound) of the problem model at the point state, assuming the risk measure at the root node is risk_measure.

source
SDDP.add_all_cutsFunction
add_all_cuts(model::PolicyGraph)

Add all cuts that may have been deleted back into the model.

Explanation

During the solve, SDDP.jl may decide to remove cuts for a variety of reasons.

These can include cuts that define the optimal value function, particularly around the extremes of the state-space (e.g., reservoirs empty).

This function ensures that all cuts discovered are added back into the model.

You should call this after train and before simulate.

source

Decision rules

SDDP.DecisionRuleType
DecisionRule(model::PolicyGraph{T}; node::T)

Create a decision rule for node node in model.

Example

rule = SDDP.DecisionRule(model; node = 1)
source
SDDP.evaluateFunction
evaluate(
     rule::DecisionRule;
     incoming_state::Dict{Symbol,Float64},
     noise = nothing,
     controls_to_record = Symbol[],
-)

Evalute the decision rule rule at the point described by the incoming_state and noise.

If the node is deterministic, omit the noise argument.

Pass a list of symbols to controls_to_record to save the optimal primal solution corresponding to the names registered in the model.

source
evaluate(
+)

Evalute the decision rule rule at the point described by the incoming_state and noise.

If the node is deterministic, omit the noise argument.

Pass a list of symbols to controls_to_record to save the optimal primal solution corresponding to the names registered in the model.

source
evaluate(
     V::ValueFunction,
     point::Dict{Union{Symbol,String},<:Real}
     objective_state = nothing,
     belief_state = nothing
-)

Evaluate the value function V at point in the state-space.

Returns a tuple containing the height of the function, and the subgradient w.r.t. the convex state-variables.

Examples

evaluate(V, Dict(:volume => 1.0))

If the state variable is constructed like @variable(sp, volume[1:4] >= 0, SDDP.State, initial_value = 0.0), use [i] to index the state variable:

evaluate(V, Dict(Symbol("volume[1]") => 1.0))

You can also use strings or symbols for the keys.

evaluate(V, Dict("volume[1]" => 1))
source
evalute(V::ValueFunction{Nothing, Nothing}; kwargs...)

Evalute the value function V at the point in the state-space specified by kwargs.

Examples

evaluate(V; volume = 1)
source
evaluate(
+)

Evaluate the value function V at point in the state-space.

Returns a tuple containing the height of the function, and the subgradient w.r.t. the convex state-variables.

Examples

evaluate(V, Dict(:volume => 1.0))

If the state variable is constructed like @variable(sp, volume[1:4] >= 0, SDDP.State, initial_value = 0.0), use [i] to index the state variable:

evaluate(V, Dict(Symbol("volume[1]") => 1.0))

You can also use strings or symbols for the keys.

evaluate(V, Dict("volume[1]" => 1))
source
evalute(V::ValueFunction{Nothing, Nothing}; kwargs...)

Evalute the value function V at the point in the state-space specified by kwargs.

Examples

evaluate(V; volume = 1)
source
evaluate(
     model::PolicyGraph{T},
     validation_scenarios::ValidationScenarios{T,S},
 ) where {T,S}

Evaluate the performance of the policy contained in model after a call to train on the scenarios specified by validation_scenarios.

Examples

model, validation_scenarios = read_from_file("my_model.sof.json")
 train(model; iteration_limit = 100)
-simulations = evaluate(model, validation_scenarios)
source

Visualizing the policy

SDDP.SpaghettiPlotType
SDDP.SpaghettiPlot(; stages, scenarios)

Initialize a new SpaghettiPlot with stages stages and scenarios number of replications.

source
SDDP.add_spaghettiFunction
SDDP.add_spaghetti(data_function::Function, plt::SpaghettiPlot; kwargs...)

Description

Add a new figure to the SpaghettiPlot plt, where the y-value of the scenarioth line when x = stage is given by data_function(plt.simulations[scenario][stage]).

Keyword arguments

  • xlabel: set the xaxis label
  • ylabel: set the yaxis label
  • title: set the title of the plot
  • ymin: set the minimum y value
  • ymax: set the maximum y value
  • cumulative: plot the additive accumulation of the value across the stages
  • interpolate: interpolation method for lines between stages.

Defaults to "linear" see the d3 docs for all options.

Examples

simulations = simulate(model, 10)
+simulations = evaluate(model, validation_scenarios)
source

Visualizing the policy

SDDP.SpaghettiPlotType
SDDP.SpaghettiPlot(; stages, scenarios)

Initialize a new SpaghettiPlot with stages stages and scenarios number of replications.

source
SDDP.add_spaghettiFunction
SDDP.add_spaghetti(data_function::Function, plt::SpaghettiPlot; kwargs...)

Description

Add a new figure to the SpaghettiPlot plt, where the y-value of the scenarioth line when x = stage is given by data_function(plt.simulations[scenario][stage]).

Keyword arguments

  • xlabel: set the xaxis label
  • ylabel: set the yaxis label
  • title: set the title of the plot
  • ymin: set the minimum y value
  • ymax: set the maximum y value
  • cumulative: plot the additive accumulation of the value across the stages
  • interpolate: interpolation method for lines between stages.

Defaults to "linear" see the d3 docs for all options.

Examples

simulations = simulate(model, 10)
 plt = SDDP.spaghetti_plot(simulations)
 SDDP.add_spaghetti(plt; title = "Stage objective") do data
     return data[:stage_objective]
-end
source
SDDP.publication_plotFunction
SDDP.publication_plot(
+end
source
SDDP.publication_plotFunction
SDDP.publication_plot(
     data_function, simulations;
     quantile = [0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0],
     kwargs...)

Create a Plots.jl recipe plot of the simulations.

See Plots.jl for the list of keyword arguments.

Examples

SDDP.publication_plot(simulations; title = "My title") do data
     return data[:stage_objective]
-end
source
SDDP.ValueFunctionType
ValueFunction

A representation of the value function. SDDP.jl uses the following unique representation of the value function that is undocumented in the literature.

It supports three types of state variables:

  1. x - convex "resource" states
  2. b - concave "belief" states
  3. y - concave "objective" states

In addition, we have three types of cuts:

  1. Single-cuts (also called "average" cuts in the literature), which involve the risk-adjusted expectation of the cost-to-go.
  2. Multi-cuts, which use a different cost-to-go term for each realization w.
  3. Risk-cuts, which correspond to the facets of the dual interpretation of a coherent risk measure.

Therefore, ValueFunction returns a JuMP model of the following form:

V(x, b, y) = min: μᵀb + νᵀy + θ
+end
source
SDDP.ValueFunctionType
ValueFunction

A representation of the value function. SDDP.jl uses the following unique representation of the value function that is undocumented in the literature.

It supports three types of state variables:

  1. x - convex "resource" states
  2. b - concave "belief" states
  3. y - concave "objective" states

In addition, we have three types of cuts:

  1. Single-cuts (also called "average" cuts in the literature), which involve the risk-adjusted expectation of the cost-to-go.
  2. Multi-cuts, which use a different cost-to-go term for each realization w.
  3. Risk-cuts, which correspond to the facets of the dual interpretation of a coherent risk measure.

Therefore, ValueFunction returns a JuMP model of the following form:

V(x, b, y) = min: μᵀb + νᵀy + θ
              s.t. # "Single" / "Average" cuts
                   μᵀb(j) + νᵀy(j) + θ >= α(j) + xᵀβ(j), ∀ j ∈ J
                   # "Multi" cuts
                   μᵀb(k) + νᵀy(k) + φ(w) >= α(k, w) + xᵀβ(k, w), ∀w ∈ Ω, k ∈ K
                   # "Risk-set" cuts
-                  θ ≥ Σ{p(k, w) * φ(w)}_w - μᵀb(k) - νᵀy(k), ∀ k ∈ K
source
SDDP.evaluateMethod
evaluate(
+                  θ ≥ Σ{p(k, w) * φ(w)}_w - μᵀb(k) - νᵀy(k), ∀ k ∈ K
source
SDDP.evaluateMethod
evaluate(
     V::ValueFunction,
     point::Dict{Union{Symbol,String},<:Real}
     objective_state = nothing,
     belief_state = nothing
-)

Evaluate the value function V at point in the state-space.

Returns a tuple containing the height of the function, and the subgradient w.r.t. the convex state-variables.

Examples

evaluate(V, Dict(:volume => 1.0))

If the state variable is constructed like @variable(sp, volume[1:4] >= 0, SDDP.State, initial_value = 0.0), use [i] to index the state variable:

evaluate(V, Dict(Symbol("volume[1]") => 1.0))

You can also use strings or symbols for the keys.

evaluate(V, Dict("volume[1]" => 1))
source
SDDP.plotFunction
plot(plt::SpaghettiPlot[, filename::String]; open::Bool = true)

The SpaghettiPlot plot plt to filename. If filename is not given, it will be saved to a temporary directory. If open = true, then a browser window will be opened to display the resulting HTML file.

source

Debugging the model

SDDP.write_subproblem_to_fileFunction
write_subproblem_to_file(
+)

Evaluate the value function V at point in the state-space.

Returns a tuple containing the height of the function, and the subgradient w.r.t. the convex state-variables.

Examples

evaluate(V, Dict(:volume => 1.0))

If the state variable is constructed like @variable(sp, volume[1:4] >= 0, SDDP.State, initial_value = 0.0), use [i] to index the state variable:

evaluate(V, Dict(Symbol("volume[1]") => 1.0))

You can also use strings or symbols for the keys.

evaluate(V, Dict("volume[1]" => 1))
source
SDDP.plotFunction
plot(plt::SpaghettiPlot[, filename::String]; open::Bool = true)

The SpaghettiPlot plot plt to filename. If filename is not given, it will be saved to a temporary directory. If open = true, then a browser window will be opened to display the resulting HTML file.

source

Debugging the model

SDDP.write_subproblem_to_fileFunction
write_subproblem_to_file(
     node::Node,
     filename::String;
     throw_error::Bool = false,
-)

Write the subproblem contained in node to the file filename.

The throw_error is an argument used internally by SDDP.jl. If set, an error will be thrown.

Example

SDDP.write_subproblem_to_file(model[1], "subproblem_1.lp")
source
SDDP.deterministic_equivalentFunction
deterministic_equivalent(
+)

Write the subproblem contained in node to the file filename.

The throw_error is an argument used internally by SDDP.jl. If set, an error will be thrown.

Example

SDDP.write_subproblem_to_file(model[1], "subproblem_1.lp")
source
SDDP.deterministic_equivalentFunction
deterministic_equivalent(
     pg::PolicyGraph{T},
     optimizer = nothing;
     time_limit::Union{Real,Nothing} = 60.0,
-)

Form a JuMP model that represents the deterministic equivalent of the problem.

Examples

deterministic_equivalent(model)
deterministic_equivalent(model, HiGHS.Optimizer)
source

StochOptFormat

SDDP.write_to_fileFunction
write_to_file(
+)

Form a JuMP model that represents the deterministic equivalent of the problem.

Examples

deterministic_equivalent(model)
deterministic_equivalent(model, HiGHS.Optimizer)
source

StochOptFormat

SDDP.write_to_fileFunction
write_to_file(
     model::PolicyGraph,
     filename::String;
     compression::MOI.FileFormats.AbstractCompressionScheme =
         MOI.FileFormats.AutomaticCompression(),
     kwargs...
-)

Write model to filename in the StochOptFormat file format.

Pass an argument to compression to override the default of automatically detecting the file compression to use based on the extension of filename.

See Base.write(::IO, ::PolicyGraph) for information on the keyword arguments that can be provided.

Warning

This function is experimental. See the full warning in Base.write(::IO, ::PolicyGraph).

Examples

write_to_file(model, "my_model.sof.json"; validation_scenarios = 10)
source
SDDP.read_from_fileFunction
read_from_file(
+)

Write model to filename in the StochOptFormat file format.

Pass an argument to compression to override the default of automatically detecting the file compression to use based on the extension of filename.

See Base.write(::IO, ::PolicyGraph) for information on the keyword arguments that can be provided.

Warning

This function is experimental. See the full warning in Base.write(::IO, ::PolicyGraph).

Examples

write_to_file(model, "my_model.sof.json"; validation_scenarios = 10)
source
SDDP.read_from_fileFunction
read_from_file(
     filename::String;
     compression::MOI.FileFormats.AbstractCompressionScheme =
         MOI.FileFormats.AutomaticCompression(),
     kwargs...
-)::Tuple{PolicyGraph, ValidationScenarios}

Return a tuple containing a PolicyGraph object and a ValidationScenarios read from filename in the StochOptFormat file format.

Pass an argument to compression to override the default of automatically detecting the file compression to use based on the extension of filename.

See Base.read(::IO, ::Type{PolicyGraph}) for information on the keyword arguments that can be provided.

Warning

This function is experimental. See the full warning in Base.read(::IO, ::Type{PolicyGraph}).

Examples

model, validation_scenarios = read_from_file("my_model.sof.json")
source
Base.writeMethod
Base.write(
+)::Tuple{PolicyGraph, ValidationScenarios}

Return a tuple containing a PolicyGraph object and a ValidationScenarios read from filename in the StochOptFormat file format.

Pass an argument to compression to override the default of automatically detecting the file compression to use based on the extension of filename.

See Base.read(::IO, ::Type{PolicyGraph}) for information on the keyword arguments that can be provided.

Warning

This function is experimental. See the full warning in Base.read(::IO, ::Type{PolicyGraph}).

Examples

model, validation_scenarios = read_from_file("my_model.sof.json")
source
Base.writeMethod
Base.write(
     io::IO,
     model::PolicyGraph;
     validation_scenarios::Union{Nothing,Int,ValidationScenarios} = nothing,
@@ -500,15 +500,15 @@
         date = "2020-07-20",
         description = "Example problem for the SDDP.jl documentation",
     )
-end
source
Base.readMethod
Base.read(
+end
source
Base.readMethod
Base.read(
     io::IO,
     ::Type{PolicyGraph};
     bound::Float64 = 1e6,
 )::Tuple{PolicyGraph,ValidationScenarios}

Return a tuple containing a PolicyGraph object and a ValidationScenarios read from io in the StochOptFormat file format.

See also: evaluate.

Compatibility

Warning

This function is experimental. Things may change between commits. You should not rely on this functionality as a long-term file format (yet).

In addition to potential changes to the underlying format, only a subset of possible modifications are supported. These include:

  • Additive random variables in the constraints or in the objective
  • Multiplicative random variables in the objective

If your model uses something other than this, this function may throw an error or silently build a non-convex model.

Examples

open("my_model.sof.json", "r") do io
     model, validation_scenarios = read(io, PolicyGraph)
-end
source
SDDP.evaluateMethod
evaluate(
+end
source
SDDP.evaluateMethod
evaluate(
     model::PolicyGraph{T},
     validation_scenarios::ValidationScenarios{T,S},
 ) where {T,S}

Evaluate the performance of the policy contained in model after a call to train on the scenarios specified by validation_scenarios.

Examples

model, validation_scenarios = read_from_file("my_model.sof.json")
 train(model; iteration_limit = 100)
-simulations = evaluate(model, validation_scenarios)
source
SDDP.ValidationScenariosType
ValidationScenario{T,S}(scenarios::Vector{ValidationScenario{T,S}})

An AbstractSamplingScheme based on a vector of scenarios.

Each scenario is a vector of Tuple{T, S} where the first element is the node to visit and the second element is the realization of the stagewise-independent noise term. Pass nothing if the node is deterministic.

source
SDDP.ValidationScenarioType
ValidationScenario{T,S}(scenario::Vector{Tuple{T,S}})

A single scenario for testing.

See also: ValidationScenarios.

source
+simulations = evaluate(model, validation_scenarios)source
SDDP.ValidationScenariosType
ValidationScenario{T,S}(scenarios::Vector{ValidationScenario{T,S}})

An AbstractSamplingScheme based on a vector of scenarios.

Each scenario is a vector of Tuple{T, S} where the first element is the node to visit and the second element is the realization of the stagewise-independent noise term. Pass nothing if the node is deterministic.

source
SDDP.ValidationScenarioType
ValidationScenario{T,S}(scenario::Vector{Tuple{T,S}})

A single scenario for testing.

See also: ValidationScenarios.

source
diff --git a/previews/PR811/changelog/index.html b/previews/PR811/changelog/index.html index 89651c7c8..58983376a 100644 --- a/previews/PR811/changelog/index.html +++ b/previews/PR811/changelog/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-HZQQDVMPZW', {'page_path': location.pathname + location.search + location.hash}); -

Release notes

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

v1.10.1 (November 28, 2024)

Fixed

Other

  • Documentation updates (#801)

v1.10.0 (November 19, 2024)

Added

  • Added root_node_risk_measure keyword to train (#804)

Fixed

  • Fixed a bug with cut sharing in a graph with zero-probability arcs (#797)

Other

v1.9.0 (October 17, 2024)

Added

Fixed

  • Fixed the tests to skip threading tests if running in serial (#770)
  • Fixed BanditDuality to handle the case where the standard deviation is NaN (#779)
  • Fixed an error when lagged state variables are encountered in MSPFormat (#786)
  • Fixed publication_plot with replications of different lengths (#788)
  • Fixed CTRL+C interrupting the code at unsafe points (#789)

Other

  • Documentation improvements (#771) (#772)
  • Updated printing because of changes in JuMP (#773)

v1.8.1 (August 5, 2024)

Fixed

  • Fixed various issues with SDDP.Threaded() (#761)
  • Fixed a deprecation warning for sorting a dictionary (#763)

Other

  • Updated copyright notices (#762)
  • Updated .JuliaFormatter.toml (#764)

v1.8.0 (July 24, 2024)

Added

  • Added SDDP.Threaded(), which is an experimental parallel scheme that supports solving problems using multiple threads. Some parts of SDDP.jl may not be thread-safe, and this can cause incorrect results, segfaults, or other errors. Please use with care and report any issues by opening a GitHub issue. (#758)

Other

  • Documentation improvements and fixes (#747) (#759)

v1.7.0 (June 4, 2024)

Added

  • Added sample_backward_noise_terms_with_state for creating backward pass sampling schemes that depend on the current primal state. (#742) (Thanks @arthur-brigatto)

Fixed

  • Fixed error message when publication_plot has non-finite data (#738)

Other

  • Updated the logo constructor (#730)

v1.6.7 (February 1, 2024)

Fixed

  • Fixed non-constant state dimension in the MSPFormat reader (#695)
  • Fixed SimulatorSamplingScheme for deterministic nodes (#710)
  • Fixed line search in BFGS (#711)
  • Fixed handling of NEARLY_FEASIBLE_POINT status (#726)

Other

  • Documentation improvements (#692) (#694) (#706) (#716) (#727)
  • Updated to StochOptFormat v1.0 (#705)
  • Added an experimental OuterApproximation algorithm (#709)
  • Updated .gitignore (#717)
  • Added code for MDP paper (#720) (#721)
  • Added Google analytics (#723)

v1.6.6 (September 29, 2023)

Other

v1.6.5 (September 25, 2023)

Fixed

Other

  • Updated tutorials (#677) (#678) (#682) (#683)
  • Fixed documentation preview (#679)

v1.6.4 (September 23, 2023)

Fixed

Other

  • Documentation updates (#658) (#666) (#671)
  • Switch to GitHub action for deploying docs (#668) (#670)
  • Update to Documenter@1 (#669)

v1.6.3 (September 8, 2023)

Fixed

  • Fixed default stopping rule with iteration_limit or time_limit set (#662)

Other

  • Various documentation improvements (#651) (#657) (#659) (#660)

v1.6.2 (August 24, 2023)

Fixed

  • MSPFormat now detect and exploit stagewise independent lattices (#653)
  • Fixed set_optimizer for models read from file (#654)

Other

  • Fixed typo in pglib_opf.jl (#647)
  • Fixed documentation build and added color (#652)

v1.6.1 (July 20, 2023)

Fixed

  • Fixed bugs in MSPFormat reader (#638) (#639)

Other

  • Clarified OutOfSampleMonteCarlo docstring (#643)

v1.6.0 (July 3, 2023)

Added

Other

v1.5.1 (June 30, 2023)

This release contains a number of minor code changes, but it has a large impact on the content that is printed to screen. In particular, we now log periodically, instead of each iteration, and a "good" stopping rule is used as the default if none are specified. Try using SDDP.train(model) to see the difference.

Other

  • Fixed various typos in the documentation (#617)
  • Fixed printing test after changes in JuMP (#618)
  • Set SimulationStoppingRule as the default stopping rule (#619)
  • Changed the default logging frequency. Pass log_every_seconds = 0.0 to train to revert to the old behavior. (#620)
  • Added example usage with Distributions.jl (@slwu89) (#622)
  • Removed the numerical issue @warn (#627)
  • Improved the quality of docstrings (#630)

v1.5.0 (May 14, 2023)

Added

  • Added the ability to use a different model for the forward pass. This is a novel feature that lets you train better policies when the model is non-convex or does not have a well-defined dual. See the Alternative forward models tutorial in which we train convex and non-convex formulations of the optimal power flow problem. (#611)

Other

  • Updated missing changelog entries (#608)
  • Removed global variables (#610)
  • Converted the Options struct to keyword arguments. This struct was a private implementation detail, but the change is breaking if you developed an extension to SDDP that touched these internals. (#612)
  • Fixed some typos (#613)

v1.4.0 (May 8, 2023)

Added

Fixed

  • Fixed parsing of some MSPFormat files (#602) (#604)
  • Fixed printing in header (#605)

v1.3.0 (May 3, 2023)

Added

  • Added experimental support for SDDP.MSPFormat.read_from_file (#593)

Other

  • Updated to StochOptFormat v0.3 (#600)

v1.2.1 (May 1, 2023)

Fixed

  • Fixed log_every_seconds (#597)

v1.2.0 (May 1, 2023)

Added

Other

  • Tweaked how the log is printed (#588)
  • Updated to StochOptFormat v0.2 (#592)

v1.1.4 (April 10, 2023)

Fixed

  • Logs are now flushed every iteration (#584)

Other

  • Added docstrings to various functions (#581)
  • Minor documentation updates (#580)
  • Clarified integrality documentation (#582)
  • Updated the README (#585)
  • Number of numerical issues is now printed to the log (#586)

v1.1.3 (April 2, 2023)

Other

v1.1.2 (March 18, 2023)

Other

v1.1.1 (March 16, 2023)

Other

  • Fixed email in Project.toml
  • Added notebook to documentation tutorials (#571)

v1.1.0 (January 12, 2023)

Added

v1.0.0 (January 3, 2023)

Although we're bumping MAJOR version, this is a non-breaking release. Going forward:

  • New features will bump the MINOR version
  • Bug fixes, maintenance, and documentation updates will bump the PATCH version
  • We will support only the Long Term Support (currently v1.6.7) and the latest patch (currently v1.8.4) releases of Julia. Updates to the LTS version will bump the MINOR version
  • Updates to the compat bounds of package dependencies will bump the PATCH version.

We do not intend any breaking changes to the public API, which would require a new MAJOR release. The public API is everything defined in the documentation. Anything not in the documentation is considered private and may change in any PATCH release.

Added

Other

  • Updated Plotting tools to use live plots (#563)
  • Added vale as a linter (#565)
  • Improved documentation for initializing a parallel scheme (#566)

v0.4.9 (January 3, 2023)

Added

Other

  • Added tutorial on Markov Decision Processes (#556)
  • Added two-stage newsvendor tutorial (#557)
  • Refactored the layout of the documentation (#554) (#555)
  • Updated copyright to 2023 (#558)
  • Fixed errors in the documentation (#561)

v0.4.8 (December 19, 2022)

Added

Fixed

  • Reverted then fixed (#531) because it failed to account for problems with integer variables (#546) (#551)

v0.4.7 (December 17, 2022)

Added

  • Added initial_node support to InSampleMonteCarlo and OutOfSampleMonteCarlo (#535)

Fixed

  • Rethrow InterruptException when solver is interrupted (#534)
  • Fixed numerical recovery when we need dual solutions (#531) (Thanks @bfpc)
  • Fixed re-using the dashboard = true option between solves (#538)
  • Fixed bug when no @stageobjective is set (now defaults to 0.0) (#539)
  • Fixed errors thrown when invalid inputs are provided to add_objective_state (#540)

Other

  • Drop support for Julia versions prior to 1.6 (#533)
  • Updated versions of dependencies (#522) (#533)
  • Switched to HiGHS in the documentation and tests (#533)
  • Added license headers (#519)
  • Fixed link in air conditioning example (#521) (Thanks @conema)
  • Clarified variable naming in deterministic equivalent (#525) (Thanks @lucasprocessi)
  • Added this change log (#536)
  • Cuts are now written to model.cuts.json when numerical instability is discovered. This can aid debugging because it allows to you reload the cuts as of the iteration that caused the numerical issue (#537)

v0.4.6 (March 25, 2022)

Other

  • Updated to JuMP v1.0 (#517)

v0.4.5 (March 9, 2022)

Fixed

  • Fixed issue with set_silent in a subproblem (#510)

Other

  • Fixed many typos (#500) (#501) (#506) (#511) (Thanks @bfpc)
  • Update to JuMP v0.23 (#514)
  • Added auto-regressive tutorial (#507)

v0.4.4 (December 11, 2021)

Added

  • Added BanditDuality (#471)
  • Added benchmark scripts (#475) (#476) (#490)
  • write_cuts_to_file now saves visited states (#468)

Fixed

  • Fixed BoundStalling in a deterministic policy (#470) (#474)
  • Fixed magnitude warning with zero coefficients (#483)

Other

  • Improvements to LagrangianDuality (#481) (#482) (#487)
  • Improvements to StrengthenedConicDuality (#486)
  • Switch to functional form for the tests (#478)
  • Fixed typos (#472) (Thanks @vfdev-5)
  • Update to JuMP v0.22 (#498)

v0.4.3 (August 31, 2021)

Added

  • Added biobjective solver (#462)
  • Added forward_pass_callback (#466)

Other

  • Update tutorials and documentation (#459) (#465)
  • Organize how paper materials are stored (#464)

v0.4.2 (August 24, 2021)

Fixed

  • Fixed a bug in Lagrangian duality (#457)

v0.4.1 (August 23, 2021)

Other

  • Minor changes to our implementation of LagrangianDuality (#454) (#455)

v0.4.0 (August 17, 2021)

Breaking

  • A large refactoring for how we handle stochastic integer programs. This added support for things like SDDP.ContinuousConicDuality and SDDP.LagrangianDuality. It was breaking because we removed the integrality_handler argument to PolicyGraph. (#449) (#453)

Other

  • Documentation improvements (#447) (#448) (#450)

v0.3.17 (July 6, 2021)

Added

Other

  • Display more model attributes (#438)
  • Documentation improvements (#433) (#437) (#439)

v0.3.16 (June 17, 2021)

Added

Other

  • Update risk measure docstrings (#418)

v0.3.15 (June 1, 2021)

Added

Fixed

  • Fixed scoping bug in SDDP.@stageobjective (#407)
  • Fixed a bug when the initial point is infeasible (#411)
  • Set subproblems to silent by default (#409)

Other

  • Add JuliaFormatter (#412)
  • Documentation improvements (#406) (#408)

v0.3.14 (March 30, 2021)

Fixed

  • Fixed O(N^2) behavior in get_same_children (#393)

v0.3.13 (March 27, 2021)

Fixed

  • Fixed bug in print.jl
  • Fixed compat of Reexport (#388)

v0.3.12 (March 22, 2021)

Added

  • Added problem statistics to header (#385) (#386)

Fixed

  • Fixed subtypes in visualization (#384)

v0.3.11 (March 22, 2021)

Fixed

  • Fixed constructor in direct mode (#383)

Other

  • Fix documentation (#379)

v0.3.10 (February 23, 2021)

Fixed

  • Fixed seriescolor in publication plot (#376)

v0.3.9 (February 20, 2021)

Added

  • Add option to simulate with different incoming state (#372)
  • Added warning for cuts with high dynamic range (#373)

Fixed

  • Fixed seriesalpha in publication plot (#375)

v0.3.8 (January 19, 2021)

Other

  • Documentation improvements (#367) (#369) (#370)

v0.3.7 (January 8, 2021)

Other

  • Documentation improvements (#362) (#363) (#365) (#366)
  • Bump copyright (#364)

v0.3.6 (December 17, 2020)

Other

  • Fix typos (#358)
  • Collapse navigation bar in docs (#359)
  • Update TagBot.yml (#361)

v0.3.5 (November 18, 2020)

Other

  • Update citations (#348)
  • Switch to GitHub actions (#355)

v0.3.4 (August 25, 2020)

Added

  • Added non-uniform distributionally robust risk measure (#328)
  • Added numerical recovery functions (#330)
  • Added experimental StochOptFormat (#332) (#336) (#337) (#341) (#343) (#344)
  • Added entropic risk measure (#347)

Other

  • Documentation improvements (#327) (#333) (#339) (#340)

v0.3.3 (June 19, 2020)

Added

  • Added asynchronous support for price and belief states (#325)
  • Added ForwardPass plug-in system (#320)

Fixed

  • Fix check for probabilities in Markovian graph (#322)

v0.3.2 (April 6, 2020)

Added

Other

  • Improve error message in deterministic equivalent (#312)
  • Update to RecipesBase 1.0 (#313)

v0.3.1 (February 26, 2020)

Fixed

  • Fixed filename in integrality_handlers.jl (#304)

v0.3.0 (February 20, 2020)

Breaking

  • Breaking changes to update to JuMP v0.21 (#300).

v0.2.4 (February 7, 2020)

Added

  • Added a counter for the number of total subproblem solves (#301)

Other

  • Update formatter (#298)
  • Added tests (#299)

v0.2.3 (January 24, 2020)

Added

  • Added support for convex risk measures (#294)

Fixed

  • Fixed bug when subproblem is infeasible (#296)
  • Fixed bug in deterministic equivalent (#297)

Other

  • Added example from IJOC paper (#293)

v0.2.2 (January 10, 2020)

Fixed

  • Fixed flakey time limit in tests (#291)

Other

  • Removed MathOptFormat.jl (#289)
  • Update copyright (#290)

v0.2.1 (December 19, 2019)

Added

  • Added support for approximating a Markov lattice (#282) (#285)
  • Add tools for visualizing the value function (#272) (#286)
  • Write .mof.json files on error (#284)

Other

  • Improve documentation (#281) (#283)
  • Update tests for Julia 1.3 (#287)

v0.2.0 (December 16, 2019)

This version added the asynchronous parallel implementation with a few minor breaking changes in how we iterated internally. It didn't break basic user-facing models, only implementations that implemented some of the extension features. It probably could have been a v1.1 release.

Added

  • Added asynchronous parallel implementation (#277)
  • Added roll-out algorithm for cyclic graphs (#279)

Other

  • Improved error messages in PolicyGraph (#271)
  • Added JuliaFormatter (#273) (#276)
  • Fixed compat bounds (#274) (#278)
  • Added documentation for simulating non-standard graphs (#280)

v0.1.0 (October 17, 2019)

A complete rewrite of SDDP.jl based on the policy graph framework. This was essentially a new package. It has minimal code in common with the previous implementation.

Development started on September 28, 2018 in Kokako.jl, and the code was merged into SDDP.jl on March 14, 2019.

The pull request SDDP.jl#180 lists the 29 issues that the rewrite closed.

v0.0.1 (April 18, 2018)

Initial release. Development had been underway since January 22, 2016 in the StochDualDynamicProgram.jl repository. The last development commit there was April 5, 2017. Work then continued in this repository for a year before the first tagged release.

+

Release notes

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

v1.10.1 (November 28, 2024)

Fixed

Other

  • Documentation updates (#801)

v1.10.0 (November 19, 2024)

Added

  • Added root_node_risk_measure keyword to train (#804)

Fixed

  • Fixed a bug with cut sharing in a graph with zero-probability arcs (#797)

Other

v1.9.0 (October 17, 2024)

Added

Fixed

  • Fixed the tests to skip threading tests if running in serial (#770)
  • Fixed BanditDuality to handle the case where the standard deviation is NaN (#779)
  • Fixed an error when lagged state variables are encountered in MSPFormat (#786)
  • Fixed publication_plot with replications of different lengths (#788)
  • Fixed CTRL+C interrupting the code at unsafe points (#789)

Other

  • Documentation improvements (#771) (#772)
  • Updated printing because of changes in JuMP (#773)

v1.8.1 (August 5, 2024)

Fixed

  • Fixed various issues with SDDP.Threaded() (#761)
  • Fixed a deprecation warning for sorting a dictionary (#763)

Other

  • Updated copyright notices (#762)
  • Updated .JuliaFormatter.toml (#764)

v1.8.0 (July 24, 2024)

Added

  • Added SDDP.Threaded(), which is an experimental parallel scheme that supports solving problems using multiple threads. Some parts of SDDP.jl may not be thread-safe, and this can cause incorrect results, segfaults, or other errors. Please use with care and report any issues by opening a GitHub issue. (#758)

Other

  • Documentation improvements and fixes (#747) (#759)

v1.7.0 (June 4, 2024)

Added

  • Added sample_backward_noise_terms_with_state for creating backward pass sampling schemes that depend on the current primal state. (#742) (Thanks @arthur-brigatto)

Fixed

  • Fixed error message when publication_plot has non-finite data (#738)

Other

  • Updated the logo constructor (#730)

v1.6.7 (February 1, 2024)

Fixed

  • Fixed non-constant state dimension in the MSPFormat reader (#695)
  • Fixed SimulatorSamplingScheme for deterministic nodes (#710)
  • Fixed line search in BFGS (#711)
  • Fixed handling of NEARLY_FEASIBLE_POINT status (#726)

Other

  • Documentation improvements (#692) (#694) (#706) (#716) (#727)
  • Updated to StochOptFormat v1.0 (#705)
  • Added an experimental OuterApproximation algorithm (#709)
  • Updated .gitignore (#717)
  • Added code for MDP paper (#720) (#721)
  • Added Google analytics (#723)

v1.6.6 (September 29, 2023)

Other

v1.6.5 (September 25, 2023)

Fixed

Other

  • Updated tutorials (#677) (#678) (#682) (#683)
  • Fixed documentation preview (#679)

v1.6.4 (September 23, 2023)

Fixed

Other

  • Documentation updates (#658) (#666) (#671)
  • Switch to GitHub action for deploying docs (#668) (#670)
  • Update to Documenter@1 (#669)

v1.6.3 (September 8, 2023)

Fixed

  • Fixed default stopping rule with iteration_limit or time_limit set (#662)

Other

  • Various documentation improvements (#651) (#657) (#659) (#660)

v1.6.2 (August 24, 2023)

Fixed

  • MSPFormat now detect and exploit stagewise independent lattices (#653)
  • Fixed set_optimizer for models read from file (#654)

Other

  • Fixed typo in pglib_opf.jl (#647)
  • Fixed documentation build and added color (#652)

v1.6.1 (July 20, 2023)

Fixed

  • Fixed bugs in MSPFormat reader (#638) (#639)

Other

  • Clarified OutOfSampleMonteCarlo docstring (#643)

v1.6.0 (July 3, 2023)

Added

Other

v1.5.1 (June 30, 2023)

This release contains a number of minor code changes, but it has a large impact on the content that is printed to screen. In particular, we now log periodically, instead of each iteration, and a "good" stopping rule is used as the default if none are specified. Try using SDDP.train(model) to see the difference.

Other

  • Fixed various typos in the documentation (#617)
  • Fixed printing test after changes in JuMP (#618)
  • Set SimulationStoppingRule as the default stopping rule (#619)
  • Changed the default logging frequency. Pass log_every_seconds = 0.0 to train to revert to the old behavior. (#620)
  • Added example usage with Distributions.jl (@slwu89) (#622)
  • Removed the numerical issue @warn (#627)
  • Improved the quality of docstrings (#630)

v1.5.0 (May 14, 2023)

Added

  • Added the ability to use a different model for the forward pass. This is a novel feature that lets you train better policies when the model is non-convex or does not have a well-defined dual. See the Alternative forward models tutorial in which we train convex and non-convex formulations of the optimal power flow problem. (#611)

Other

  • Updated missing changelog entries (#608)
  • Removed global variables (#610)
  • Converted the Options struct to keyword arguments. This struct was a private implementation detail, but the change is breaking if you developed an extension to SDDP that touched these internals. (#612)
  • Fixed some typos (#613)

v1.4.0 (May 8, 2023)

Added

Fixed

  • Fixed parsing of some MSPFormat files (#602) (#604)
  • Fixed printing in header (#605)

v1.3.0 (May 3, 2023)

Added

  • Added experimental support for SDDP.MSPFormat.read_from_file (#593)

Other

  • Updated to StochOptFormat v0.3 (#600)

v1.2.1 (May 1, 2023)

Fixed

  • Fixed log_every_seconds (#597)

v1.2.0 (May 1, 2023)

Added

Other

  • Tweaked how the log is printed (#588)
  • Updated to StochOptFormat v0.2 (#592)

v1.1.4 (April 10, 2023)

Fixed

  • Logs are now flushed every iteration (#584)

Other

  • Added docstrings to various functions (#581)
  • Minor documentation updates (#580)
  • Clarified integrality documentation (#582)
  • Updated the README (#585)
  • Number of numerical issues is now printed to the log (#586)

v1.1.3 (April 2, 2023)

Other

v1.1.2 (March 18, 2023)

Other

v1.1.1 (March 16, 2023)

Other

  • Fixed email in Project.toml
  • Added notebook to documentation tutorials (#571)

v1.1.0 (January 12, 2023)

Added

v1.0.0 (January 3, 2023)

Although we're bumping MAJOR version, this is a non-breaking release. Going forward:

  • New features will bump the MINOR version
  • Bug fixes, maintenance, and documentation updates will bump the PATCH version
  • We will support only the Long Term Support (currently v1.6.7) and the latest patch (currently v1.8.4) releases of Julia. Updates to the LTS version will bump the MINOR version
  • Updates to the compat bounds of package dependencies will bump the PATCH version.

We do not intend any breaking changes to the public API, which would require a new MAJOR release. The public API is everything defined in the documentation. Anything not in the documentation is considered private and may change in any PATCH release.

Added

Other

  • Updated Plotting tools to use live plots (#563)
  • Added vale as a linter (#565)
  • Improved documentation for initializing a parallel scheme (#566)

v0.4.9 (January 3, 2023)

Added

Other

  • Added tutorial on Markov Decision Processes (#556)
  • Added two-stage newsvendor tutorial (#557)
  • Refactored the layout of the documentation (#554) (#555)
  • Updated copyright to 2023 (#558)
  • Fixed errors in the documentation (#561)

v0.4.8 (December 19, 2022)

Added

Fixed

  • Reverted then fixed (#531) because it failed to account for problems with integer variables (#546) (#551)

v0.4.7 (December 17, 2022)

Added

  • Added initial_node support to InSampleMonteCarlo and OutOfSampleMonteCarlo (#535)

Fixed

  • Rethrow InterruptException when solver is interrupted (#534)
  • Fixed numerical recovery when we need dual solutions (#531) (Thanks @bfpc)
  • Fixed re-using the dashboard = true option between solves (#538)
  • Fixed bug when no @stageobjective is set (now defaults to 0.0) (#539)
  • Fixed errors thrown when invalid inputs are provided to add_objective_state (#540)

Other

  • Drop support for Julia versions prior to 1.6 (#533)
  • Updated versions of dependencies (#522) (#533)
  • Switched to HiGHS in the documentation and tests (#533)
  • Added license headers (#519)
  • Fixed link in air conditioning example (#521) (Thanks @conema)
  • Clarified variable naming in deterministic equivalent (#525) (Thanks @lucasprocessi)
  • Added this change log (#536)
  • Cuts are now written to model.cuts.json when numerical instability is discovered. This can aid debugging because it allows to you reload the cuts as of the iteration that caused the numerical issue (#537)

v0.4.6 (March 25, 2022)

Other

  • Updated to JuMP v1.0 (#517)

v0.4.5 (March 9, 2022)

Fixed

  • Fixed issue with set_silent in a subproblem (#510)

Other

  • Fixed many typos (#500) (#501) (#506) (#511) (Thanks @bfpc)
  • Update to JuMP v0.23 (#514)
  • Added auto-regressive tutorial (#507)

v0.4.4 (December 11, 2021)

Added

  • Added BanditDuality (#471)
  • Added benchmark scripts (#475) (#476) (#490)
  • write_cuts_to_file now saves visited states (#468)

Fixed

  • Fixed BoundStalling in a deterministic policy (#470) (#474)
  • Fixed magnitude warning with zero coefficients (#483)

Other

  • Improvements to LagrangianDuality (#481) (#482) (#487)
  • Improvements to StrengthenedConicDuality (#486)
  • Switch to functional form for the tests (#478)
  • Fixed typos (#472) (Thanks @vfdev-5)
  • Update to JuMP v0.22 (#498)

v0.4.3 (August 31, 2021)

Added

  • Added biobjective solver (#462)
  • Added forward_pass_callback (#466)

Other

  • Update tutorials and documentation (#459) (#465)
  • Organize how paper materials are stored (#464)

v0.4.2 (August 24, 2021)

Fixed

  • Fixed a bug in Lagrangian duality (#457)

v0.4.1 (August 23, 2021)

Other

  • Minor changes to our implementation of LagrangianDuality (#454) (#455)

v0.4.0 (August 17, 2021)

Breaking

  • A large refactoring for how we handle stochastic integer programs. This added support for things like SDDP.ContinuousConicDuality and SDDP.LagrangianDuality. It was breaking because we removed the integrality_handler argument to PolicyGraph. (#449) (#453)

Other

  • Documentation improvements (#447) (#448) (#450)

v0.3.17 (July 6, 2021)

Added

Other

  • Display more model attributes (#438)
  • Documentation improvements (#433) (#437) (#439)

v0.3.16 (June 17, 2021)

Added

Other

  • Update risk measure docstrings (#418)

v0.3.15 (June 1, 2021)

Added

Fixed

  • Fixed scoping bug in SDDP.@stageobjective (#407)
  • Fixed a bug when the initial point is infeasible (#411)
  • Set subproblems to silent by default (#409)

Other

  • Add JuliaFormatter (#412)
  • Documentation improvements (#406) (#408)

v0.3.14 (March 30, 2021)

Fixed

  • Fixed O(N^2) behavior in get_same_children (#393)

v0.3.13 (March 27, 2021)

Fixed

  • Fixed bug in print.jl
  • Fixed compat of Reexport (#388)

v0.3.12 (March 22, 2021)

Added

  • Added problem statistics to header (#385) (#386)

Fixed

  • Fixed subtypes in visualization (#384)

v0.3.11 (March 22, 2021)

Fixed

  • Fixed constructor in direct mode (#383)

Other

  • Fix documentation (#379)

v0.3.10 (February 23, 2021)

Fixed

  • Fixed seriescolor in publication plot (#376)

v0.3.9 (February 20, 2021)

Added

  • Add option to simulate with different incoming state (#372)
  • Added warning for cuts with high dynamic range (#373)

Fixed

  • Fixed seriesalpha in publication plot (#375)

v0.3.8 (January 19, 2021)

Other

  • Documentation improvements (#367) (#369) (#370)

v0.3.7 (January 8, 2021)

Other

  • Documentation improvements (#362) (#363) (#365) (#366)
  • Bump copyright (#364)

v0.3.6 (December 17, 2020)

Other

  • Fix typos (#358)
  • Collapse navigation bar in docs (#359)
  • Update TagBot.yml (#361)

v0.3.5 (November 18, 2020)

Other

  • Update citations (#348)
  • Switch to GitHub actions (#355)

v0.3.4 (August 25, 2020)

Added

  • Added non-uniform distributionally robust risk measure (#328)
  • Added numerical recovery functions (#330)
  • Added experimental StochOptFormat (#332) (#336) (#337) (#341) (#343) (#344)
  • Added entropic risk measure (#347)

Other

  • Documentation improvements (#327) (#333) (#339) (#340)

v0.3.3 (June 19, 2020)

Added

  • Added asynchronous support for price and belief states (#325)
  • Added ForwardPass plug-in system (#320)

Fixed

  • Fix check for probabilities in Markovian graph (#322)

v0.3.2 (April 6, 2020)

Added

Other

  • Improve error message in deterministic equivalent (#312)
  • Update to RecipesBase 1.0 (#313)

v0.3.1 (February 26, 2020)

Fixed

  • Fixed filename in integrality_handlers.jl (#304)

v0.3.0 (February 20, 2020)

Breaking

  • Breaking changes to update to JuMP v0.21 (#300).

v0.2.4 (February 7, 2020)

Added

  • Added a counter for the number of total subproblem solves (#301)

Other

  • Update formatter (#298)
  • Added tests (#299)

v0.2.3 (January 24, 2020)

Added

  • Added support for convex risk measures (#294)

Fixed

  • Fixed bug when subproblem is infeasible (#296)
  • Fixed bug in deterministic equivalent (#297)

Other

  • Added example from IJOC paper (#293)

v0.2.2 (January 10, 2020)

Fixed

  • Fixed flakey time limit in tests (#291)

Other

  • Removed MathOptFormat.jl (#289)
  • Update copyright (#290)

v0.2.1 (December 19, 2019)

Added

  • Added support for approximating a Markov lattice (#282) (#285)
  • Add tools for visualizing the value function (#272) (#286)
  • Write .mof.json files on error (#284)

Other

  • Improve documentation (#281) (#283)
  • Update tests for Julia 1.3 (#287)

v0.2.0 (December 16, 2019)

This version added the asynchronous parallel implementation with a few minor breaking changes in how we iterated internally. It didn't break basic user-facing models, only implementations that implemented some of the extension features. It probably could have been a v1.1 release.

Added

  • Added asynchronous parallel implementation (#277)
  • Added roll-out algorithm for cyclic graphs (#279)

Other

  • Improved error messages in PolicyGraph (#271)
  • Added JuliaFormatter (#273) (#276)
  • Fixed compat bounds (#274) (#278)
  • Added documentation for simulating non-standard graphs (#280)

v0.1.0 (October 17, 2019)

A complete rewrite of SDDP.jl based on the policy graph framework. This was essentially a new package. It has minimal code in common with the previous implementation.

Development started on September 28, 2018 in Kokako.jl, and the code was merged into SDDP.jl on March 14, 2019.

The pull request SDDP.jl#180 lists the 29 issues that the rewrite closed.

v0.0.1 (April 18, 2018)

Initial release. Development had been underway since January 22, 2016 in the StochDualDynamicProgram.jl repository. The last development commit there was April 5, 2017. Work then continued in this repository for a year before the first tagged release.

diff --git a/previews/PR811/examples/FAST_hydro_thermal/index.html b/previews/PR811/examples/FAST_hydro_thermal/index.html index f49ebabc2..8f23ef131 100644 --- a/previews/PR811/examples/FAST_hydro_thermal/index.html +++ b/previews/PR811/examples/FAST_hydro_thermal/index.html @@ -66,13 +66,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 -1.000000e+01 2.515078e-03 5 1 - 20 0.000000e+00 -1.000000e+01 1.450109e-02 104 1 + 1 0.000000e+00 -1.000000e+01 2.610922e-03 5 1 + 20 0.000000e+00 -1.000000e+01 1.427984e-02 104 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.450109e-02 +total time (s) : 1.427984e-02 total solves : 104 best bound : -1.000000e+01 simulation ci : -9.000000e+00 ± 4.474009e+00 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/FAST_production_management/index.html b/previews/PR811/examples/FAST_production_management/index.html index 072b4b0b7..789e337d4 100644 --- a/previews/PR811/examples/FAST_production_management/index.html +++ b/previews/PR811/examples/FAST_production_management/index.html @@ -35,4 +35,4 @@ end fast_production_management(; cut_type = SDDP.SINGLE_CUT) -fast_production_management(; cut_type = SDDP.MULTI_CUT)
Test Passed
+fast_production_management(; cut_type = SDDP.MULTI_CUT)
Test Passed
diff --git a/previews/PR811/examples/FAST_quickstart/index.html b/previews/PR811/examples/FAST_quickstart/index.html index b9ad7cf95..5210ec431 100644 --- a/previews/PR811/examples/FAST_quickstart/index.html +++ b/previews/PR811/examples/FAST_quickstart/index.html @@ -33,4 +33,4 @@ @test SDDP.calculate_bound(model) == -2 end -fast_quickstart()
Test Passed
+fast_quickstart()
Test Passed
diff --git a/previews/PR811/examples/Hydro_thermal/index.html b/previews/PR811/examples/Hydro_thermal/index.html index 8c2c6c6d5..1e9d8e09f 100644 --- a/previews/PR811/examples/Hydro_thermal/index.html +++ b/previews/PR811/examples/Hydro_thermal/index.html @@ -59,15 +59,15 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.390000e+02 6.304440e+01 1.052470e-01 183 1 - 31 8.517170e+02 2.346450e+02 1.131817e+00 7701 1 - 53 2.848993e+02 2.362264e+02 2.182867e+00 13899 1 - 71 2.110123e+02 2.363880e+02 3.183201e+00 19101 1 - 81 2.720751e+02 2.364227e+02 4.237067e+00 23895 1 - 100 1.135002e+02 2.364293e+02 4.869921e+00 26640 1 + 1 2.390000e+02 6.304440e+01 1.033659e-01 183 1 + 32 3.987949e+01 2.346450e+02 1.108426e+00 7752 1 + 53 2.848993e+02 2.362264e+02 2.109312e+00 13899 1 + 72 6.195245e+02 2.363946e+02 3.180672e+00 19692 1 + 84 1.975040e+02 2.364251e+02 4.187706e+00 24504 1 + 100 1.135002e+02 2.364293e+02 4.697168e+00 26640 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 4.869921e+00 +total time (s) : 4.697168e+00 total solves : 26640 best bound : 2.364293e+02 simulation ci : 2.593398e+02 ± 5.186931e+01 @@ -75,4 +75,4 @@ -------------------------------------------------------------------

Simulating the policy

After training, we can simulate the policy using SDDP.simulate.

sims = SDDP.simulate(model, 100, [:g_t])
 mu = round(mean([s[1][:g_t] for s in sims]); digits = 2)
 println("On average, $(mu) units of thermal are used in the first stage.")
On average, 1.71 units of thermal are used in the first stage.

Extracting the water values

Finally, we can use SDDP.ValueFunction and SDDP.evaluate to obtain and evaluate the value function at different points in the state-space. Note that since we are minimizing, the price has a negative sign: each additional unit of water leads to a decrease in the expected long-run cost.

V = SDDP.ValueFunction(model[1])
-cost, price = SDDP.evaluate(V; x = 10)
(233.55074662683333, Dict(:x => -0.6602685305287201))
+cost, price = SDDP.evaluate(V; x = 10)
(233.55074662683333, Dict(:x => -0.6602685305287201))
diff --git a/previews/PR811/examples/SDDP.log b/previews/PR811/examples/SDDP.log index f29879886..1d829cd23 100644 --- a/previews/PR811/examples/SDDP.log +++ b/previews/PR811/examples/SDDP.log @@ -25,11 +25,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 -1.000000e+01 2.515078e-03 5 1 - 20 0.000000e+00 -1.000000e+01 1.450109e-02 104 1 + 1 0.000000e+00 -1.000000e+01 2.610922e-03 5 1 + 20 0.000000e+00 -1.000000e+01 1.427984e-02 104 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.450109e-02 +total time (s) : 1.427984e-02 total solves : 104 best bound : -1.000000e+01 simulation ci : -9.000000e+00 ± 4.474009e+00 @@ -61,17 +61,17 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 5 -2.396000e+01 -2.396000e+01 8.341074e-03 52 1 - 10 -4.260000e+01 -2.396000e+01 1.259112e-02 92 1 - 15 -4.260000e+01 -2.396000e+01 1.672006e-02 132 1 - 20 -4.260000e+01 -2.396000e+01 2.099395e-02 172 1 - 25 -2.396000e+01 -2.396000e+01 2.635598e-02 224 1 - 30 -4.260000e+01 -2.396000e+01 3.115106e-02 264 1 - 35 -2.396000e+01 -2.396000e+01 3.624010e-02 304 1 - 40 -2.396000e+01 -2.396000e+01 4.160595e-02 344 1 + 5 -2.396000e+01 -2.396000e+01 7.262230e-03 52 1 + 10 -4.260000e+01 -2.396000e+01 1.092815e-02 92 1 + 15 -4.260000e+01 -2.396000e+01 1.484513e-02 132 1 + 20 -4.260000e+01 -2.396000e+01 1.902413e-02 172 1 + 25 -2.396000e+01 -2.396000e+01 2.425408e-02 224 1 + 30 -4.260000e+01 -2.396000e+01 2.903223e-02 264 1 + 35 -2.396000e+01 -2.396000e+01 3.420901e-02 304 1 + 40 -2.396000e+01 -2.396000e+01 3.966022e-02 344 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 4.160595e-02 +total time (s) : 3.966022e-02 total solves : 344 best bound : -2.396000e+01 simulation ci : -2.660914e+01 ± 3.908038e+00 @@ -81,21 +81,21 @@ numeric issues : 0 ──────────────────────────────────────────────────────────────────────────────── Time Allocations ─────────────────────── ──────────────────────── - Tot / % measured: 98.4ms / 37.3% 32.9MiB / 20.7% + Tot / % measured: 47.5ms / 73.8% 32.8MiB / 20.6% Section ncalls time %tot avg alloc %tot avg ──────────────────────────────────────────────────────────────────────────────── -backward_pass 40 22.3ms 61.0% 559μs 5.84MiB 85.7% 150KiB - solve_subproblem 160 12.6ms 34.5% 79.0μs 871KiB 12.5% 5.44KiB - get_dual_solution 160 620μs 1.7% 3.88μs 190KiB 2.7% 1.19KiB - prepare_backward... 160 28.5μs 0.1% 178ns 0.00B 0.0% 0.00B -forward_pass 40 8.73ms 23.8% 218μs 768KiB 11.0% 19.2KiB - solve_subproblem 120 7.69ms 21.0% 64.1μs 588KiB 8.4% 4.90KiB - get_dual_solution 120 78.8μs 0.2% 656ns 16.9KiB 0.2% 144B - sample_scenario 40 161μs 0.4% 4.01μs 24.5KiB 0.4% 628B -calculate_bound 40 5.55ms 15.1% 139μs 224KiB 3.2% 5.61KiB - get_dual_solution 40 38.7μs 0.1% 967ns 5.62KiB 0.1% 144B -get_dual_solution 36 22.1μs 0.1% 614ns 5.06KiB 0.1% 144B +backward_pass 40 21.7ms 61.9% 544μs 5.79MiB 85.6% 148KiB + solve_subproblem 160 12.2ms 34.7% 76.2μs 871KiB 12.6% 5.44KiB + get_dual_solution 160 632μs 1.8% 3.95μs 190KiB 2.7% 1.19KiB + prepare_backward... 160 27.7μs 0.1% 173ns 0.00B 0.0% 0.00B +forward_pass 40 8.03ms 22.9% 201μs 768KiB 11.1% 19.2KiB + solve_subproblem 120 7.10ms 20.2% 59.2μs 588KiB 8.5% 4.90KiB + get_dual_solution 120 78.0μs 0.2% 650ns 16.9KiB 0.2% 144B + sample_scenario 40 133μs 0.4% 3.33μs 24.5KiB 0.4% 628B +calculate_bound 40 5.31ms 15.1% 133μs 224KiB 3.2% 5.61KiB + get_dual_solution 40 35.7μs 0.1% 892ns 5.62KiB 0.1% 144B +get_dual_solution 36 22.2μs 0.1% 617ns 5.06KiB 0.1% 144B ──────────────────────────────────────────────────────────────────────────────── ------------------------------------------------------------------- @@ -123,17 +123,17 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 5 -5.320000e+00 -2.396000e+01 7.375002e-03 52 1 - 10 -5.320000e+00 -2.396000e+01 1.152205e-02 92 1 - 15 -2.396000e+01 -2.396000e+01 1.614308e-02 132 1 - 20 -5.320000e+00 -2.396000e+01 2.136302e-02 172 1 - 25 -4.260000e+01 -2.396000e+01 2.837300e-02 224 1 - 30 -2.396000e+01 -2.396000e+01 3.509092e-02 264 1 - 35 -2.396000e+01 -2.396000e+01 4.224014e-02 304 1 - 40 -2.396000e+01 -2.396000e+01 5.014515e-02 344 1 + 5 -5.320000e+00 -2.396000e+01 7.006884e-03 52 1 + 10 -5.320000e+00 -2.396000e+01 1.109004e-02 92 1 + 15 -2.396000e+01 -2.396000e+01 1.569891e-02 132 1 + 20 -5.320000e+00 -2.396000e+01 2.090096e-02 172 1 + 25 -4.260000e+01 -2.396000e+01 2.747893e-02 224 1 + 30 -2.396000e+01 -2.396000e+01 3.394389e-02 264 1 + 35 -2.396000e+01 -2.396000e+01 4.089403e-02 304 1 + 40 -2.396000e+01 -2.396000e+01 4.849195e-02 344 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 5.014515e-02 +total time (s) : 4.849195e-02 total solves : 344 best bound : -2.396000e+01 simulation ci : -1.957570e+01 ± 3.890802e+00 @@ -143,21 +143,21 @@ numeric issues : 0 ──────────────────────────────────────────────────────────────────────────────── Time Allocations ─────────────────────── ──────────────────────── - Tot / % measured: 79.8ms / 57.2% 38.7MiB / 32.8% + Tot / % measured: 80.3ms / 55.1% 38.7MiB / 32.8% Section ncalls time %tot avg alloc %tot avg ──────────────────────────────────────────────────────────────────────────────── -backward_pass 40 31.9ms 69.8% 797μs 11.7MiB 92.3% 300KiB - solve_subproblem 160 12.6ms 27.5% 78.5μs 872KiB 6.7% 5.45KiB - get_dual_solution 160 611μs 1.3% 3.82μs 190KiB 1.5% 1.19KiB - prepare_backward... 160 27.4μs 0.1% 171ns 0.00B 0.0% 0.00B -forward_pass 40 8.06ms 17.6% 201μs 768KiB 5.9% 19.2KiB - solve_subproblem 120 7.15ms 15.6% 59.6μs 588KiB 4.5% 4.90KiB - get_dual_solution 120 70.7μs 0.2% 589ns 16.9KiB 0.1% 144B - sample_scenario 40 134μs 0.3% 3.35μs 24.2KiB 0.2% 620B -calculate_bound 40 5.72ms 12.5% 143μs 226KiB 1.7% 5.66KiB - get_dual_solution 40 35.2μs 0.1% 880ns 5.62KiB 0.0% 144B -get_dual_solution 36 20.3μs 0.0% 563ns 5.06KiB 0.0% 144B +backward_pass 40 30.7ms 69.4% 767μs 11.7MiB 92.3% 300KiB + solve_subproblem 160 12.2ms 27.6% 76.2μs 872KiB 6.7% 5.45KiB + get_dual_solution 160 625μs 1.4% 3.91μs 190KiB 1.5% 1.19KiB + prepare_backward... 160 27.1μs 0.1% 169ns 0.00B 0.0% 0.00B +forward_pass 40 7.90ms 17.9% 197μs 768KiB 5.9% 19.2KiB + solve_subproblem 120 7.00ms 15.8% 58.3μs 588KiB 4.5% 4.90KiB + get_dual_solution 120 106μs 0.2% 883ns 16.9KiB 0.1% 144B + sample_scenario 40 124μs 0.3% 3.11μs 24.2KiB 0.2% 620B +calculate_bound 40 5.62ms 12.7% 141μs 226KiB 1.7% 5.66KiB + get_dual_solution 40 35.0μs 0.1% 875ns 5.62KiB 0.0% 144B +get_dual_solution 36 20.4μs 0.0% 567ns 5.06KiB 0.0% 144B ──────────────────────────────────────────────────────────────────────────────── ------------------------------------------------------------------- @@ -185,49 +185,49 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 -2.500000e+00 2.141953e-03 5 1 - 2 -1.500000e+00 -2.000000e+00 3.125906e-03 14 1 - 3 -1.000000e+00 -2.000000e+00 3.595829e-03 19 1 - 4 -1.000000e+00 -2.000000e+00 4.153967e-03 24 1 - 5 -2.000000e+00 -2.000000e+00 4.801989e-03 29 1 - 6 -2.000000e+00 -2.000000e+00 5.398035e-03 34 1 - 7 -2.000000e+00 -2.000000e+00 5.965948e-03 39 1 - 8 -2.000000e+00 -2.000000e+00 6.535053e-03 44 1 - 9 -2.000000e+00 -2.000000e+00 7.117033e-03 49 1 - 10 -2.000000e+00 -2.000000e+00 7.704020e-03 54 1 - 11 -2.000000e+00 -2.000000e+00 8.286953e-03 59 1 - 12 -2.000000e+00 -2.000000e+00 8.920908e-03 64 1 - 13 -2.000000e+00 -2.000000e+00 9.531975e-03 69 1 - 14 -2.000000e+00 -2.000000e+00 1.012897e-02 74 1 - 15 -2.000000e+00 -2.000000e+00 1.073384e-02 79 1 - 16 -2.000000e+00 -2.000000e+00 1.133084e-02 84 1 - 17 -2.000000e+00 -2.000000e+00 1.194382e-02 89 1 - 18 -2.000000e+00 -2.000000e+00 1.257300e-02 94 1 - 19 -2.000000e+00 -2.000000e+00 1.319289e-02 99 1 - 20 -2.000000e+00 -2.000000e+00 1.382685e-02 104 1 - 21 -2.000000e+00 -2.000000e+00 1.477289e-02 113 1 - 22 -2.000000e+00 -2.000000e+00 1.540899e-02 118 1 - 23 -2.000000e+00 -2.000000e+00 1.606083e-02 123 1 - 24 -2.000000e+00 -2.000000e+00 1.673102e-02 128 1 - 25 -2.000000e+00 -2.000000e+00 1.739001e-02 133 1 - 26 -2.000000e+00 -2.000000e+00 1.811385e-02 138 1 - 27 -2.000000e+00 -2.000000e+00 1.877594e-02 143 1 - 28 -2.000000e+00 -2.000000e+00 1.945901e-02 148 1 - 29 -2.000000e+00 -2.000000e+00 2.013087e-02 153 1 - 30 -2.000000e+00 -2.000000e+00 2.084899e-02 158 1 - 31 -2.000000e+00 -2.000000e+00 2.154183e-02 163 1 - 32 -2.000000e+00 -2.000000e+00 2.223897e-02 168 1 - 33 -2.000000e+00 -2.000000e+00 2.297592e-02 173 1 - 34 -2.000000e+00 -2.000000e+00 2.367496e-02 178 1 - 35 -2.000000e+00 -2.000000e+00 2.437401e-02 183 1 - 36 -2.000000e+00 -2.000000e+00 2.512503e-02 188 1 - 37 -2.000000e+00 -2.000000e+00 2.585697e-02 193 1 - 38 -2.000000e+00 -2.000000e+00 5.089498e-02 198 1 - 39 -2.000000e+00 -2.000000e+00 5.169106e-02 203 1 - 40 -2.000000e+00 -2.000000e+00 5.245590e-02 208 1 + 1 0.000000e+00 -2.500000e+00 2.111912e-03 5 1 + 2 -1.500000e+00 -2.000000e+00 3.072023e-03 14 1 + 3 -1.000000e+00 -2.000000e+00 3.530979e-03 19 1 + 4 -1.000000e+00 -2.000000e+00 4.077911e-03 24 1 + 5 -2.000000e+00 -2.000000e+00 4.676104e-03 29 1 + 6 -2.000000e+00 -2.000000e+00 5.233049e-03 34 1 + 7 -2.000000e+00 -2.000000e+00 5.804062e-03 39 1 + 8 -2.000000e+00 -2.000000e+00 6.359100e-03 44 1 + 9 -2.000000e+00 -2.000000e+00 6.913900e-03 49 1 + 10 -2.000000e+00 -2.000000e+00 7.481098e-03 54 1 + 11 -2.000000e+00 -2.000000e+00 8.039951e-03 59 1 + 12 -2.000000e+00 -2.000000e+00 8.598089e-03 64 1 + 13 -2.000000e+00 -2.000000e+00 9.202003e-03 69 1 + 14 -2.000000e+00 -2.000000e+00 9.831905e-03 74 1 + 15 -2.000000e+00 -2.000000e+00 1.043510e-02 79 1 + 16 -2.000000e+00 -2.000000e+00 1.110005e-02 84 1 + 17 -2.000000e+00 -2.000000e+00 1.172900e-02 89 1 + 18 -2.000000e+00 -2.000000e+00 1.234508e-02 94 1 + 19 -2.000000e+00 -2.000000e+00 1.296091e-02 99 1 + 20 -2.000000e+00 -2.000000e+00 1.356912e-02 104 1 + 21 -2.000000e+00 -2.000000e+00 1.453805e-02 113 1 + 22 -2.000000e+00 -2.000000e+00 1.519608e-02 118 1 + 23 -2.000000e+00 -2.000000e+00 1.583099e-02 123 1 + 24 -2.000000e+00 -2.000000e+00 1.648688e-02 128 1 + 25 -2.000000e+00 -2.000000e+00 1.711702e-02 133 1 + 26 -2.000000e+00 -2.000000e+00 1.778102e-02 138 1 + 27 -2.000000e+00 -2.000000e+00 1.843810e-02 143 1 + 28 -2.000000e+00 -2.000000e+00 1.910305e-02 148 1 + 29 -2.000000e+00 -2.000000e+00 1.976109e-02 153 1 + 30 -2.000000e+00 -2.000000e+00 4.321909e-02 158 1 + 31 -2.000000e+00 -2.000000e+00 4.396009e-02 163 1 + 32 -2.000000e+00 -2.000000e+00 4.464602e-02 168 1 + 33 -2.000000e+00 -2.000000e+00 4.533100e-02 173 1 + 34 -2.000000e+00 -2.000000e+00 4.602504e-02 178 1 + 35 -2.000000e+00 -2.000000e+00 4.671597e-02 183 1 + 36 -2.000000e+00 -2.000000e+00 4.740500e-02 188 1 + 37 -2.000000e+00 -2.000000e+00 4.810095e-02 193 1 + 38 -2.000000e+00 -2.000000e+00 4.881501e-02 198 1 + 39 -2.000000e+00 -2.000000e+00 4.952502e-02 203 1 + 40 -2.000000e+00 -2.000000e+00 5.027390e-02 208 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 5.245590e-02 +total time (s) : 5.027390e-02 total solves : 208 best bound : -2.000000e+00 simulation ci : -1.887500e+00 ± 1.189300e-01 @@ -259,15 +259,15 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.390000e+02 6.304440e+01 1.052470e-01 183 1 - 31 8.517170e+02 2.346450e+02 1.131817e+00 7701 1 - 53 2.848993e+02 2.362264e+02 2.182867e+00 13899 1 - 71 2.110123e+02 2.363880e+02 3.183201e+00 19101 1 - 81 2.720751e+02 2.364227e+02 4.237067e+00 23895 1 - 100 1.135002e+02 2.364293e+02 4.869921e+00 26640 1 + 1 2.390000e+02 6.304440e+01 1.033659e-01 183 1 + 32 3.987949e+01 2.346450e+02 1.108426e+00 7752 1 + 53 2.848993e+02 2.362264e+02 2.109312e+00 13899 1 + 72 6.195245e+02 2.363946e+02 3.180672e+00 19692 1 + 84 1.975040e+02 2.364251e+02 4.187706e+00 24504 1 + 100 1.135002e+02 2.364293e+02 4.697168e+00 26640 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 4.869921e+00 +total time (s) : 4.697168e+00 total solves : 26640 best bound : 2.364293e+02 simulation ci : 2.593398e+02 ± 5.186931e+01 @@ -300,19 +300,19 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -3.878303e+00 -4.434982e+00 1.954072e-01 1400 1 - 20 -4.262885e+00 -4.399265e+00 3.146410e-01 2800 1 - 30 -3.075162e+00 -4.382527e+00 4.405310e-01 4200 1 - 40 -3.761147e+00 -4.369587e+00 5.749981e-01 5600 1 - 50 -4.323162e+00 -4.362199e+00 7.177551e-01 7000 1 - 60 -3.654943e+00 -4.358401e+00 8.631310e-01 8400 1 - 70 -4.010883e+00 -4.357368e+00 1.069839e+00 9800 1 - 80 -4.314412e+00 -4.355714e+00 1.222770e+00 11200 1 - 90 -4.542422e+00 -4.353708e+00 1.375749e+00 12600 1 - 100 -4.178952e+00 -4.351685e+00 1.525265e+00 14000 1 + 10 -3.878303e+00 -4.434982e+00 1.908009e-01 1400 1 + 20 -4.262885e+00 -4.399265e+00 3.070920e-01 2800 1 + 30 -3.075162e+00 -4.382527e+00 4.300220e-01 4200 1 + 40 -3.761147e+00 -4.369587e+00 5.593009e-01 5600 1 + 50 -4.323162e+00 -4.362199e+00 7.511120e-01 7000 1 + 60 -3.654943e+00 -4.358401e+00 8.881328e-01 8400 1 + 70 -4.010883e+00 -4.357368e+00 1.027195e+00 9800 1 + 80 -4.314412e+00 -4.355714e+00 1.171472e+00 11200 1 + 90 -4.542422e+00 -4.353708e+00 1.321075e+00 12600 1 + 100 -4.178952e+00 -4.351685e+00 1.464739e+00 14000 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.525265e+00 +total time (s) : 1.464739e+00 total solves : 14000 best bound : -4.351685e+00 simulation ci : -4.246786e+00 ± 8.703997e-02 @@ -344,16 +344,16 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -1.573154e+00 -1.474247e+00 6.967521e-02 1050 1 - 20 -1.346690e+00 -1.471483e+00 1.089730e-01 1600 1 - 30 -1.308031e+00 -1.471307e+00 1.949091e-01 2650 1 - 40 -1.401200e+00 -1.471167e+00 2.374411e-01 3200 1 - 50 -1.557483e+00 -1.471097e+00 3.282430e-01 4250 1 - 60 -1.534169e+00 -1.471075e+00 3.747780e-01 4800 1 - 65 -1.689864e+00 -1.471075e+00 3.981712e-01 5075 1 + 10 -1.573154e+00 -1.474247e+00 6.817293e-02 1050 1 + 20 -1.346690e+00 -1.471483e+00 1.061029e-01 1600 1 + 30 -1.308031e+00 -1.471307e+00 1.872530e-01 2650 1 + 40 -1.401200e+00 -1.471167e+00 2.279379e-01 3200 1 + 50 -1.557483e+00 -1.471097e+00 3.135750e-01 4250 1 + 60 -1.534169e+00 -1.471075e+00 3.576341e-01 4800 1 + 65 -1.689864e+00 -1.471075e+00 3.798909e-01 5075 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.981712e-01 +total time (s) : 3.798909e-01 total solves : 5075 best bound : -1.471075e+00 simulation ci : -1.484094e+00 ± 4.058993e-02 @@ -387,14 +387,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 3.455904e+05 3.147347e+05 8.262157e-03 54 1 - 20 3.336455e+05 3.402383e+05 1.447606e-02 104 1 - 30 3.337559e+05 3.403155e+05 2.172709e-02 158 1 - 40 3.337559e+05 3.403155e+05 2.874899e-02 208 1 - 48 3.337559e+05 3.403155e+05 3.487802e-02 248 1 + 10 3.455904e+05 3.147347e+05 7.987022e-03 54 1 + 20 3.336455e+05 3.402383e+05 1.392007e-02 104 1 + 30 3.337559e+05 3.403155e+05 2.099895e-02 158 1 + 40 3.337559e+05 3.403155e+05 2.778602e-02 208 1 + 48 3.337559e+05 3.403155e+05 3.368807e-02 248 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.487802e-02 +total time (s) : 3.368807e-02 total solves : 248 best bound : 3.403155e+05 simulation ci : 1.351676e+08 ± 1.785770e+08 @@ -429,14 +429,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 4.403329e+05 3.509666e+05 1.330900e-02 92 1 - 20 4.055335e+05 4.054833e+05 2.407002e-02 172 1 - 30 3.959476e+05 4.067125e+05 3.729391e-02 264 1 - 40 3.959476e+05 4.067125e+05 5.070090e-02 344 1 - 47 3.959476e+05 4.067125e+05 6.092501e-02 400 1 + 10 4.403329e+05 3.509666e+05 1.372409e-02 92 1 + 20 4.055335e+05 4.054833e+05 2.413797e-02 172 1 + 30 3.959476e+05 4.067125e+05 3.714299e-02 264 1 + 40 3.959476e+05 4.067125e+05 5.035496e-02 344 1 + 47 3.959476e+05 4.067125e+05 6.017613e-02 400 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 6.092501e-02 +total time (s) : 6.017613e-02 total solves : 400 best bound : 4.067125e+05 simulation ci : 2.695623e+07 ± 3.645336e+07 @@ -470,11 +470,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 8.316000e+03 0.000000e+00 9.188700e-02 14 1 - 40 4.716000e+03 4.074139e+03 2.221341e-01 776 1 + 1 8.316000e+03 0.000000e+00 9.584212e-02 14 1 + 40 4.716000e+03 4.074139e+03 2.251890e-01 776 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 2.221341e-01 +total time (s) : 2.251890e-01 total solves : 776 best bound : 4.074139e+03 simulation ci : 4.477341e+03 ± 6.593738e+02 @@ -507,11 +507,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1L 7.000000e+04 6.166667e+04 5.622830e-01 8 1 - 40L 5.500000e+04 6.250000e+04 8.109930e-01 344 1 + 1L 7.000000e+04 6.166667e+04 5.616159e-01 8 1 + 40L 5.500000e+04 6.250000e+04 7.965860e-01 344 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 8.109930e-01 +total time (s) : 7.965860e-01 total solves : 344 best bound : 6.250000e+04 simulation ci : 6.091250e+04 ± 6.325667e+03 @@ -544,11 +544,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.000000e+04 6.250000e+04 3.826857e-03 8 1 - 20 6.000000e+04 6.250000e+04 4.415202e-02 172 1 + 1 3.000000e+04 6.250000e+04 3.710985e-03 8 1 + 20 6.000000e+04 6.250000e+04 4.263806e-02 172 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 4.415202e-02 +total time (s) : 4.263806e-02 total solves : 172 best bound : 6.250000e+04 simulation ci : 5.675000e+04 ± 6.792430e+03 @@ -580,11 +580,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 7.000000e+04 6.250000e+04 6.102085e-03 5 1 - 10 4.000000e+04 6.250000e+04 2.176714e-02 50 1 + 1 7.000000e+04 6.250000e+04 5.466938e-03 5 1 + 10 4.000000e+04 6.250000e+04 1.977706e-02 50 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 2.176714e-02 +total time (s) : 1.977706e-02 total solves : 50 best bound : 6.250000e+04 simulation ci : 6.300000e+04 ± 1.505505e+04 @@ -617,11 +617,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1L 6.000000e+00 9.000000e+00 3.972387e-02 6 1 - 20L 9.000000e+00 9.000000e+00 7.997894e-02 123 1 + 1L 6.000000e+00 9.000000e+00 3.953099e-02 6 1 + 20L 9.000000e+00 9.000000e+00 7.881713e-02 123 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.997894e-02 +total time (s) : 7.881713e-02 total solves : 123 best bound : 9.000000e+00 simulation ci : 8.850000e+00 ± 2.940000e-01 @@ -653,17 +653,17 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 5 -5.684342e-14 1.184830e+00 1.324701e-02 87 1 - 10 5.012507e+01 1.508277e+00 1.992893e-02 142 1 - 15 -1.428571e+00 1.514085e+00 2.718711e-02 197 1 - 20 7.105427e-14 1.514085e+00 3.492689e-02 252 1 - 25 -3.979039e-13 1.514085e+00 9.082890e-02 339 1 - 30 -1.428571e+00 1.514085e+00 9.950495e-02 394 1 - 35 -1.428571e+00 1.514085e+00 1.088130e-01 449 1 - 40 0.000000e+00 1.514085e+00 1.187019e-01 504 1 + 5 -5.684342e-14 1.184830e+00 1.294804e-02 87 1 + 10 5.012507e+01 1.508277e+00 1.928401e-02 142 1 + 15 -1.428571e+00 1.514085e+00 2.620506e-02 197 1 + 20 7.105427e-14 1.514085e+00 3.358603e-02 252 1 + 25 -3.979039e-13 1.514085e+00 8.626199e-02 339 1 + 30 -1.428571e+00 1.514085e+00 9.451199e-02 394 1 + 35 -1.428571e+00 1.514085e+00 1.033161e-01 449 1 + 40 0.000000e+00 1.514085e+00 1.364520e-01 504 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.187019e-01 +total time (s) : 1.364520e-01 total solves : 504 best bound : 1.514085e+00 simulation ci : 2.863132e+00 ± 6.778637e+00 @@ -695,14 +695,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 1.100409e+00 1.301856e+00 1.650801e-01 278 1 - 20 1.263098e+01 1.278410e+00 1.862741e-01 428 1 - 30 -5.003795e+01 1.278410e+00 2.207019e-01 706 1 - 40 6.740000e+00 1.278410e+00 2.450829e-01 856 1 - 44 1.111084e+01 1.278410e+00 2.551520e-01 916 1 + 10 1.100409e+00 1.301856e+00 1.600721e-01 278 1 + 20 1.263098e+01 1.278410e+00 1.794529e-01 428 1 + 30 -5.003795e+01 1.278410e+00 2.113140e-01 706 1 + 40 6.740000e+00 1.278410e+00 2.339380e-01 856 1 + 44 1.111084e+01 1.278410e+00 2.433879e-01 916 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 2.551520e-01 +total time (s) : 2.433879e-01 total solves : 916 best bound : 1.278410e+00 simulation ci : 4.090025e+00 ± 5.358375e+00 @@ -734,13 +734,13 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 2.007061e+00 1.281639e+00 3.784490e-02 278 1 - 20 1.426676e+01 1.278410e+00 6.748295e-02 428 1 - 30 1.522212e+00 1.278410e+00 1.148939e-01 706 1 - 40 -4.523775e+01 1.278410e+00 1.542470e-01 856 1 + 10 2.007061e+00 1.281639e+00 3.518391e-02 278 1 + 20 1.426676e+01 1.278410e+00 6.251502e-02 428 1 + 30 1.522212e+00 1.278410e+00 1.079910e-01 706 1 + 40 -4.523775e+01 1.278410e+00 1.468689e-01 856 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.542470e-01 +total time (s) : 1.468689e-01 total solves : 856 best bound : 1.278410e+00 simulation ci : 1.019480e+00 ± 6.246418e+00 @@ -774,19 +774,19 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 4.787277e+00 9.346930e+00 1.374903e+00 900 1 - 20 6.374753e+00 1.361934e+01 1.545683e+00 1720 1 - 30 2.813321e+01 1.651297e+01 1.905802e+00 3036 1 - 40 1.654759e+01 1.632970e+01 2.253714e+00 4192 1 - 50 3.570941e+00 1.846889e+01 2.544238e+00 5020 1 - 60 1.087425e+01 1.890254e+01 2.851454e+00 5808 1 - 70 9.381610e+00 1.940320e+01 3.172653e+00 6540 1 - 80 5.648731e+01 1.962435e+01 3.527620e+00 7088 1 - 90 3.879273e+01 1.981008e+01 4.762945e+00 8180 1 - 100 7.870187e+00 1.997117e+01 5.025220e+00 8664 1 + 10 4.787277e+00 9.346930e+00 1.380354e+00 900 1 + 20 6.374753e+00 1.361934e+01 1.548098e+00 1720 1 + 30 2.813321e+01 1.651297e+01 1.900516e+00 3036 1 + 40 1.654759e+01 1.632970e+01 2.278601e+00 4192 1 + 50 3.570941e+00 1.846889e+01 2.535460e+00 5020 1 + 60 1.087425e+01 1.890254e+01 2.823263e+00 5808 1 + 70 9.381610e+00 1.940320e+01 3.120219e+00 6540 1 + 80 5.648731e+01 1.962435e+01 3.347280e+00 7088 1 + 90 3.879273e+01 1.981008e+01 4.501978e+00 8180 1 + 100 7.870187e+00 1.997117e+01 4.722817e+00 8664 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 5.025220e+00 +total time (s) : 4.722817e+00 total solves : 8664 best bound : 1.997117e+01 simulation ci : 2.275399e+01 ± 4.541987e+00 @@ -821,17 +821,17 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 5 9.000000e+00 9.002950e+00 1.350040e-01 235 1 - 10 4.000000e+00 9.002950e+00 1.556311e-01 310 1 - 15 4.000000e+00 9.002950e+00 1.771379e-01 385 1 - 20 4.000000e+00 9.002950e+00 1.987100e-01 460 1 - 25 1.000000e+01 9.002950e+00 2.729900e-01 695 1 - 30 5.000000e+00 9.002950e+00 2.956219e-01 770 1 - 35 1.000000e+01 9.002950e+00 3.193719e-01 845 1 - 40 5.000000e+00 9.002950e+00 3.437741e-01 920 1 + 5 9.000000e+00 9.002950e+00 1.397099e-01 235 1 + 10 4.000000e+00 9.002950e+00 1.603119e-01 310 1 + 15 4.000000e+00 9.002950e+00 1.813471e-01 385 1 + 20 4.000000e+00 9.002950e+00 2.026861e-01 460 1 + 25 1.000000e+01 9.002950e+00 2.760241e-01 695 1 + 30 5.000000e+00 9.002950e+00 2.983031e-01 770 1 + 35 1.000000e+01 9.002950e+00 3.219221e-01 845 1 + 40 5.000000e+00 9.002950e+00 3.457811e-01 920 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.437741e-01 +total time (s) : 3.457811e-01 total solves : 920 best bound : 9.002950e+00 simulation ci : 6.375000e+00 ± 7.930178e-01 @@ -866,15 +866,15 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 1.000000e+01 6.868919e+00 1.075342e-01 510 1 - 20 2.000000e+00 6.834387e+00 1.608391e-01 720 1 - 30 1.200000e+01 6.834387e+00 3.048151e-01 1230 1 - 40 7.000000e+00 6.823805e+00 3.581901e-01 1440 1 - 50 7.000000e+00 6.823805e+00 5.050421e-01 1950 1 - 60 5.000000e+00 6.823805e+00 5.601120e-01 2160 1 + 10 1.000000e+01 6.868919e+00 1.058819e-01 510 1 + 20 2.000000e+00 6.834387e+00 1.586750e-01 720 1 + 30 1.200000e+01 6.834387e+00 3.022470e-01 1230 1 + 40 7.000000e+00 6.823805e+00 3.562090e-01 1440 1 + 50 7.000000e+00 6.823805e+00 5.026660e-01 1950 1 + 60 5.000000e+00 6.823805e+00 5.581319e-01 2160 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 5.601120e-01 +total time (s) : 5.581319e-01 total solves : 2160 best bound : 6.823805e+00 simulation ci : 6.183333e+00 ± 6.258900e-01 @@ -908,15 +908,15 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 2.549668e+06 2.078257e+06 5.240018e-01 920 1 - 20 5.494568e+05 2.078257e+06 7.212958e-01 1340 1 - 30 4.985879e+04 2.078257e+06 1.260305e+00 2260 1 - 40 3.799447e+06 2.078257e+06 1.460601e+00 2680 1 - 50 1.049867e+06 2.078257e+06 2.033111e+00 3600 1 - 60 3.985191e+04 2.078257e+06 2.237982e+00 4020 1 + 10 2.549668e+06 2.078257e+06 5.147491e-01 920 1 + 20 5.494568e+05 2.078257e+06 7.083230e-01 1340 1 + 30 4.985879e+04 2.078257e+06 1.255638e+00 2260 1 + 40 3.799447e+06 2.078257e+06 1.457364e+00 2680 1 + 50 1.049867e+06 2.078257e+06 2.019956e+00 3600 1 + 60 3.985191e+04 2.078257e+06 2.227458e+00 4020 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 2.237982e+00 +total time (s) : 2.227458e+00 total solves : 4020 best bound : 2.078257e+06 simulation ci : 2.031697e+06 ± 3.922745e+05 @@ -950,15 +950,15 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10L 4.986663e+04 2.079119e+06 9.402680e-01 920 1 - 20L 3.799878e+06 2.079330e+06 1.662699e+00 1340 1 - 30L 3.003923e+04 2.079457e+06 2.782754e+00 2260 1 - 40L 5.549882e+06 2.079457e+06 3.587709e+00 2680 1 - 50L 2.799466e+06 2.079457e+06 4.801594e+00 3600 1 - 60L 3.549880e+06 2.079457e+06 5.577852e+00 4020 1 + 10L 4.986663e+04 2.079119e+06 9.453409e-01 920 1 + 20L 3.799878e+06 2.079330e+06 1.661727e+00 1340 1 + 30L 3.003923e+04 2.079457e+06 2.782502e+00 2260 1 + 40L 5.549882e+06 2.079457e+06 3.574901e+00 2680 1 + 50L 2.799466e+06 2.079457e+06 4.784258e+00 3600 1 + 60L 3.549880e+06 2.079457e+06 5.556520e+00 4020 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 5.577852e+00 +total time (s) : 5.556520e+00 total solves : 4020 best bound : 2.079457e+06 simulation ci : 2.352204e+06 ± 5.377531e+05 @@ -990,13 +990,13 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 100 2.500000e+01 1.188965e+02 8.147130e-01 1946 1 - 200 2.500000e+01 1.191634e+02 1.027875e+00 3920 1 - 300 0.000000e+00 1.191666e+02 1.253149e+00 5902 1 - 330 2.500000e+01 1.191667e+02 1.295287e+00 6224 1 + 100 2.500000e+01 1.188965e+02 7.813201e-01 1946 1 + 200 2.500000e+01 1.191634e+02 9.817300e-01 3920 1 + 300 0.000000e+00 1.191666e+02 1.189551e+00 5902 1 + 330 2.500000e+01 1.191667e+02 1.229830e+00 6224 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.295287e+00 +total time (s) : 1.229830e+00 total solves : 6224 best bound : 1.191667e+02 simulation ci : 2.158333e+01 ± 3.290252e+00 @@ -1028,12 +1028,12 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 100 0.000000e+00 1.191285e+02 3.682230e-01 2874 1 - 200 2.500000e+00 1.191666e+02 6.167409e-01 4855 1 - 282 7.500000e+00 1.191667e+02 7.612429e-01 5733 1 + 100 0.000000e+00 1.191285e+02 3.425910e-01 2874 1 + 200 2.500000e+00 1.191666e+02 5.737948e-01 4855 1 + 282 7.500000e+00 1.191667e+02 7.097430e-01 5733 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.612429e-01 +total time (s) : 7.097430e-01 total solves : 5733 best bound : 1.191667e+02 simulation ci : 2.104610e+01 ± 3.492245e+00 @@ -1064,13 +1064,13 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 4.000000e+00 1.997089e+01 7.080197e-02 1204 1 - 20 8.000000e+00 2.000000e+01 9.183383e-02 1420 1 - 30 1.600000e+01 2.000000e+01 1.607640e-01 2628 1 - 40 8.000000e+00 2.000000e+01 1.828198e-01 2834 1 + 10 4.000000e+00 1.997089e+01 6.758094e-02 1204 1 + 20 8.000000e+00 2.000000e+01 8.787799e-02 1420 1 + 30 1.600000e+01 2.000000e+01 1.550801e-01 2628 1 + 40 8.000000e+00 2.000000e+01 1.759651e-01 2834 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.828198e-01 +total time (s) : 1.759651e-01 total solves : 2834 best bound : 2.000000e+01 simulation ci : 1.625000e+01 ± 4.766381e+00 @@ -1101,11 +1101,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.000000e+00 1.500000e+00 1.674891e-03 3 1 - 40 4.000000e+00 2.000000e+00 4.355884e-02 578 1 + 1 1.000000e+00 1.500000e+00 1.639128e-03 3 1 + 40 4.000000e+00 2.000000e+00 4.273510e-02 578 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 4.355884e-02 +total time (s) : 4.273510e-02 total solves : 578 best bound : 2.000000e+00 simulation ci : 1.950000e+00 ± 5.568095e-01 @@ -1138,136 +1138,138 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 5.250000e+00 4.888859e+00 1.734259e-01 1350 1 - 20 4.350000e+00 4.105855e+00 2.593269e-01 2700 1 - 30 5.000000e+00 4.100490e+00 3.561099e-01 4050 1 - 40 3.500000e+00 4.097376e+00 4.613249e-01 5400 1 - 50 5.250000e+00 4.095859e+00 5.681269e-01 6750 1 - 60 3.643750e+00 4.093342e+00 6.795769e-01 8100 1 - 70 2.643750e+00 4.091818e+00 8.375499e-01 9450 1 - 80 5.087500e+00 4.091591e+00 9.514139e-01 10800 1 - 90 5.062500e+00 4.091309e+00 1.069393e+00 12150 1 - 100 4.843750e+00 4.087004e+00 1.194058e+00 13500 1 - 110 3.437500e+00 4.086094e+00 1.318437e+00 14850 1 - 120 3.375000e+00 4.085926e+00 1.443642e+00 16200 1 - 130 5.025000e+00 4.085866e+00 1.572026e+00 17550 1 - 140 5.000000e+00 4.085734e+00 1.699506e+00 18900 1 - 150 3.500000e+00 4.085655e+00 1.828924e+00 20250 1 - 160 4.281250e+00 4.085454e+00 1.955072e+00 21600 1 - 170 4.562500e+00 4.085425e+00 2.086330e+00 22950 1 - 180 5.768750e+00 4.085425e+00 2.217444e+00 24300 1 - 190 3.468750e+00 4.085359e+00 2.362571e+00 25650 1 - 200 4.131250e+00 4.085225e+00 2.501070e+00 27000 1 - 210 4.512500e+00 4.085157e+00 2.635083e+00 28350 1 - 220 4.900000e+00 4.085153e+00 2.773443e+00 29700 1 - 230 4.025000e+00 4.085134e+00 2.915444e+00 31050 1 - 240 4.468750e+00 4.085116e+00 3.059644e+00 32400 1 - 250 4.062500e+00 4.085075e+00 3.199127e+00 33750 1 - 260 4.875000e+00 4.085037e+00 3.340952e+00 35100 1 - 270 3.850000e+00 4.085011e+00 3.481494e+00 36450 1 - 280 4.912500e+00 4.084992e+00 3.624226e+00 37800 1 - 290 2.987500e+00 4.084986e+00 3.771702e+00 39150 1 - 300 3.825000e+00 4.084957e+00 3.960055e+00 40500 1 - 310 3.250000e+00 4.084911e+00 4.108256e+00 41850 1 - 320 3.600000e+00 4.084896e+00 4.255653e+00 43200 1 - 330 3.925000e+00 4.084896e+00 4.393683e+00 44550 1 - 340 4.500000e+00 4.084893e+00 4.541749e+00 45900 1 - 350 5.000000e+00 4.084891e+00 4.690975e+00 47250 1 - 360 3.075000e+00 4.084866e+00 4.837096e+00 48600 1 - 370 3.500000e+00 4.084861e+00 4.990098e+00 49950 1 - 380 3.356250e+00 4.084857e+00 5.144240e+00 51300 1 - 390 5.500000e+00 4.084846e+00 5.310439e+00 52650 1 - 400 4.475000e+00 4.084846e+00 5.465906e+00 54000 1 - 410 3.750000e+00 4.084843e+00 5.620679e+00 55350 1 - 420 3.687500e+00 4.084843e+00 5.779263e+00 56700 1 - 430 4.337500e+00 4.084825e+00 5.935040e+00 58050 1 - 440 5.750000e+00 4.084825e+00 6.076252e+00 59400 1 - 450 4.925000e+00 4.084792e+00 6.246021e+00 60750 1 - 460 3.600000e+00 4.084792e+00 6.400154e+00 62100 1 - 470 4.387500e+00 4.084792e+00 6.549840e+00 63450 1 - 480 4.000000e+00 4.084792e+00 6.710515e+00 64800 1 - 490 2.975000e+00 4.084788e+00 6.864817e+00 66150 1 - 500 3.125000e+00 4.084788e+00 7.024368e+00 67500 1 - 510 4.250000e+00 4.084788e+00 7.186687e+00 68850 1 - 520 4.512500e+00 4.084786e+00 7.338763e+00 70200 1 - 530 3.875000e+00 4.084786e+00 7.532629e+00 71550 1 - 540 4.387500e+00 4.084781e+00 7.696063e+00 72900 1 - 550 5.281250e+00 4.084780e+00 7.860922e+00 74250 1 - 560 4.650000e+00 4.084780e+00 8.016701e+00 75600 1 - 570 3.062500e+00 4.084780e+00 8.171513e+00 76950 1 - 580 3.187500e+00 4.084780e+00 8.325596e+00 78300 1 - 590 3.812500e+00 4.084780e+00 8.475552e+00 79650 1 - 600 3.637500e+00 4.084774e+00 8.634904e+00 81000 1 - 610 3.950000e+00 4.084765e+00 8.792513e+00 82350 1 - 620 4.625000e+00 4.084760e+00 8.950787e+00 83700 1 - 630 4.218750e+00 4.084760e+00 9.112958e+00 85050 1 - 640 3.025000e+00 4.084755e+00 9.280204e+00 86400 1 - 650 2.993750e+00 4.084751e+00 9.435989e+00 87750 1 - 660 3.262500e+00 4.084746e+00 9.601910e+00 89100 1 - 670 3.625000e+00 4.084746e+00 9.775332e+00 90450 1 - 680 2.981250e+00 4.084746e+00 9.948784e+00 91800 1 - 690 4.187500e+00 4.084746e+00 1.011872e+01 93150 1 - 700 4.500000e+00 4.084746e+00 1.028642e+01 94500 1 - 710 3.225000e+00 4.084746e+00 1.045848e+01 95850 1 - 720 4.375000e+00 4.084746e+00 1.063083e+01 97200 1 - 730 2.650000e+00 4.084746e+00 1.083783e+01 98550 1 - 740 3.250000e+00 4.084746e+00 1.100563e+01 99900 1 - 750 4.725000e+00 4.084746e+00 1.118854e+01 101250 1 - 760 3.375000e+00 4.084746e+00 1.137177e+01 102600 1 - 770 5.375000e+00 4.084746e+00 1.154874e+01 103950 1 - 780 4.068750e+00 4.084746e+00 1.172674e+01 105300 1 - 790 4.412500e+00 4.084746e+00 1.190625e+01 106650 1 - 800 4.350000e+00 4.084746e+00 1.208874e+01 108000 1 - 810 5.887500e+00 4.084746e+00 1.227040e+01 109350 1 - 820 4.912500e+00 4.084746e+00 1.244445e+01 110700 1 - 830 4.387500e+00 4.084746e+00 1.261354e+01 112050 1 - 840 3.675000e+00 4.084746e+00 1.279480e+01 113400 1 - 850 5.375000e+00 4.084746e+00 1.296941e+01 114750 1 - 860 3.562500e+00 4.084746e+00 1.316130e+01 116100 1 - 870 3.075000e+00 4.084746e+00 1.334805e+01 117450 1 - 880 3.625000e+00 4.084746e+00 1.353763e+01 118800 1 - 890 2.937500e+00 4.084746e+00 1.371442e+01 120150 1 - 900 4.450000e+00 4.084746e+00 1.390157e+01 121500 1 - 910 4.200000e+00 4.084746e+00 1.410609e+01 122850 1 - 920 3.687500e+00 4.084746e+00 1.428934e+01 124200 1 - 930 4.725000e+00 4.084746e+00 1.447056e+01 125550 1 - 940 4.018750e+00 4.084746e+00 1.463890e+01 126900 1 - 950 4.675000e+00 4.084746e+00 1.480195e+01 128250 1 - 960 3.375000e+00 4.084746e+00 1.496423e+01 129600 1 - 970 3.812500e+00 4.084746e+00 1.512657e+01 130950 1 - 980 3.112500e+00 4.084746e+00 1.529611e+01 132300 1 - 990 3.600000e+00 4.084746e+00 1.547750e+01 133650 1 - 1000 5.500000e+00 4.084746e+00 1.565246e+01 135000 1 - 1010 3.187500e+00 4.084746e+00 1.582274e+01 136350 1 - 1020 4.900000e+00 4.084746e+00 1.599779e+01 137700 1 - 1030 3.637500e+00 4.084746e+00 1.618343e+01 139050 1 - 1040 3.975000e+00 4.084746e+00 1.635629e+01 140400 1 - 1050 4.750000e+00 4.084746e+00 1.655779e+01 141750 1 - 1060 4.437500e+00 4.084746e+00 1.675049e+01 143100 1 - 1070 5.000000e+00 4.084746e+00 1.693024e+01 144450 1 - 1080 4.143750e+00 4.084746e+00 1.711242e+01 145800 1 - 1090 5.625000e+00 4.084746e+00 1.728857e+01 147150 1 - 1100 3.475000e+00 4.084746e+00 1.747086e+01 148500 1 - 1110 4.156250e+00 4.084746e+00 1.766315e+01 149850 1 - 1120 4.450000e+00 4.084746e+00 1.785749e+01 151200 1 - 1130 3.312500e+00 4.084741e+00 1.805663e+01 152550 1 - 1140 5.375000e+00 4.084741e+00 1.823556e+01 153900 1 - 1150 4.800000e+00 4.084737e+00 1.843092e+01 155250 1 - 1160 3.300000e+00 4.084737e+00 1.861697e+01 156600 1 - 1170 4.356250e+00 4.084737e+00 1.879954e+01 157950 1 - 1180 3.900000e+00 4.084737e+00 1.901167e+01 159300 1 - 1190 4.450000e+00 4.084737e+00 1.920076e+01 160650 1 - 1200 5.156250e+00 4.084737e+00 1.939178e+01 162000 1 - 1210 4.500000e+00 4.084737e+00 1.957136e+01 163350 1 - 1220 4.875000e+00 4.084737e+00 1.976497e+01 164700 1 - 1230 4.000000e+00 4.084737e+00 1.994862e+01 166050 1 - 1233 5.218750e+00 4.084737e+00 2.000150e+01 166455 1 + 10 5.250000e+00 4.888859e+00 1.712432e-01 1350 1 + 20 4.350000e+00 4.105855e+00 2.557001e-01 2700 1 + 30 5.000000e+00 4.100490e+00 3.899250e-01 4050 1 + 40 3.500000e+00 4.097376e+00 4.926381e-01 5400 1 + 50 5.250000e+00 4.095859e+00 6.009200e-01 6750 1 + 60 3.643750e+00 4.093342e+00 7.120681e-01 8100 1 + 70 2.643750e+00 4.091818e+00 8.236940e-01 9450 1 + 80 5.087500e+00 4.091591e+00 9.382150e-01 10800 1 + 90 5.062500e+00 4.091309e+00 1.052949e+00 12150 1 + 100 4.843750e+00 4.087004e+00 1.177181e+00 13500 1 + 110 3.437500e+00 4.086094e+00 1.301021e+00 14850 1 + 120 3.375000e+00 4.085926e+00 1.426546e+00 16200 1 + 130 5.025000e+00 4.085866e+00 1.556027e+00 17550 1 + 140 5.000000e+00 4.085734e+00 1.687912e+00 18900 1 + 150 3.500000e+00 4.085655e+00 1.818401e+00 20250 1 + 160 4.281250e+00 4.085454e+00 1.944509e+00 21600 1 + 170 4.562500e+00 4.085425e+00 2.072280e+00 22950 1 + 180 5.768750e+00 4.085425e+00 2.200540e+00 24300 1 + 190 3.468750e+00 4.085359e+00 2.335219e+00 25650 1 + 200 4.131250e+00 4.085225e+00 2.469636e+00 27000 1 + 210 4.512500e+00 4.085157e+00 2.603997e+00 28350 1 + 220 4.900000e+00 4.085153e+00 2.737233e+00 29700 1 + 230 4.025000e+00 4.085134e+00 2.874589e+00 31050 1 + 240 4.468750e+00 4.085116e+00 3.014505e+00 32400 1 + 250 4.062500e+00 4.085075e+00 3.192237e+00 33750 1 + 260 4.875000e+00 4.085037e+00 3.331058e+00 35100 1 + 270 3.850000e+00 4.085011e+00 3.470104e+00 36450 1 + 280 4.912500e+00 4.084992e+00 3.611678e+00 37800 1 + 290 2.987500e+00 4.084986e+00 3.758030e+00 39150 1 + 300 3.825000e+00 4.084957e+00 3.904765e+00 40500 1 + 310 3.250000e+00 4.084911e+00 4.053302e+00 41850 1 + 320 3.600000e+00 4.084896e+00 4.201271e+00 43200 1 + 330 3.925000e+00 4.084896e+00 4.337336e+00 44550 1 + 340 4.500000e+00 4.084893e+00 4.481930e+00 45900 1 + 350 5.000000e+00 4.084891e+00 4.630258e+00 47250 1 + 360 3.075000e+00 4.084866e+00 4.781391e+00 48600 1 + 370 3.500000e+00 4.084861e+00 4.931129e+00 49950 1 + 380 3.356250e+00 4.084857e+00 5.080989e+00 51300 1 + 390 5.500000e+00 4.084846e+00 5.238686e+00 52650 1 + 400 4.475000e+00 4.084846e+00 5.386836e+00 54000 1 + 410 3.750000e+00 4.084843e+00 5.537586e+00 55350 1 + 420 3.687500e+00 4.084843e+00 5.703979e+00 56700 1 + 430 4.337500e+00 4.084825e+00 5.860562e+00 58050 1 + 440 5.750000e+00 4.084825e+00 6.001830e+00 59400 1 + 450 4.925000e+00 4.084792e+00 6.161568e+00 60750 1 + 460 3.600000e+00 4.084792e+00 6.316679e+00 62100 1 + 470 4.387500e+00 4.084792e+00 6.466405e+00 63450 1 + 480 4.000000e+00 4.084792e+00 6.652086e+00 64800 1 + 490 2.975000e+00 4.084788e+00 6.808310e+00 66150 1 + 500 3.125000e+00 4.084788e+00 6.962584e+00 67500 1 + 510 4.250000e+00 4.084788e+00 7.124767e+00 68850 1 + 520 4.512500e+00 4.084786e+00 7.279242e+00 70200 1 + 530 3.875000e+00 4.084786e+00 7.446755e+00 71550 1 + 540 4.387500e+00 4.084781e+00 7.607976e+00 72900 1 + 550 5.281250e+00 4.084780e+00 7.772215e+00 74250 1 + 560 4.650000e+00 4.084780e+00 7.923224e+00 75600 1 + 570 3.062500e+00 4.084780e+00 8.077300e+00 76950 1 + 580 3.187500e+00 4.084780e+00 8.227366e+00 78300 1 + 590 3.812500e+00 4.084780e+00 8.374758e+00 79650 1 + 600 3.637500e+00 4.084774e+00 8.532806e+00 81000 1 + 610 3.950000e+00 4.084765e+00 8.689049e+00 82350 1 + 620 4.625000e+00 4.084760e+00 8.847563e+00 83700 1 + 630 4.218750e+00 4.084760e+00 9.008270e+00 85050 1 + 640 3.025000e+00 4.084755e+00 9.168273e+00 86400 1 + 650 2.993750e+00 4.084751e+00 9.324117e+00 87750 1 + 660 3.262500e+00 4.084746e+00 9.482478e+00 89100 1 + 670 3.625000e+00 4.084746e+00 9.644065e+00 90450 1 + 680 2.981250e+00 4.084746e+00 9.838071e+00 91800 1 + 690 4.187500e+00 4.084746e+00 9.996642e+00 93150 1 + 700 4.500000e+00 4.084746e+00 1.015159e+01 94500 1 + 710 3.225000e+00 4.084746e+00 1.030851e+01 95850 1 + 720 4.375000e+00 4.084746e+00 1.046806e+01 97200 1 + 730 2.650000e+00 4.084746e+00 1.063247e+01 98550 1 + 740 3.250000e+00 4.084746e+00 1.079002e+01 99900 1 + 750 4.725000e+00 4.084746e+00 1.096502e+01 101250 1 + 760 3.375000e+00 4.084746e+00 1.113593e+01 102600 1 + 770 5.375000e+00 4.084746e+00 1.130502e+01 103950 1 + 780 4.068750e+00 4.084746e+00 1.147862e+01 105300 1 + 790 4.412500e+00 4.084746e+00 1.165918e+01 106650 1 + 800 4.350000e+00 4.084746e+00 1.183344e+01 108000 1 + 810 5.887500e+00 4.084746e+00 1.201065e+01 109350 1 + 820 4.912500e+00 4.084746e+00 1.218002e+01 110700 1 + 830 4.387500e+00 4.084746e+00 1.234002e+01 112050 1 + 840 3.675000e+00 4.084746e+00 1.250737e+01 113400 1 + 850 5.375000e+00 4.084746e+00 1.267340e+01 114750 1 + 860 3.562500e+00 4.084746e+00 1.287131e+01 116100 1 + 870 3.075000e+00 4.084746e+00 1.304815e+01 117450 1 + 880 3.625000e+00 4.084746e+00 1.321521e+01 118800 1 + 890 2.937500e+00 4.084746e+00 1.337899e+01 120150 1 + 900 4.450000e+00 4.084746e+00 1.355284e+01 121500 1 + 910 4.200000e+00 4.084746e+00 1.372446e+01 122850 1 + 920 3.687500e+00 4.084746e+00 1.390016e+01 124200 1 + 930 4.725000e+00 4.084746e+00 1.407677e+01 125550 1 + 940 4.018750e+00 4.084746e+00 1.424514e+01 126900 1 + 950 4.675000e+00 4.084746e+00 1.441165e+01 128250 1 + 960 3.375000e+00 4.084746e+00 1.457437e+01 129600 1 + 970 3.812500e+00 4.084746e+00 1.474051e+01 130950 1 + 980 3.112500e+00 4.084746e+00 1.490928e+01 132300 1 + 990 3.600000e+00 4.084746e+00 1.509131e+01 133650 1 + 1000 5.500000e+00 4.084746e+00 1.528799e+01 135000 1 + 1010 3.187500e+00 4.084746e+00 1.545659e+01 136350 1 + 1020 4.900000e+00 4.084746e+00 1.563010e+01 137700 1 + 1030 3.637500e+00 4.084746e+00 1.581252e+01 139050 1 + 1040 3.975000e+00 4.084746e+00 1.598426e+01 140400 1 + 1050 4.750000e+00 4.084746e+00 1.616359e+01 141750 1 + 1060 4.437500e+00 4.084746e+00 1.635204e+01 143100 1 + 1070 5.000000e+00 4.084746e+00 1.653067e+01 144450 1 + 1080 4.143750e+00 4.084746e+00 1.671378e+01 145800 1 + 1090 5.625000e+00 4.084746e+00 1.688430e+01 147150 1 + 1100 3.475000e+00 4.084746e+00 1.706820e+01 148500 1 + 1110 4.156250e+00 4.084746e+00 1.725233e+01 149850 1 + 1120 4.450000e+00 4.084746e+00 1.743011e+01 151200 1 + 1130 3.312500e+00 4.084741e+00 1.761266e+01 152550 1 + 1140 5.375000e+00 4.084741e+00 1.780811e+01 153900 1 + 1150 4.800000e+00 4.084737e+00 1.799549e+01 155250 1 + 1160 3.300000e+00 4.084737e+00 1.817865e+01 156600 1 + 1170 4.356250e+00 4.084737e+00 1.835846e+01 157950 1 + 1180 3.900000e+00 4.084737e+00 1.854494e+01 159300 1 + 1190 4.450000e+00 4.084737e+00 1.873824e+01 160650 1 + 1200 5.156250e+00 4.084737e+00 1.892452e+01 162000 1 + 1210 4.500000e+00 4.084737e+00 1.909851e+01 163350 1 + 1220 4.875000e+00 4.084737e+00 1.929208e+01 164700 1 + 1230 4.000000e+00 4.084737e+00 1.947183e+01 166050 1 + 1240 4.062500e+00 4.084737e+00 1.965651e+01 167400 1 + 1250 5.450000e+00 4.084737e+00 1.986792e+01 168750 1 + 1257 4.125000e+00 4.084737e+00 2.000116e+01 169695 1 ------------------------------------------------------------------- status : time_limit -total time (s) : 2.000150e+01 -total solves : 166455 +total time (s) : 2.000116e+01 +total solves : 169695 best bound : 4.084737e+00 -simulation ci : 4.072644e+00 ± 4.044792e-02 +simulation ci : 4.071924e+00 ± 4.030230e-02 numeric issues : 0 ------------------------------------------------------------------- @@ -1297,29 +1299,29 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 5.250000e+00 5.621506e+00 1.820130e-01 1350 1 - 20 5.625000e+00 4.738243e+00 5.347002e-01 2700 1 - 30 4.800000e+00 4.043340e+00 9.793801e-01 4050 1 - 40 2.981250e+00 4.039693e+00 1.528040e+00 5400 1 - 50 4.875000e+00 4.039162e+00 2.258422e+00 6750 1 - 60 4.200000e+00 4.039061e+00 3.131524e+00 8100 1 - 70 3.625000e+00 4.039083e+00 4.117996e+00 9450 1 - 80 5.168750e+00 4.039000e+00 5.269657e+00 10800 1 - 90 4.725000e+00 4.038902e+00 6.521223e+00 12150 1 - 100 4.200000e+00 4.038847e+00 7.835695e+00 13500 1 - 110 5.156250e+00 4.038832e+00 9.323179e+00 14850 1 - 120 5.200000e+00 4.038784e+00 1.088657e+01 16200 1 - 130 5.437500e+00 4.038795e+00 1.253203e+01 17550 1 - 140 5.218750e+00 4.038777e+00 1.432849e+01 18900 1 - 150 3.631250e+00 4.038777e+00 1.637355e+01 20250 1 - 160 2.650000e+00 4.038777e+00 1.844013e+01 21600 1 - 168 4.237500e+00 4.038770e+00 2.008583e+01 22680 1 + 10 3.875000e+00 4.353130e+00 2.004929e-01 1350 1 + 20 2.981250e+00 4.046840e+00 5.817509e-01 2700 1 + 30 4.125000e+00 4.044475e+00 1.076938e+00 4050 1 + 40 4.875000e+00 4.041075e+00 1.732080e+00 5400 1 + 50 4.275000e+00 4.040539e+00 2.433584e+00 6750 1 + 60 4.843750e+00 4.040288e+00 3.289070e+00 8100 1 + 70 5.625000e+00 4.039205e+00 4.243661e+00 9450 1 + 80 4.375000e+00 4.039110e+00 5.368436e+00 10800 1 + 90 4.900000e+00 4.039004e+00 6.512935e+00 12150 1 + 100 2.893750e+00 4.038938e+00 7.844159e+00 13500 1 + 110 5.287500e+00 4.038884e+00 9.266460e+00 14850 1 + 120 4.250000e+00 4.038839e+00 1.079688e+01 16200 1 + 130 4.012500e+00 4.038776e+00 1.257979e+01 17550 1 + 140 4.368750e+00 4.038776e+00 1.428642e+01 18900 1 + 150 4.875000e+00 4.038774e+00 1.617734e+01 20250 1 + 160 4.368750e+00 4.037591e+00 1.818796e+01 21600 1 + 169 4.500000e+00 4.037578e+00 2.005415e+01 22815 1 ------------------------------------------------------------------- status : time_limit -total time (s) : 2.008583e+01 -total solves : 22680 -best bound : 4.038770e+00 -simulation ci : 4.104824e+00 ± 1.171821e-01 +total time (s) : 2.005415e+01 +total solves : 22815 +best bound : 4.037578e+00 +simulation ci : 4.050816e+00 ± 1.155829e-01 numeric issues : 0 ------------------------------------------------------------------- @@ -1350,19 +1352,20 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 3.092749e+00 1.166404e+00 3.928251e-01 1680 1 - 20 2.656862e+00 1.167365e+00 4.926121e-01 2560 1 - 30 3.085472e+00 1.167365e+00 8.912382e-01 4240 1 - 40 3.293473e+00 1.167365e+00 9.923971e-01 5120 1 - 50 3.112712e+00 1.167365e+00 1.393122e+00 6800 1 - 60 3.239056e+00 1.167410e+00 1.498153e+00 7680 1 - 64 3.106758e+00 1.167410e+00 1.540112e+00 8032 1 + 10 3.785215e+00 1.166861e+00 3.889260e-01 1680 1 + 20 2.812407e+00 1.167299e+00 4.863241e-01 2560 1 + 30 2.828561e+00 1.167299e+00 8.810191e-01 4240 1 + 40 3.470837e+00 1.167299e+00 9.838631e-01 5120 1 + 50 2.832678e+00 1.167299e+00 1.378870e+00 6800 1 + 60 3.234686e+00 1.167299e+00 1.485548e+00 7680 1 + 70 3.192636e+00 1.167299e+00 1.885161e+00 9360 1 + 80 2.722614e+00 1.167299e+00 1.993683e+00 10240 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.540112e+00 -total solves : 8032 -best bound : 1.167410e+00 -simulation ci : 3.369436e+00 ± 1.052982e-01 +total time (s) : 1.993683e+00 +total solves : 10240 +best bound : 1.167299e+00 +simulation ci : 3.241472e+00 ± 9.570211e-02 numeric issues : 0 ------------------------------------------------------------------- @@ -1394,16 +1397,16 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -4.000000e+01 -5.809615e+01 3.280902e-02 78 1 - 20 -4.000000e+01 -5.809615e+01 6.489182e-02 148 1 - 30 -4.000000e+01 -5.809615e+01 1.038380e-01 226 1 - 40 -4.000000e+01 -5.809615e+01 1.381290e-01 296 1 + 10 -4.700000e+01 -5.809615e+01 3.338099e-02 78 1 + 20 -4.700000e+01 -5.809615e+01 6.633687e-02 148 1 + 30 -4.700000e+01 -5.809615e+01 1.058669e-01 226 1 + 40 -4.700000e+01 -5.809615e+01 1.393440e-01 296 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.381290e-01 +total time (s) : 1.393440e-01 total solves : 296 best bound : -5.809615e+01 -simulation ci : -6.053750e+01 ± 8.436950e+00 +simulation ci : -5.821250e+01 ± 8.353903e+00 numeric issues : 0 ------------------------------------------------------------------- @@ -1435,16 +1438,16 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -4.700000e+01 -6.196125e+01 4.201603e-02 138 1 - 20 -4.700000e+01 -6.196125e+01 8.031297e-02 258 1 - 30 -4.000000e+01 -6.196125e+01 1.318018e-01 396 1 - 40 -4.000000e+01 -6.196125e+01 1.705229e-01 516 1 + 10 -7.500000e+01 -6.196125e+01 4.039788e-02 138 1 + 20 -7.500000e+01 -6.196125e+01 7.732701e-02 258 1 + 30 -4.000000e+01 -6.196125e+01 1.287961e-01 396 1 + 40 -4.000000e+01 -6.196125e+01 1.674640e-01 516 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.705229e-01 +total time (s) : 1.674640e-01 total solves : 516 best bound : -6.196125e+01 -simulation ci : -5.191250e+01 ± 5.053380e+00 +simulation ci : -5.753750e+01 ± 6.415492e+00 numeric issues : 0 ------------------------------------------------------------------- @@ -1476,16 +1479,16 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -8.200000e+01 -6.546793e+01 8.193111e-02 462 1 - 20 -4.000000e+01 -6.546793e+01 1.442950e-01 852 1 - 30 -4.000000e+01 -6.546793e+01 2.659330e-01 1314 1 - 40 -5.900000e+01 -6.546793e+01 3.300650e-01 1704 1 + 10 -7.000000e+01 -6.546793e+01 7.961798e-02 462 1 + 20 -6.300000e+01 -6.546793e+01 1.399961e-01 852 1 + 30 -4.000000e+01 -6.546793e+01 2.566769e-01 1314 1 + 40 -8.200000e+01 -6.546793e+01 3.185890e-01 1704 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.300650e-01 +total time (s) : 3.185890e-01 total solves : 1704 best bound : -6.546793e+01 -simulation ci : -5.996250e+01 ± 4.578408e+00 +simulation ci : -6.206250e+01 ± 4.415467e+00 numeric issues : 0 ------------------------------------------------------------------- @@ -1516,14 +1519,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1L 6.000000e+00 1.200000e+01 4.302812e-02 11 1 - 40L 1.200000e+01 8.000000e+00 4.347019e-01 602 1 + 1L 6.000000e+00 1.200000e+01 4.302001e-02 11 1 + 40L 1.200000e+01 8.000000e+00 4.238839e-01 602 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 4.347019e-01 +total time (s) : 4.238839e-01 total solves : 602 best bound : 8.000000e+00 -simulation ci : 8.250000e+00 ± 9.356503e-01 +simulation ci : 8.100000e+00 ± 9.693887e-01 numeric issues : 0 ------------------------------------------------------------------- @@ -1554,14 +1557,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 -9.800000e+04 4.922260e+05 9.035993e-02 6 1 - 40 1.093500e+05 1.083900e+05 1.199400e-01 240 1 + 1 -9.800000e+04 4.922260e+05 8.714199e-02 6 1 + 40 1.093500e+05 1.083900e+05 1.163521e-01 240 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.199400e-01 +total time (s) : 1.163521e-01 total solves : 240 best bound : 1.083900e+05 -simulation ci : 9.552212e+04 ± 1.983096e+04 +simulation ci : 1.008813e+05 ± 2.001742e+04 numeric issues : 0 ------------------------------------------------------------------- diff --git a/previews/PR811/examples/SDDP_0.0.log b/previews/PR811/examples/SDDP_0.0.log index 1ecc8e296..0cd440ea3 100644 --- a/previews/PR811/examples/SDDP_0.0.log +++ b/previews/PR811/examples/SDDP_0.0.log @@ -19,11 +19,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 0.000000e+00 1.050186e-02 36 1 - 10 0.000000e+00 0.000000e+00 3.173590e-02 360 1 + 1 0.000000e+00 0.000000e+00 9.330988e-03 36 1 + 10 0.000000e+00 0.000000e+00 2.937508e-02 360 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.173590e-02 +total time (s) : 2.937508e-02 total solves : 360 best bound : 0.000000e+00 simulation ci : 0.000000e+00 ± 0.000000e+00 diff --git a/previews/PR811/examples/SDDP_0.0625.log b/previews/PR811/examples/SDDP_0.0625.log index c1008cd01..f1e58a371 100644 --- a/previews/PR811/examples/SDDP_0.0625.log +++ b/previews/PR811/examples/SDDP_0.0625.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.437500e+01 5.937500e+01 3.335953e-03 3375 1 - 10 3.750000e+01 5.938557e+01 3.399801e-02 3699 1 + 1 3.437500e+01 5.937500e+01 3.075838e-03 3375 1 + 10 3.750000e+01 5.938557e+01 3.089690e-02 3699 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.399801e-02 +total time (s) : 3.089690e-02 total solves : 3699 best bound : 5.938557e+01 simulation ci : 5.906250e+01 ± 1.352595e+01 diff --git a/previews/PR811/examples/SDDP_0.125.log b/previews/PR811/examples/SDDP_0.125.log index d58438d75..3f33a87c5 100644 --- a/previews/PR811/examples/SDDP_0.125.log +++ b/previews/PR811/examples/SDDP_0.125.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.675000e+02 1.129545e+02 3.136873e-03 1891 1 - 10 1.362500e+02 1.129771e+02 3.280091e-02 2215 1 + 1 1.675000e+02 1.129545e+02 2.783060e-03 1891 1 + 10 1.362500e+02 1.129771e+02 3.028989e-02 2215 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.280091e-02 +total time (s) : 3.028989e-02 total solves : 2215 best bound : 1.129771e+02 simulation ci : 1.176375e+02 ± 1.334615e+01 diff --git a/previews/PR811/examples/SDDP_0.25.log b/previews/PR811/examples/SDDP_0.25.log index 21e5a2dfd..7909bb9cb 100644 --- a/previews/PR811/examples/SDDP_0.25.log +++ b/previews/PR811/examples/SDDP_0.25.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.887500e+02 1.995243e+02 3.022909e-03 1149 1 - 10 2.962500e+02 2.052855e+02 3.225207e-02 1473 1 + 1 1.887500e+02 1.995243e+02 2.761126e-03 1149 1 + 10 2.962500e+02 2.052855e+02 2.954102e-02 1473 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.225207e-02 +total time (s) : 2.954102e-02 total solves : 1473 best bound : 2.052855e+02 simulation ci : 2.040201e+02 ± 3.876873e+01 diff --git a/previews/PR811/examples/SDDP_0.375.log b/previews/PR811/examples/SDDP_0.375.log index 7493e3d34..ef12a7544 100644 --- a/previews/PR811/examples/SDDP_0.375.log +++ b/previews/PR811/examples/SDDP_0.375.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.562500e+02 2.788373e+02 3.476858e-03 2262 1 - 10 2.375000e+02 2.795671e+02 3.591585e-02 2586 1 + 1 2.562500e+02 2.788373e+02 3.196001e-03 2262 1 + 10 2.375000e+02 2.795671e+02 3.301382e-02 2586 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.591585e-02 +total time (s) : 3.301382e-02 total solves : 2586 best bound : 2.795671e+02 simulation ci : 2.375000e+02 ± 3.099032e+01 diff --git a/previews/PR811/examples/SDDP_0.5.log b/previews/PR811/examples/SDDP_0.5.log index fd8dae3f9..7789aefd9 100644 --- a/previews/PR811/examples/SDDP_0.5.log +++ b/previews/PR811/examples/SDDP_0.5.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 4.850000e+02 3.349793e+02 3.319025e-03 778 1 - 10 3.550000e+02 3.468286e+02 3.398108e-02 1102 1 + 1 4.850000e+02 3.349793e+02 3.025055e-03 778 1 + 10 3.550000e+02 3.468286e+02 3.070188e-02 1102 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.398108e-02 +total time (s) : 3.070188e-02 total solves : 1102 best bound : 3.468286e+02 simulation ci : 3.948309e+02 ± 7.954180e+01 diff --git a/previews/PR811/examples/SDDP_0.625.log b/previews/PR811/examples/SDDP_0.625.log index 3d2a43a63..f21e54b1b 100644 --- a/previews/PR811/examples/SDDP_0.625.log +++ b/previews/PR811/examples/SDDP_0.625.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.812500e+02 4.072952e+02 3.874063e-03 2633 1 - 10 5.818750e+02 4.080500e+02 3.808999e-02 2957 1 + 1 3.812500e+02 4.072952e+02 3.535986e-03 2633 1 + 10 5.818750e+02 4.080500e+02 3.540611e-02 2957 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.808999e-02 +total time (s) : 3.540611e-02 total solves : 2957 best bound : 4.080500e+02 simulation ci : 4.235323e+02 ± 1.029245e+02 diff --git a/previews/PR811/examples/SDDP_0.75.log b/previews/PR811/examples/SDDP_0.75.log index b41827b7c..fec38938a 100644 --- a/previews/PR811/examples/SDDP_0.75.log +++ b/previews/PR811/examples/SDDP_0.75.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.737500e+02 4.626061e+02 3.686905e-03 1520 1 - 10 2.450000e+02 4.658509e+02 3.725886e-02 1844 1 + 1 3.737500e+02 4.626061e+02 3.305912e-03 1520 1 + 10 2.450000e+02 4.658509e+02 3.355384e-02 1844 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.725886e-02 +total time (s) : 3.355384e-02 total solves : 1844 best bound : 4.658509e+02 simulation ci : 3.907376e+02 ± 9.045105e+01 diff --git a/previews/PR811/examples/SDDP_0.875.log b/previews/PR811/examples/SDDP_0.875.log index 38d681420..bb126ff41 100644 --- a/previews/PR811/examples/SDDP_0.875.log +++ b/previews/PR811/examples/SDDP_0.875.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 8.525000e+02 5.197742e+02 3.797054e-03 3004 1 - 10 4.493750e+02 5.211793e+02 3.929520e-02 3328 1 + 1 8.525000e+02 5.197742e+02 3.447056e-03 3004 1 + 10 4.493750e+02 5.211793e+02 3.638792e-02 3328 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.929520e-02 +total time (s) : 3.638792e-02 total solves : 3328 best bound : 5.211793e+02 simulation ci : 5.268125e+02 ± 1.227709e+02 diff --git a/previews/PR811/examples/SDDP_1.0.log b/previews/PR811/examples/SDDP_1.0.log index f40074d17..bdd9abf6f 100644 --- a/previews/PR811/examples/SDDP_1.0.log +++ b/previews/PR811/examples/SDDP_1.0.log @@ -20,11 +20,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 6.750000e+02 5.500000e+02 3.112078e-03 407 1 - 10 4.500000e+02 5.733959e+02 3.222489e-02 731 1 + 1 6.750000e+02 5.500000e+02 2.792835e-03 407 1 + 10 4.500000e+02 5.733959e+02 2.948785e-02 731 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.222489e-02 +total time (s) : 2.948785e-02 total solves : 731 best bound : 5.733959e+02 simulation ci : 5.000000e+02 ± 1.079583e+02 diff --git a/previews/PR811/examples/StochDynamicProgramming.jl_multistock/index.html b/previews/PR811/examples/StochDynamicProgramming.jl_multistock/index.html index eb702a213..34eca95cf 100644 --- a/previews/PR811/examples/StochDynamicProgramming.jl_multistock/index.html +++ b/previews/PR811/examples/StochDynamicProgramming.jl_multistock/index.html @@ -80,21 +80,21 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -3.878303e+00 -4.434982e+00 1.954072e-01 1400 1 - 20 -4.262885e+00 -4.399265e+00 3.146410e-01 2800 1 - 30 -3.075162e+00 -4.382527e+00 4.405310e-01 4200 1 - 40 -3.761147e+00 -4.369587e+00 5.749981e-01 5600 1 - 50 -4.323162e+00 -4.362199e+00 7.177551e-01 7000 1 - 60 -3.654943e+00 -4.358401e+00 8.631310e-01 8400 1 - 70 -4.010883e+00 -4.357368e+00 1.069839e+00 9800 1 - 80 -4.314412e+00 -4.355714e+00 1.222770e+00 11200 1 - 90 -4.542422e+00 -4.353708e+00 1.375749e+00 12600 1 - 100 -4.178952e+00 -4.351685e+00 1.525265e+00 14000 1 + 10 -3.878303e+00 -4.434982e+00 1.908009e-01 1400 1 + 20 -4.262885e+00 -4.399265e+00 3.070920e-01 2800 1 + 30 -3.075162e+00 -4.382527e+00 4.300220e-01 4200 1 + 40 -3.761147e+00 -4.369587e+00 5.593009e-01 5600 1 + 50 -4.323162e+00 -4.362199e+00 7.511120e-01 7000 1 + 60 -3.654943e+00 -4.358401e+00 8.881328e-01 8400 1 + 70 -4.010883e+00 -4.357368e+00 1.027195e+00 9800 1 + 80 -4.314412e+00 -4.355714e+00 1.171472e+00 11200 1 + 90 -4.542422e+00 -4.353708e+00 1.321075e+00 12600 1 + 100 -4.178952e+00 -4.351685e+00 1.464739e+00 14000 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.525265e+00 +total time (s) : 1.464739e+00 total solves : 14000 best bound : -4.351685e+00 simulation ci : -4.246786e+00 ± 8.703997e-02 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/StochDynamicProgramming.jl_stock/index.html b/previews/PR811/examples/StochDynamicProgramming.jl_stock/index.html index 1ef37de21..a1a9b1e64 100644 --- a/previews/PR811/examples/StochDynamicProgramming.jl_stock/index.html +++ b/previews/PR811/examples/StochDynamicProgramming.jl_stock/index.html @@ -57,18 +57,18 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -1.573154e+00 -1.474247e+00 6.967521e-02 1050 1 - 20 -1.346690e+00 -1.471483e+00 1.089730e-01 1600 1 - 30 -1.308031e+00 -1.471307e+00 1.949091e-01 2650 1 - 40 -1.401200e+00 -1.471167e+00 2.374411e-01 3200 1 - 50 -1.557483e+00 -1.471097e+00 3.282430e-01 4250 1 - 60 -1.534169e+00 -1.471075e+00 3.747780e-01 4800 1 - 65 -1.689864e+00 -1.471075e+00 3.981712e-01 5075 1 + 10 -1.573154e+00 -1.474247e+00 6.817293e-02 1050 1 + 20 -1.346690e+00 -1.471483e+00 1.061029e-01 1600 1 + 30 -1.308031e+00 -1.471307e+00 1.872530e-01 2650 1 + 40 -1.401200e+00 -1.471167e+00 2.279379e-01 3200 1 + 50 -1.557483e+00 -1.471097e+00 3.135750e-01 4250 1 + 60 -1.534169e+00 -1.471075e+00 3.576341e-01 4800 1 + 65 -1.689864e+00 -1.471075e+00 3.798909e-01 5075 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.981712e-01 +total time (s) : 3.798909e-01 total solves : 5075 best bound : -1.471075e+00 simulation ci : -1.484094e+00 ± 4.058993e-02 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/StructDualDynProg.jl_prob5.2_2stages/index.html b/previews/PR811/examples/StructDualDynProg.jl_prob5.2_2stages/index.html index 62870f540..424fa262c 100644 --- a/previews/PR811/examples/StructDualDynProg.jl_prob5.2_2stages/index.html +++ b/previews/PR811/examples/StructDualDynProg.jl_prob5.2_2stages/index.html @@ -85,16 +85,16 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 3.455904e+05 3.147347e+05 8.262157e-03 54 1 - 20 3.336455e+05 3.402383e+05 1.447606e-02 104 1 - 30 3.337559e+05 3.403155e+05 2.172709e-02 158 1 - 40 3.337559e+05 3.403155e+05 2.874899e-02 208 1 - 48 3.337559e+05 3.403155e+05 3.487802e-02 248 1 + 10 3.455904e+05 3.147347e+05 7.987022e-03 54 1 + 20 3.336455e+05 3.402383e+05 1.392007e-02 104 1 + 30 3.337559e+05 3.403155e+05 2.099895e-02 158 1 + 40 3.337559e+05 3.403155e+05 2.778602e-02 208 1 + 48 3.337559e+05 3.403155e+05 3.368807e-02 248 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.487802e-02 +total time (s) : 3.368807e-02 total solves : 248 best bound : 3.403155e+05 simulation ci : 1.351676e+08 ± 1.785770e+08 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/StructDualDynProg.jl_prob5.2_3stages/index.html b/previews/PR811/examples/StructDualDynProg.jl_prob5.2_3stages/index.html index ba217eaca..5e3df0ccd 100644 --- a/previews/PR811/examples/StructDualDynProg.jl_prob5.2_3stages/index.html +++ b/previews/PR811/examples/StructDualDynProg.jl_prob5.2_3stages/index.html @@ -81,16 +81,16 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 4.403329e+05 3.509666e+05 1.330900e-02 92 1 - 20 4.055335e+05 4.054833e+05 2.407002e-02 172 1 - 30 3.959476e+05 4.067125e+05 3.729391e-02 264 1 - 40 3.959476e+05 4.067125e+05 5.070090e-02 344 1 - 47 3.959476e+05 4.067125e+05 6.092501e-02 400 1 + 10 4.403329e+05 3.509666e+05 1.372409e-02 92 1 + 20 4.055335e+05 4.054833e+05 2.413797e-02 172 1 + 30 3.959476e+05 4.067125e+05 3.714299e-02 264 1 + 40 3.959476e+05 4.067125e+05 5.035496e-02 344 1 + 47 3.959476e+05 4.067125e+05 6.017613e-02 400 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 6.092501e-02 +total time (s) : 6.017613e-02 total solves : 400 best bound : 4.067125e+05 simulation ci : 2.695623e+07 ± 3.645336e+07 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/agriculture_mccardle_farm/index.html b/previews/PR811/examples/agriculture_mccardle_farm/index.html index 04086e217..ef9516909 100644 --- a/previews/PR811/examples/agriculture_mccardle_farm/index.html +++ b/previews/PR811/examples/agriculture_mccardle_farm/index.html @@ -124,4 +124,4 @@ @test SDDP.calculate_bound(model) ≈ 4074.1391 atol = 1e-5 end -test_mccardle_farm_model()
Test Passed
+test_mccardle_farm_model()
Test Passed
diff --git a/previews/PR811/examples/air_conditioning/index.html b/previews/PR811/examples/air_conditioning/index.html index 5c732edda..9580d56d6 100644 --- a/previews/PR811/examples/air_conditioning/index.html +++ b/previews/PR811/examples/air_conditioning/index.html @@ -76,11 +76,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1L 7.000000e+04 6.166667e+04 5.622830e-01 8 1 - 40L 5.500000e+04 6.250000e+04 8.109930e-01 344 1 + 1L 7.000000e+04 6.166667e+04 5.616159e-01 8 1 + 40L 5.500000e+04 6.250000e+04 7.965860e-01 344 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 8.109930e-01 +total time (s) : 7.965860e-01 total solves : 344 best bound : 6.250000e+04 simulation ci : 6.091250e+04 ± 6.325667e+03 @@ -115,11 +115,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.000000e+04 6.250000e+04 3.826857e-03 8 1 - 20 6.000000e+04 6.250000e+04 4.415202e-02 172 1 + 1 3.000000e+04 6.250000e+04 3.710985e-03 8 1 + 20 6.000000e+04 6.250000e+04 4.263806e-02 172 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 4.415202e-02 +total time (s) : 4.263806e-02 total solves : 172 best bound : 6.250000e+04 simulation ci : 5.675000e+04 ± 6.792430e+03 @@ -127,4 +127,4 @@ ------------------------------------------------------------------- Lower bound is: 62500.0 -With first stage solutions 200.0 (production) and 100.0 (stored_production). +With first stage solutions 200.0 (production) and 100.0 (stored_production). diff --git a/previews/PR811/examples/air_conditioning_forward/index.html b/previews/PR811/examples/air_conditioning_forward/index.html index 7bc9998a3..89ed501be 100644 --- a/previews/PR811/examples/air_conditioning_forward/index.html +++ b/previews/PR811/examples/air_conditioning_forward/index.html @@ -37,4 +37,4 @@ iteration_limit = 10, ) Test.@test isapprox(SDDP.calculate_bound(non_convex), 62_500.0, atol = 0.1) -Test.@test isapprox(SDDP.calculate_bound(convex), 62_500.0, atol = 0.1)
Test Passed
+Test.@test isapprox(SDDP.calculate_bound(convex), 62_500.0, atol = 0.1)
Test Passed
diff --git a/previews/PR811/examples/all_blacks/index.html b/previews/PR811/examples/all_blacks/index.html index 3226498e8..6db33baeb 100644 --- a/previews/PR811/examples/all_blacks/index.html +++ b/previews/PR811/examples/all_blacks/index.html @@ -61,13 +61,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1L 6.000000e+00 9.000000e+00 3.972387e-02 6 1 - 20L 9.000000e+00 9.000000e+00 7.997894e-02 123 1 + 1L 6.000000e+00 9.000000e+00 3.953099e-02 6 1 + 20L 9.000000e+00 9.000000e+00 7.881713e-02 123 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.997894e-02 +total time (s) : 7.881713e-02 total solves : 123 best bound : 9.000000e+00 simulation ci : 8.850000e+00 ± 2.940000e-01 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/asset_management_simple/index.html b/previews/PR811/examples/asset_management_simple/index.html index 93ad27619..4cb83776f 100644 --- a/previews/PR811/examples/asset_management_simple/index.html +++ b/previews/PR811/examples/asset_management_simple/index.html @@ -74,19 +74,19 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 5 -5.684342e-14 1.184830e+00 1.324701e-02 87 1 - 10 5.012507e+01 1.508277e+00 1.992893e-02 142 1 - 15 -1.428571e+00 1.514085e+00 2.718711e-02 197 1 - 20 7.105427e-14 1.514085e+00 3.492689e-02 252 1 - 25 -3.979039e-13 1.514085e+00 9.082890e-02 339 1 - 30 -1.428571e+00 1.514085e+00 9.950495e-02 394 1 - 35 -1.428571e+00 1.514085e+00 1.088130e-01 449 1 - 40 0.000000e+00 1.514085e+00 1.187019e-01 504 1 + 5 -5.684342e-14 1.184830e+00 1.294804e-02 87 1 + 10 5.012507e+01 1.508277e+00 1.928401e-02 142 1 + 15 -1.428571e+00 1.514085e+00 2.620506e-02 197 1 + 20 7.105427e-14 1.514085e+00 3.358603e-02 252 1 + 25 -3.979039e-13 1.514085e+00 8.626199e-02 339 1 + 30 -1.428571e+00 1.514085e+00 9.451199e-02 394 1 + 35 -1.428571e+00 1.514085e+00 1.033161e-01 449 1 + 40 0.000000e+00 1.514085e+00 1.364520e-01 504 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.187019e-01 +total time (s) : 1.364520e-01 total solves : 504 best bound : 1.514085e+00 simulation ci : 2.863132e+00 ± 6.778637e+00 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/asset_management_stagewise/index.html b/previews/PR811/examples/asset_management_stagewise/index.html index e4d2e5367..fd2903510 100644 --- a/previews/PR811/examples/asset_management_stagewise/index.html +++ b/previews/PR811/examples/asset_management_stagewise/index.html @@ -91,14 +91,14 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 1.100409e+00 1.301856e+00 1.650801e-01 278 1 - 20 1.263098e+01 1.278410e+00 1.862741e-01 428 1 - 30 -5.003795e+01 1.278410e+00 2.207019e-01 706 1 - 40 6.740000e+00 1.278410e+00 2.450829e-01 856 1 - 44 1.111084e+01 1.278410e+00 2.551520e-01 916 1 + 10 1.100409e+00 1.301856e+00 1.600721e-01 278 1 + 20 1.263098e+01 1.278410e+00 1.794529e-01 428 1 + 30 -5.003795e+01 1.278410e+00 2.113140e-01 706 1 + 40 6.740000e+00 1.278410e+00 2.339380e-01 856 1 + 44 1.111084e+01 1.278410e+00 2.433879e-01 916 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 2.551520e-01 +total time (s) : 2.433879e-01 total solves : 916 best bound : 1.278410e+00 simulation ci : 4.090025e+00 ± 5.358375e+00 @@ -130,15 +130,15 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 2.007061e+00 1.281639e+00 3.784490e-02 278 1 - 20 1.426676e+01 1.278410e+00 6.748295e-02 428 1 - 30 1.522212e+00 1.278410e+00 1.148939e-01 706 1 - 40 -4.523775e+01 1.278410e+00 1.542470e-01 856 1 + 10 2.007061e+00 1.281639e+00 3.518391e-02 278 1 + 20 1.426676e+01 1.278410e+00 6.251502e-02 428 1 + 30 1.522212e+00 1.278410e+00 1.079910e-01 706 1 + 40 -4.523775e+01 1.278410e+00 1.468689e-01 856 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.542470e-01 +total time (s) : 1.468689e-01 total solves : 856 best bound : 1.278410e+00 simulation ci : 1.019480e+00 ± 6.246418e+00 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/belief/index.html b/previews/PR811/examples/belief/index.html index 5eda1edbe..d0ca93cdc 100644 --- a/previews/PR811/examples/belief/index.html +++ b/previews/PR811/examples/belief/index.html @@ -94,21 +94,21 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 4.787277e+00 9.346930e+00 1.374903e+00 900 1 - 20 6.374753e+00 1.361934e+01 1.545683e+00 1720 1 - 30 2.813321e+01 1.651297e+01 1.905802e+00 3036 1 - 40 1.654759e+01 1.632970e+01 2.253714e+00 4192 1 - 50 3.570941e+00 1.846889e+01 2.544238e+00 5020 1 - 60 1.087425e+01 1.890254e+01 2.851454e+00 5808 1 - 70 9.381610e+00 1.940320e+01 3.172653e+00 6540 1 - 80 5.648731e+01 1.962435e+01 3.527620e+00 7088 1 - 90 3.879273e+01 1.981008e+01 4.762945e+00 8180 1 - 100 7.870187e+00 1.997117e+01 5.025220e+00 8664 1 + 10 4.787277e+00 9.346930e+00 1.380354e+00 900 1 + 20 6.374753e+00 1.361934e+01 1.548098e+00 1720 1 + 30 2.813321e+01 1.651297e+01 1.900516e+00 3036 1 + 40 1.654759e+01 1.632970e+01 2.278601e+00 4192 1 + 50 3.570941e+00 1.846889e+01 2.535460e+00 5020 1 + 60 1.087425e+01 1.890254e+01 2.823263e+00 5808 1 + 70 9.381610e+00 1.940320e+01 3.120219e+00 6540 1 + 80 5.648731e+01 1.962435e+01 3.347280e+00 7088 1 + 90 3.879273e+01 1.981008e+01 4.501978e+00 8180 1 + 100 7.870187e+00 1.997117e+01 4.722817e+00 8664 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 5.025220e+00 +total time (s) : 4.722817e+00 total solves : 8664 best bound : 1.997117e+01 simulation ci : 2.275399e+01 ± 4.541987e+00 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/biobjective_hydro/index.html b/previews/PR811/examples/biobjective_hydro/index.html index 013919df7..120248475 100644 --- a/previews/PR811/examples/biobjective_hydro/index.html +++ b/previews/PR811/examples/biobjective_hydro/index.html @@ -80,11 +80,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 0.000000e+00 1.050186e-02 36 1 - 10 0.000000e+00 0.000000e+00 3.173590e-02 360 1 + 1 0.000000e+00 0.000000e+00 9.330988e-03 36 1 + 10 0.000000e+00 0.000000e+00 2.937508e-02 360 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.173590e-02 +total time (s) : 2.937508e-02 total solves : 360 best bound : 0.000000e+00 simulation ci : 0.000000e+00 ± 0.000000e+00 @@ -113,11 +113,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 6.750000e+02 5.500000e+02 3.112078e-03 407 1 - 10 4.500000e+02 5.733959e+02 3.222489e-02 731 1 + 1 6.750000e+02 5.500000e+02 2.792835e-03 407 1 + 10 4.500000e+02 5.733959e+02 2.948785e-02 731 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.222489e-02 +total time (s) : 2.948785e-02 total solves : 731 best bound : 5.733959e+02 simulation ci : 5.000000e+02 ± 1.079583e+02 @@ -146,11 +146,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 4.850000e+02 3.349793e+02 3.319025e-03 778 1 - 10 3.550000e+02 3.468286e+02 3.398108e-02 1102 1 + 1 4.850000e+02 3.349793e+02 3.025055e-03 778 1 + 10 3.550000e+02 3.468286e+02 3.070188e-02 1102 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.398108e-02 +total time (s) : 3.070188e-02 total solves : 1102 best bound : 3.468286e+02 simulation ci : 3.948309e+02 ± 7.954180e+01 @@ -179,11 +179,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.887500e+02 1.995243e+02 3.022909e-03 1149 1 - 10 2.962500e+02 2.052855e+02 3.225207e-02 1473 1 + 1 1.887500e+02 1.995243e+02 2.761126e-03 1149 1 + 10 2.962500e+02 2.052855e+02 2.954102e-02 1473 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.225207e-02 +total time (s) : 2.954102e-02 total solves : 1473 best bound : 2.052855e+02 simulation ci : 2.040201e+02 ± 3.876873e+01 @@ -212,11 +212,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.737500e+02 4.626061e+02 3.686905e-03 1520 1 - 10 2.450000e+02 4.658509e+02 3.725886e-02 1844 1 + 1 3.737500e+02 4.626061e+02 3.305912e-03 1520 1 + 10 2.450000e+02 4.658509e+02 3.355384e-02 1844 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.725886e-02 +total time (s) : 3.355384e-02 total solves : 1844 best bound : 4.658509e+02 simulation ci : 3.907376e+02 ± 9.045105e+01 @@ -245,11 +245,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.675000e+02 1.129545e+02 3.136873e-03 1891 1 - 10 1.362500e+02 1.129771e+02 3.280091e-02 2215 1 + 1 1.675000e+02 1.129545e+02 2.783060e-03 1891 1 + 10 1.362500e+02 1.129771e+02 3.028989e-02 2215 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.280091e-02 +total time (s) : 3.028989e-02 total solves : 2215 best bound : 1.129771e+02 simulation ci : 1.176375e+02 ± 1.334615e+01 @@ -278,11 +278,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.562500e+02 2.788373e+02 3.476858e-03 2262 1 - 10 2.375000e+02 2.795671e+02 3.591585e-02 2586 1 + 1 2.562500e+02 2.788373e+02 3.196001e-03 2262 1 + 10 2.375000e+02 2.795671e+02 3.301382e-02 2586 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.591585e-02 +total time (s) : 3.301382e-02 total solves : 2586 best bound : 2.795671e+02 simulation ci : 2.375000e+02 ± 3.099032e+01 @@ -311,11 +311,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.812500e+02 4.072952e+02 3.874063e-03 2633 1 - 10 5.818750e+02 4.080500e+02 3.808999e-02 2957 1 + 1 3.812500e+02 4.072952e+02 3.535986e-03 2633 1 + 10 5.818750e+02 4.080500e+02 3.540611e-02 2957 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.808999e-02 +total time (s) : 3.540611e-02 total solves : 2957 best bound : 4.080500e+02 simulation ci : 4.235323e+02 ± 1.029245e+02 @@ -344,11 +344,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 8.525000e+02 5.197742e+02 3.797054e-03 3004 1 - 10 4.493750e+02 5.211793e+02 3.929520e-02 3328 1 + 1 8.525000e+02 5.197742e+02 3.447056e-03 3004 1 + 10 4.493750e+02 5.211793e+02 3.638792e-02 3328 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.929520e-02 +total time (s) : 3.638792e-02 total solves : 3328 best bound : 5.211793e+02 simulation ci : 5.268125e+02 ± 1.227709e+02 @@ -377,13 +377,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.437500e+01 5.937500e+01 3.335953e-03 3375 1 - 10 3.750000e+01 5.938557e+01 3.399801e-02 3699 1 + 1 3.437500e+01 5.937500e+01 3.075838e-03 3375 1 + 10 3.750000e+01 5.938557e+01 3.089690e-02 3699 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.399801e-02 +total time (s) : 3.089690e-02 total solves : 3699 best bound : 5.938557e+01 simulation ci : 5.906250e+01 ± 1.352595e+01 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/booking_management/index.html b/previews/PR811/examples/booking_management/index.html index bfb996f1c..2311d92f1 100644 --- a/previews/PR811/examples/booking_management/index.html +++ b/previews/PR811/examples/booking_management/index.html @@ -96,4 +96,4 @@ end end -booking_management(SDDP.ContinuousConicDuality())
Test Passed

New version of HiGHS stalls booking_management(SDDP.LagrangianDuality())

+booking_management(SDDP.ContinuousConicDuality())
Test Passed

New version of HiGHS stalls booking_management(SDDP.LagrangianDuality())

diff --git a/previews/PR811/examples/generation_expansion/index.html b/previews/PR811/examples/generation_expansion/index.html index 02f0d8426..9d1a492ff 100644 --- a/previews/PR811/examples/generation_expansion/index.html +++ b/previews/PR811/examples/generation_expansion/index.html @@ -115,15 +115,15 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 2.549668e+06 2.078257e+06 5.240018e-01 920 1 - 20 5.494568e+05 2.078257e+06 7.212958e-01 1340 1 - 30 4.985879e+04 2.078257e+06 1.260305e+00 2260 1 - 40 3.799447e+06 2.078257e+06 1.460601e+00 2680 1 - 50 1.049867e+06 2.078257e+06 2.033111e+00 3600 1 - 60 3.985191e+04 2.078257e+06 2.237982e+00 4020 1 + 10 2.549668e+06 2.078257e+06 5.147491e-01 920 1 + 20 5.494568e+05 2.078257e+06 7.083230e-01 1340 1 + 30 4.985879e+04 2.078257e+06 1.255638e+00 2260 1 + 40 3.799447e+06 2.078257e+06 1.457364e+00 2680 1 + 50 1.049867e+06 2.078257e+06 2.019956e+00 3600 1 + 60 3.985191e+04 2.078257e+06 2.227458e+00 4020 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 2.237982e+00 +total time (s) : 2.227458e+00 total solves : 4020 best bound : 2.078257e+06 simulation ci : 2.031697e+06 ± 3.922745e+05 @@ -157,17 +157,17 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10L 4.986663e+04 2.079119e+06 9.402680e-01 920 1 - 20L 3.799878e+06 2.079330e+06 1.662699e+00 1340 1 - 30L 3.003923e+04 2.079457e+06 2.782754e+00 2260 1 - 40L 5.549882e+06 2.079457e+06 3.587709e+00 2680 1 - 50L 2.799466e+06 2.079457e+06 4.801594e+00 3600 1 - 60L 3.549880e+06 2.079457e+06 5.577852e+00 4020 1 + 10L 4.986663e+04 2.079119e+06 9.453409e-01 920 1 + 20L 3.799878e+06 2.079330e+06 1.661727e+00 1340 1 + 30L 3.003923e+04 2.079457e+06 2.782502e+00 2260 1 + 40L 5.549882e+06 2.079457e+06 3.574901e+00 2680 1 + 50L 2.799466e+06 2.079457e+06 4.784258e+00 3600 1 + 60L 3.549880e+06 2.079457e+06 5.556520e+00 4020 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 5.577852e+00 +total time (s) : 5.556520e+00 total solves : 4020 best bound : 2.079457e+06 simulation ci : 2.352204e+06 ± 5.377531e+05 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/hydro_valley/index.html b/previews/PR811/examples/hydro_valley/index.html index 98f8faa1e..06978eba3 100644 --- a/previews/PR811/examples/hydro_valley/index.html +++ b/previews/PR811/examples/hydro_valley/index.html @@ -280,4 +280,4 @@ ### = $835 end -test_hydro_valley_model()
Test Passed
+test_hydro_valley_model()
Test Passed
diff --git a/previews/PR811/examples/infinite_horizon_hydro_thermal/index.html b/previews/PR811/examples/infinite_horizon_hydro_thermal/index.html index 5d6c323e2..bf36f437a 100644 --- a/previews/PR811/examples/infinite_horizon_hydro_thermal/index.html +++ b/previews/PR811/examples/infinite_horizon_hydro_thermal/index.html @@ -93,13 +93,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 100 2.500000e+01 1.188965e+02 8.147130e-01 1946 1 - 200 2.500000e+01 1.191634e+02 1.027875e+00 3920 1 - 300 0.000000e+00 1.191666e+02 1.253149e+00 5902 1 - 330 2.500000e+01 1.191667e+02 1.295287e+00 6224 1 + 100 2.500000e+01 1.188965e+02 7.813201e-01 1946 1 + 200 2.500000e+01 1.191634e+02 9.817300e-01 3920 1 + 300 0.000000e+00 1.191666e+02 1.189551e+00 5902 1 + 330 2.500000e+01 1.191667e+02 1.229830e+00 6224 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.295287e+00 +total time (s) : 1.229830e+00 total solves : 6224 best bound : 1.191667e+02 simulation ci : 2.158333e+01 ± 3.290252e+00 @@ -132,16 +132,16 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 100 0.000000e+00 1.191285e+02 3.682230e-01 2874 1 - 200 2.500000e+00 1.191666e+02 6.167409e-01 4855 1 - 282 7.500000e+00 1.191667e+02 7.612429e-01 5733 1 + 100 0.000000e+00 1.191285e+02 3.425910e-01 2874 1 + 200 2.500000e+00 1.191666e+02 5.737948e-01 4855 1 + 282 7.500000e+00 1.191667e+02 7.097430e-01 5733 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.612429e-01 +total time (s) : 7.097430e-01 total solves : 5733 best bound : 1.191667e+02 simulation ci : 2.104610e+01 ± 3.492245e+00 numeric issues : 0 ------------------------------------------------------------------- -Confidence_interval = 116.06 ± 13.65 +Confidence_interval = 116.06 ± 13.65 diff --git a/previews/PR811/examples/infinite_horizon_trivial/index.html b/previews/PR811/examples/infinite_horizon_trivial/index.html index 8f43810c9..1f65d5099 100644 --- a/previews/PR811/examples/infinite_horizon_trivial/index.html +++ b/previews/PR811/examples/infinite_horizon_trivial/index.html @@ -49,15 +49,15 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 4.000000e+00 1.997089e+01 7.080197e-02 1204 1 - 20 8.000000e+00 2.000000e+01 9.183383e-02 1420 1 - 30 1.600000e+01 2.000000e+01 1.607640e-01 2628 1 - 40 8.000000e+00 2.000000e+01 1.828198e-01 2834 1 + 10 4.000000e+00 1.997089e+01 6.758094e-02 1204 1 + 20 8.000000e+00 2.000000e+01 8.787799e-02 1420 1 + 30 1.600000e+01 2.000000e+01 1.550801e-01 2628 1 + 40 8.000000e+00 2.000000e+01 1.759651e-01 2834 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.828198e-01 +total time (s) : 1.759651e-01 total solves : 2834 best bound : 2.000000e+01 simulation ci : 1.625000e+01 ± 4.766381e+00 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/no_strong_duality/index.html b/previews/PR811/examples/no_strong_duality/index.html index d0fa94a81..3e0fadfa0 100644 --- a/previews/PR811/examples/no_strong_duality/index.html +++ b/previews/PR811/examples/no_strong_duality/index.html @@ -48,13 +48,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.000000e+00 1.500000e+00 1.674891e-03 3 1 - 40 4.000000e+00 2.000000e+00 4.355884e-02 578 1 + 1 1.000000e+00 1.500000e+00 1.639128e-03 3 1 + 40 4.000000e+00 2.000000e+00 4.273510e-02 578 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 4.355884e-02 +total time (s) : 4.273510e-02 total solves : 578 best bound : 2.000000e+00 simulation ci : 1.950000e+00 ± 5.568095e-01 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/objective_state_newsvendor/index.html b/previews/PR811/examples/objective_state_newsvendor/index.html index c5150cd4a..04ea8682e 100644 --- a/previews/PR811/examples/objective_state_newsvendor/index.html +++ b/previews/PR811/examples/objective_state_newsvendor/index.html @@ -93,136 +93,138 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 5.250000e+00 4.888859e+00 1.734259e-01 1350 1 - 20 4.350000e+00 4.105855e+00 2.593269e-01 2700 1 - 30 5.000000e+00 4.100490e+00 3.561099e-01 4050 1 - 40 3.500000e+00 4.097376e+00 4.613249e-01 5400 1 - 50 5.250000e+00 4.095859e+00 5.681269e-01 6750 1 - 60 3.643750e+00 4.093342e+00 6.795769e-01 8100 1 - 70 2.643750e+00 4.091818e+00 8.375499e-01 9450 1 - 80 5.087500e+00 4.091591e+00 9.514139e-01 10800 1 - 90 5.062500e+00 4.091309e+00 1.069393e+00 12150 1 - 100 4.843750e+00 4.087004e+00 1.194058e+00 13500 1 - 110 3.437500e+00 4.086094e+00 1.318437e+00 14850 1 - 120 3.375000e+00 4.085926e+00 1.443642e+00 16200 1 - 130 5.025000e+00 4.085866e+00 1.572026e+00 17550 1 - 140 5.000000e+00 4.085734e+00 1.699506e+00 18900 1 - 150 3.500000e+00 4.085655e+00 1.828924e+00 20250 1 - 160 4.281250e+00 4.085454e+00 1.955072e+00 21600 1 - 170 4.562500e+00 4.085425e+00 2.086330e+00 22950 1 - 180 5.768750e+00 4.085425e+00 2.217444e+00 24300 1 - 190 3.468750e+00 4.085359e+00 2.362571e+00 25650 1 - 200 4.131250e+00 4.085225e+00 2.501070e+00 27000 1 - 210 4.512500e+00 4.085157e+00 2.635083e+00 28350 1 - 220 4.900000e+00 4.085153e+00 2.773443e+00 29700 1 - 230 4.025000e+00 4.085134e+00 2.915444e+00 31050 1 - 240 4.468750e+00 4.085116e+00 3.059644e+00 32400 1 - 250 4.062500e+00 4.085075e+00 3.199127e+00 33750 1 - 260 4.875000e+00 4.085037e+00 3.340952e+00 35100 1 - 270 3.850000e+00 4.085011e+00 3.481494e+00 36450 1 - 280 4.912500e+00 4.084992e+00 3.624226e+00 37800 1 - 290 2.987500e+00 4.084986e+00 3.771702e+00 39150 1 - 300 3.825000e+00 4.084957e+00 3.960055e+00 40500 1 - 310 3.250000e+00 4.084911e+00 4.108256e+00 41850 1 - 320 3.600000e+00 4.084896e+00 4.255653e+00 43200 1 - 330 3.925000e+00 4.084896e+00 4.393683e+00 44550 1 - 340 4.500000e+00 4.084893e+00 4.541749e+00 45900 1 - 350 5.000000e+00 4.084891e+00 4.690975e+00 47250 1 - 360 3.075000e+00 4.084866e+00 4.837096e+00 48600 1 - 370 3.500000e+00 4.084861e+00 4.990098e+00 49950 1 - 380 3.356250e+00 4.084857e+00 5.144240e+00 51300 1 - 390 5.500000e+00 4.084846e+00 5.310439e+00 52650 1 - 400 4.475000e+00 4.084846e+00 5.465906e+00 54000 1 - 410 3.750000e+00 4.084843e+00 5.620679e+00 55350 1 - 420 3.687500e+00 4.084843e+00 5.779263e+00 56700 1 - 430 4.337500e+00 4.084825e+00 5.935040e+00 58050 1 - 440 5.750000e+00 4.084825e+00 6.076252e+00 59400 1 - 450 4.925000e+00 4.084792e+00 6.246021e+00 60750 1 - 460 3.600000e+00 4.084792e+00 6.400154e+00 62100 1 - 470 4.387500e+00 4.084792e+00 6.549840e+00 63450 1 - 480 4.000000e+00 4.084792e+00 6.710515e+00 64800 1 - 490 2.975000e+00 4.084788e+00 6.864817e+00 66150 1 - 500 3.125000e+00 4.084788e+00 7.024368e+00 67500 1 - 510 4.250000e+00 4.084788e+00 7.186687e+00 68850 1 - 520 4.512500e+00 4.084786e+00 7.338763e+00 70200 1 - 530 3.875000e+00 4.084786e+00 7.532629e+00 71550 1 - 540 4.387500e+00 4.084781e+00 7.696063e+00 72900 1 - 550 5.281250e+00 4.084780e+00 7.860922e+00 74250 1 - 560 4.650000e+00 4.084780e+00 8.016701e+00 75600 1 - 570 3.062500e+00 4.084780e+00 8.171513e+00 76950 1 - 580 3.187500e+00 4.084780e+00 8.325596e+00 78300 1 - 590 3.812500e+00 4.084780e+00 8.475552e+00 79650 1 - 600 3.637500e+00 4.084774e+00 8.634904e+00 81000 1 - 610 3.950000e+00 4.084765e+00 8.792513e+00 82350 1 - 620 4.625000e+00 4.084760e+00 8.950787e+00 83700 1 - 630 4.218750e+00 4.084760e+00 9.112958e+00 85050 1 - 640 3.025000e+00 4.084755e+00 9.280204e+00 86400 1 - 650 2.993750e+00 4.084751e+00 9.435989e+00 87750 1 - 660 3.262500e+00 4.084746e+00 9.601910e+00 89100 1 - 670 3.625000e+00 4.084746e+00 9.775332e+00 90450 1 - 680 2.981250e+00 4.084746e+00 9.948784e+00 91800 1 - 690 4.187500e+00 4.084746e+00 1.011872e+01 93150 1 - 700 4.500000e+00 4.084746e+00 1.028642e+01 94500 1 - 710 3.225000e+00 4.084746e+00 1.045848e+01 95850 1 - 720 4.375000e+00 4.084746e+00 1.063083e+01 97200 1 - 730 2.650000e+00 4.084746e+00 1.083783e+01 98550 1 - 740 3.250000e+00 4.084746e+00 1.100563e+01 99900 1 - 750 4.725000e+00 4.084746e+00 1.118854e+01 101250 1 - 760 3.375000e+00 4.084746e+00 1.137177e+01 102600 1 - 770 5.375000e+00 4.084746e+00 1.154874e+01 103950 1 - 780 4.068750e+00 4.084746e+00 1.172674e+01 105300 1 - 790 4.412500e+00 4.084746e+00 1.190625e+01 106650 1 - 800 4.350000e+00 4.084746e+00 1.208874e+01 108000 1 - 810 5.887500e+00 4.084746e+00 1.227040e+01 109350 1 - 820 4.912500e+00 4.084746e+00 1.244445e+01 110700 1 - 830 4.387500e+00 4.084746e+00 1.261354e+01 112050 1 - 840 3.675000e+00 4.084746e+00 1.279480e+01 113400 1 - 850 5.375000e+00 4.084746e+00 1.296941e+01 114750 1 - 860 3.562500e+00 4.084746e+00 1.316130e+01 116100 1 - 870 3.075000e+00 4.084746e+00 1.334805e+01 117450 1 - 880 3.625000e+00 4.084746e+00 1.353763e+01 118800 1 - 890 2.937500e+00 4.084746e+00 1.371442e+01 120150 1 - 900 4.450000e+00 4.084746e+00 1.390157e+01 121500 1 - 910 4.200000e+00 4.084746e+00 1.410609e+01 122850 1 - 920 3.687500e+00 4.084746e+00 1.428934e+01 124200 1 - 930 4.725000e+00 4.084746e+00 1.447056e+01 125550 1 - 940 4.018750e+00 4.084746e+00 1.463890e+01 126900 1 - 950 4.675000e+00 4.084746e+00 1.480195e+01 128250 1 - 960 3.375000e+00 4.084746e+00 1.496423e+01 129600 1 - 970 3.812500e+00 4.084746e+00 1.512657e+01 130950 1 - 980 3.112500e+00 4.084746e+00 1.529611e+01 132300 1 - 990 3.600000e+00 4.084746e+00 1.547750e+01 133650 1 - 1000 5.500000e+00 4.084746e+00 1.565246e+01 135000 1 - 1010 3.187500e+00 4.084746e+00 1.582274e+01 136350 1 - 1020 4.900000e+00 4.084746e+00 1.599779e+01 137700 1 - 1030 3.637500e+00 4.084746e+00 1.618343e+01 139050 1 - 1040 3.975000e+00 4.084746e+00 1.635629e+01 140400 1 - 1050 4.750000e+00 4.084746e+00 1.655779e+01 141750 1 - 1060 4.437500e+00 4.084746e+00 1.675049e+01 143100 1 - 1070 5.000000e+00 4.084746e+00 1.693024e+01 144450 1 - 1080 4.143750e+00 4.084746e+00 1.711242e+01 145800 1 - 1090 5.625000e+00 4.084746e+00 1.728857e+01 147150 1 - 1100 3.475000e+00 4.084746e+00 1.747086e+01 148500 1 - 1110 4.156250e+00 4.084746e+00 1.766315e+01 149850 1 - 1120 4.450000e+00 4.084746e+00 1.785749e+01 151200 1 - 1130 3.312500e+00 4.084741e+00 1.805663e+01 152550 1 - 1140 5.375000e+00 4.084741e+00 1.823556e+01 153900 1 - 1150 4.800000e+00 4.084737e+00 1.843092e+01 155250 1 - 1160 3.300000e+00 4.084737e+00 1.861697e+01 156600 1 - 1170 4.356250e+00 4.084737e+00 1.879954e+01 157950 1 - 1180 3.900000e+00 4.084737e+00 1.901167e+01 159300 1 - 1190 4.450000e+00 4.084737e+00 1.920076e+01 160650 1 - 1200 5.156250e+00 4.084737e+00 1.939178e+01 162000 1 - 1210 4.500000e+00 4.084737e+00 1.957136e+01 163350 1 - 1220 4.875000e+00 4.084737e+00 1.976497e+01 164700 1 - 1230 4.000000e+00 4.084737e+00 1.994862e+01 166050 1 - 1233 5.218750e+00 4.084737e+00 2.000150e+01 166455 1 + 10 5.250000e+00 4.888859e+00 1.712432e-01 1350 1 + 20 4.350000e+00 4.105855e+00 2.557001e-01 2700 1 + 30 5.000000e+00 4.100490e+00 3.899250e-01 4050 1 + 40 3.500000e+00 4.097376e+00 4.926381e-01 5400 1 + 50 5.250000e+00 4.095859e+00 6.009200e-01 6750 1 + 60 3.643750e+00 4.093342e+00 7.120681e-01 8100 1 + 70 2.643750e+00 4.091818e+00 8.236940e-01 9450 1 + 80 5.087500e+00 4.091591e+00 9.382150e-01 10800 1 + 90 5.062500e+00 4.091309e+00 1.052949e+00 12150 1 + 100 4.843750e+00 4.087004e+00 1.177181e+00 13500 1 + 110 3.437500e+00 4.086094e+00 1.301021e+00 14850 1 + 120 3.375000e+00 4.085926e+00 1.426546e+00 16200 1 + 130 5.025000e+00 4.085866e+00 1.556027e+00 17550 1 + 140 5.000000e+00 4.085734e+00 1.687912e+00 18900 1 + 150 3.500000e+00 4.085655e+00 1.818401e+00 20250 1 + 160 4.281250e+00 4.085454e+00 1.944509e+00 21600 1 + 170 4.562500e+00 4.085425e+00 2.072280e+00 22950 1 + 180 5.768750e+00 4.085425e+00 2.200540e+00 24300 1 + 190 3.468750e+00 4.085359e+00 2.335219e+00 25650 1 + 200 4.131250e+00 4.085225e+00 2.469636e+00 27000 1 + 210 4.512500e+00 4.085157e+00 2.603997e+00 28350 1 + 220 4.900000e+00 4.085153e+00 2.737233e+00 29700 1 + 230 4.025000e+00 4.085134e+00 2.874589e+00 31050 1 + 240 4.468750e+00 4.085116e+00 3.014505e+00 32400 1 + 250 4.062500e+00 4.085075e+00 3.192237e+00 33750 1 + 260 4.875000e+00 4.085037e+00 3.331058e+00 35100 1 + 270 3.850000e+00 4.085011e+00 3.470104e+00 36450 1 + 280 4.912500e+00 4.084992e+00 3.611678e+00 37800 1 + 290 2.987500e+00 4.084986e+00 3.758030e+00 39150 1 + 300 3.825000e+00 4.084957e+00 3.904765e+00 40500 1 + 310 3.250000e+00 4.084911e+00 4.053302e+00 41850 1 + 320 3.600000e+00 4.084896e+00 4.201271e+00 43200 1 + 330 3.925000e+00 4.084896e+00 4.337336e+00 44550 1 + 340 4.500000e+00 4.084893e+00 4.481930e+00 45900 1 + 350 5.000000e+00 4.084891e+00 4.630258e+00 47250 1 + 360 3.075000e+00 4.084866e+00 4.781391e+00 48600 1 + 370 3.500000e+00 4.084861e+00 4.931129e+00 49950 1 + 380 3.356250e+00 4.084857e+00 5.080989e+00 51300 1 + 390 5.500000e+00 4.084846e+00 5.238686e+00 52650 1 + 400 4.475000e+00 4.084846e+00 5.386836e+00 54000 1 + 410 3.750000e+00 4.084843e+00 5.537586e+00 55350 1 + 420 3.687500e+00 4.084843e+00 5.703979e+00 56700 1 + 430 4.337500e+00 4.084825e+00 5.860562e+00 58050 1 + 440 5.750000e+00 4.084825e+00 6.001830e+00 59400 1 + 450 4.925000e+00 4.084792e+00 6.161568e+00 60750 1 + 460 3.600000e+00 4.084792e+00 6.316679e+00 62100 1 + 470 4.387500e+00 4.084792e+00 6.466405e+00 63450 1 + 480 4.000000e+00 4.084792e+00 6.652086e+00 64800 1 + 490 2.975000e+00 4.084788e+00 6.808310e+00 66150 1 + 500 3.125000e+00 4.084788e+00 6.962584e+00 67500 1 + 510 4.250000e+00 4.084788e+00 7.124767e+00 68850 1 + 520 4.512500e+00 4.084786e+00 7.279242e+00 70200 1 + 530 3.875000e+00 4.084786e+00 7.446755e+00 71550 1 + 540 4.387500e+00 4.084781e+00 7.607976e+00 72900 1 + 550 5.281250e+00 4.084780e+00 7.772215e+00 74250 1 + 560 4.650000e+00 4.084780e+00 7.923224e+00 75600 1 + 570 3.062500e+00 4.084780e+00 8.077300e+00 76950 1 + 580 3.187500e+00 4.084780e+00 8.227366e+00 78300 1 + 590 3.812500e+00 4.084780e+00 8.374758e+00 79650 1 + 600 3.637500e+00 4.084774e+00 8.532806e+00 81000 1 + 610 3.950000e+00 4.084765e+00 8.689049e+00 82350 1 + 620 4.625000e+00 4.084760e+00 8.847563e+00 83700 1 + 630 4.218750e+00 4.084760e+00 9.008270e+00 85050 1 + 640 3.025000e+00 4.084755e+00 9.168273e+00 86400 1 + 650 2.993750e+00 4.084751e+00 9.324117e+00 87750 1 + 660 3.262500e+00 4.084746e+00 9.482478e+00 89100 1 + 670 3.625000e+00 4.084746e+00 9.644065e+00 90450 1 + 680 2.981250e+00 4.084746e+00 9.838071e+00 91800 1 + 690 4.187500e+00 4.084746e+00 9.996642e+00 93150 1 + 700 4.500000e+00 4.084746e+00 1.015159e+01 94500 1 + 710 3.225000e+00 4.084746e+00 1.030851e+01 95850 1 + 720 4.375000e+00 4.084746e+00 1.046806e+01 97200 1 + 730 2.650000e+00 4.084746e+00 1.063247e+01 98550 1 + 740 3.250000e+00 4.084746e+00 1.079002e+01 99900 1 + 750 4.725000e+00 4.084746e+00 1.096502e+01 101250 1 + 760 3.375000e+00 4.084746e+00 1.113593e+01 102600 1 + 770 5.375000e+00 4.084746e+00 1.130502e+01 103950 1 + 780 4.068750e+00 4.084746e+00 1.147862e+01 105300 1 + 790 4.412500e+00 4.084746e+00 1.165918e+01 106650 1 + 800 4.350000e+00 4.084746e+00 1.183344e+01 108000 1 + 810 5.887500e+00 4.084746e+00 1.201065e+01 109350 1 + 820 4.912500e+00 4.084746e+00 1.218002e+01 110700 1 + 830 4.387500e+00 4.084746e+00 1.234002e+01 112050 1 + 840 3.675000e+00 4.084746e+00 1.250737e+01 113400 1 + 850 5.375000e+00 4.084746e+00 1.267340e+01 114750 1 + 860 3.562500e+00 4.084746e+00 1.287131e+01 116100 1 + 870 3.075000e+00 4.084746e+00 1.304815e+01 117450 1 + 880 3.625000e+00 4.084746e+00 1.321521e+01 118800 1 + 890 2.937500e+00 4.084746e+00 1.337899e+01 120150 1 + 900 4.450000e+00 4.084746e+00 1.355284e+01 121500 1 + 910 4.200000e+00 4.084746e+00 1.372446e+01 122850 1 + 920 3.687500e+00 4.084746e+00 1.390016e+01 124200 1 + 930 4.725000e+00 4.084746e+00 1.407677e+01 125550 1 + 940 4.018750e+00 4.084746e+00 1.424514e+01 126900 1 + 950 4.675000e+00 4.084746e+00 1.441165e+01 128250 1 + 960 3.375000e+00 4.084746e+00 1.457437e+01 129600 1 + 970 3.812500e+00 4.084746e+00 1.474051e+01 130950 1 + 980 3.112500e+00 4.084746e+00 1.490928e+01 132300 1 + 990 3.600000e+00 4.084746e+00 1.509131e+01 133650 1 + 1000 5.500000e+00 4.084746e+00 1.528799e+01 135000 1 + 1010 3.187500e+00 4.084746e+00 1.545659e+01 136350 1 + 1020 4.900000e+00 4.084746e+00 1.563010e+01 137700 1 + 1030 3.637500e+00 4.084746e+00 1.581252e+01 139050 1 + 1040 3.975000e+00 4.084746e+00 1.598426e+01 140400 1 + 1050 4.750000e+00 4.084746e+00 1.616359e+01 141750 1 + 1060 4.437500e+00 4.084746e+00 1.635204e+01 143100 1 + 1070 5.000000e+00 4.084746e+00 1.653067e+01 144450 1 + 1080 4.143750e+00 4.084746e+00 1.671378e+01 145800 1 + 1090 5.625000e+00 4.084746e+00 1.688430e+01 147150 1 + 1100 3.475000e+00 4.084746e+00 1.706820e+01 148500 1 + 1110 4.156250e+00 4.084746e+00 1.725233e+01 149850 1 + 1120 4.450000e+00 4.084746e+00 1.743011e+01 151200 1 + 1130 3.312500e+00 4.084741e+00 1.761266e+01 152550 1 + 1140 5.375000e+00 4.084741e+00 1.780811e+01 153900 1 + 1150 4.800000e+00 4.084737e+00 1.799549e+01 155250 1 + 1160 3.300000e+00 4.084737e+00 1.817865e+01 156600 1 + 1170 4.356250e+00 4.084737e+00 1.835846e+01 157950 1 + 1180 3.900000e+00 4.084737e+00 1.854494e+01 159300 1 + 1190 4.450000e+00 4.084737e+00 1.873824e+01 160650 1 + 1200 5.156250e+00 4.084737e+00 1.892452e+01 162000 1 + 1210 4.500000e+00 4.084737e+00 1.909851e+01 163350 1 + 1220 4.875000e+00 4.084737e+00 1.929208e+01 164700 1 + 1230 4.000000e+00 4.084737e+00 1.947183e+01 166050 1 + 1240 4.062500e+00 4.084737e+00 1.965651e+01 167400 1 + 1250 5.450000e+00 4.084737e+00 1.986792e+01 168750 1 + 1257 4.125000e+00 4.084737e+00 2.000116e+01 169695 1 ------------------------------------------------------------------- status : time_limit -total time (s) : 2.000150e+01 -total solves : 166455 +total time (s) : 2.000116e+01 +total solves : 169695 best bound : 4.084737e+00 -simulation ci : 4.072644e+00 ± 4.044792e-02 +simulation ci : 4.071924e+00 ± 4.030230e-02 numeric issues : 0 ------------------------------------------------------------------- @@ -252,28 +254,28 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 5.250000e+00 5.621506e+00 1.820130e-01 1350 1 - 20 5.625000e+00 4.738243e+00 5.347002e-01 2700 1 - 30 4.800000e+00 4.043340e+00 9.793801e-01 4050 1 - 40 2.981250e+00 4.039693e+00 1.528040e+00 5400 1 - 50 4.875000e+00 4.039162e+00 2.258422e+00 6750 1 - 60 4.200000e+00 4.039061e+00 3.131524e+00 8100 1 - 70 3.625000e+00 4.039083e+00 4.117996e+00 9450 1 - 80 5.168750e+00 4.039000e+00 5.269657e+00 10800 1 - 90 4.725000e+00 4.038902e+00 6.521223e+00 12150 1 - 100 4.200000e+00 4.038847e+00 7.835695e+00 13500 1 - 110 5.156250e+00 4.038832e+00 9.323179e+00 14850 1 - 120 5.200000e+00 4.038784e+00 1.088657e+01 16200 1 - 130 5.437500e+00 4.038795e+00 1.253203e+01 17550 1 - 140 5.218750e+00 4.038777e+00 1.432849e+01 18900 1 - 150 3.631250e+00 4.038777e+00 1.637355e+01 20250 1 - 160 2.650000e+00 4.038777e+00 1.844013e+01 21600 1 - 168 4.237500e+00 4.038770e+00 2.008583e+01 22680 1 + 10 3.875000e+00 4.353130e+00 2.004929e-01 1350 1 + 20 2.981250e+00 4.046840e+00 5.817509e-01 2700 1 + 30 4.125000e+00 4.044475e+00 1.076938e+00 4050 1 + 40 4.875000e+00 4.041075e+00 1.732080e+00 5400 1 + 50 4.275000e+00 4.040539e+00 2.433584e+00 6750 1 + 60 4.843750e+00 4.040288e+00 3.289070e+00 8100 1 + 70 5.625000e+00 4.039205e+00 4.243661e+00 9450 1 + 80 4.375000e+00 4.039110e+00 5.368436e+00 10800 1 + 90 4.900000e+00 4.039004e+00 6.512935e+00 12150 1 + 100 2.893750e+00 4.038938e+00 7.844159e+00 13500 1 + 110 5.287500e+00 4.038884e+00 9.266460e+00 14850 1 + 120 4.250000e+00 4.038839e+00 1.079688e+01 16200 1 + 130 4.012500e+00 4.038776e+00 1.257979e+01 17550 1 + 140 4.368750e+00 4.038776e+00 1.428642e+01 18900 1 + 150 4.875000e+00 4.038774e+00 1.617734e+01 20250 1 + 160 4.368750e+00 4.037591e+00 1.818796e+01 21600 1 + 169 4.500000e+00 4.037578e+00 2.005415e+01 22815 1 ------------------------------------------------------------------- status : time_limit -total time (s) : 2.008583e+01 -total solves : 22680 -best bound : 4.038770e+00 -simulation ci : 4.104824e+00 ± 1.171821e-01 +total time (s) : 2.005415e+01 +total solves : 22815 +best bound : 4.037578e+00 +simulation ci : 4.050816e+00 ± 1.155829e-01 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/sldp_example_one/index.html b/previews/PR811/examples/sldp_example_one/index.html index bf63e1344..0a308d464 100644 --- a/previews/PR811/examples/sldp_example_one/index.html +++ b/previews/PR811/examples/sldp_example_one/index.html @@ -65,18 +65,19 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 3.092749e+00 1.166404e+00 3.928251e-01 1680 1 - 20 2.656862e+00 1.167365e+00 4.926121e-01 2560 1 - 30 3.085472e+00 1.167365e+00 8.912382e-01 4240 1 - 40 3.293473e+00 1.167365e+00 9.923971e-01 5120 1 - 50 3.112712e+00 1.167365e+00 1.393122e+00 6800 1 - 60 3.239056e+00 1.167410e+00 1.498153e+00 7680 1 - 64 3.106758e+00 1.167410e+00 1.540112e+00 8032 1 + 10 3.785215e+00 1.166861e+00 3.889260e-01 1680 1 + 20 2.812407e+00 1.167299e+00 4.863241e-01 2560 1 + 30 2.828561e+00 1.167299e+00 8.810191e-01 4240 1 + 40 3.470837e+00 1.167299e+00 9.838631e-01 5120 1 + 50 2.832678e+00 1.167299e+00 1.378870e+00 6800 1 + 60 3.234686e+00 1.167299e+00 1.485548e+00 7680 1 + 70 3.192636e+00 1.167299e+00 1.885161e+00 9360 1 + 80 2.722614e+00 1.167299e+00 1.993683e+00 10240 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.540112e+00 -total solves : 8032 -best bound : 1.167410e+00 -simulation ci : 3.369436e+00 ± 1.052982e-01 +total time (s) : 1.993683e+00 +total solves : 10240 +best bound : 1.167299e+00 +simulation ci : 3.241472e+00 ± 9.570211e-02 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/sldp_example_two/index.html b/previews/PR811/examples/sldp_example_two/index.html index 73aefada4..0708a0c6c 100644 --- a/previews/PR811/examples/sldp_example_two/index.html +++ b/previews/PR811/examples/sldp_example_two/index.html @@ -92,16 +92,16 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -4.000000e+01 -5.809615e+01 3.280902e-02 78 1 - 20 -4.000000e+01 -5.809615e+01 6.489182e-02 148 1 - 30 -4.000000e+01 -5.809615e+01 1.038380e-01 226 1 - 40 -4.000000e+01 -5.809615e+01 1.381290e-01 296 1 + 10 -4.700000e+01 -5.809615e+01 3.338099e-02 78 1 + 20 -4.700000e+01 -5.809615e+01 6.633687e-02 148 1 + 30 -4.700000e+01 -5.809615e+01 1.058669e-01 226 1 + 40 -4.700000e+01 -5.809615e+01 1.393440e-01 296 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.381290e-01 +total time (s) : 1.393440e-01 total solves : 296 best bound : -5.809615e+01 -simulation ci : -6.053750e+01 ± 8.436950e+00 +simulation ci : -5.821250e+01 ± 8.353903e+00 numeric issues : 0 ------------------------------------------------------------------- @@ -133,16 +133,16 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -4.700000e+01 -6.196125e+01 4.201603e-02 138 1 - 20 -4.700000e+01 -6.196125e+01 8.031297e-02 258 1 - 30 -4.000000e+01 -6.196125e+01 1.318018e-01 396 1 - 40 -4.000000e+01 -6.196125e+01 1.705229e-01 516 1 + 10 -7.500000e+01 -6.196125e+01 4.039788e-02 138 1 + 20 -7.500000e+01 -6.196125e+01 7.732701e-02 258 1 + 30 -4.000000e+01 -6.196125e+01 1.287961e-01 396 1 + 40 -4.000000e+01 -6.196125e+01 1.674640e-01 516 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.705229e-01 +total time (s) : 1.674640e-01 total solves : 516 best bound : -6.196125e+01 -simulation ci : -5.191250e+01 ± 5.053380e+00 +simulation ci : -5.753750e+01 ± 6.415492e+00 numeric issues : 0 ------------------------------------------------------------------- @@ -174,15 +174,15 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 10 -8.200000e+01 -6.546793e+01 8.193111e-02 462 1 - 20 -4.000000e+01 -6.546793e+01 1.442950e-01 852 1 - 30 -4.000000e+01 -6.546793e+01 2.659330e-01 1314 1 - 40 -5.900000e+01 -6.546793e+01 3.300650e-01 1704 1 + 10 -7.000000e+01 -6.546793e+01 7.961798e-02 462 1 + 20 -6.300000e+01 -6.546793e+01 1.399961e-01 852 1 + 30 -4.000000e+01 -6.546793e+01 2.566769e-01 1314 1 + 40 -8.200000e+01 -6.546793e+01 3.185890e-01 1704 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.300650e-01 +total time (s) : 3.185890e-01 total solves : 1704 best bound : -6.546793e+01 -simulation ci : -5.996250e+01 ± 4.578408e+00 +simulation ci : -6.206250e+01 ± 4.415467e+00 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/stochastic_all_blacks/index.html b/previews/PR811/examples/stochastic_all_blacks/index.html index 585190837..91ac31594 100644 --- a/previews/PR811/examples/stochastic_all_blacks/index.html +++ b/previews/PR811/examples/stochastic_all_blacks/index.html @@ -77,13 +77,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1L 6.000000e+00 1.200000e+01 4.302812e-02 11 1 - 40L 1.200000e+01 8.000000e+00 4.347019e-01 602 1 + 1L 6.000000e+00 1.200000e+01 4.302001e-02 11 1 + 40L 1.200000e+01 8.000000e+00 4.238839e-01 602 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 4.347019e-01 +total time (s) : 4.238839e-01 total solves : 602 best bound : 8.000000e+00 -simulation ci : 8.250000e+00 ± 9.356503e-01 +simulation ci : 8.100000e+00 ± 9.693887e-01 numeric issues : 0 -------------------------------------------------------------------- +------------------------------------------------------------------- diff --git a/previews/PR811/examples/the_farmers_problem/index.html b/previews/PR811/examples/the_farmers_problem/index.html index c2df3897f..d3ba1019e 100644 --- a/previews/PR811/examples/the_farmers_problem/index.html +++ b/previews/PR811/examples/the_farmers_problem/index.html @@ -125,13 +125,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 -9.800000e+04 4.922260e+05 9.035993e-02 6 1 - 40 1.093500e+05 1.083900e+05 1.199400e-01 240 1 + 1 -9.800000e+04 4.922260e+05 8.714199e-02 6 1 + 40 1.093500e+05 1.083900e+05 1.163521e-01 240 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.199400e-01 +total time (s) : 1.163521e-01 total solves : 240 best bound : 1.083900e+05 -simulation ci : 9.552212e+04 ± 1.983096e+04 +simulation ci : 1.008813e+05 ± 2.001742e+04 numeric issues : 0 --------------------------------------------------------------------

Checking the policy

Birge and Louveaux report that the optimal objective value is $108,390. Check that we got the correct solution using SDDP.calculate_bound:

@assert isapprox(SDDP.calculate_bound(model), 108_390.0, atol = 0.1)
+-------------------------------------------------------------------

Checking the policy

Birge and Louveaux report that the optimal objective value is $108,390. Check that we got the correct solution using SDDP.calculate_bound:

@assert isapprox(SDDP.calculate_bound(model), 108_390.0, atol = 0.1)
diff --git a/previews/PR811/examples/vehicle_location/index.html b/previews/PR811/examples/vehicle_location/index.html index 7973c73e4..7b237609b 100644 --- a/previews/PR811/examples/vehicle_location/index.html +++ b/previews/PR811/examples/vehicle_location/index.html @@ -108,4 +108,4 @@ end # TODO(odow): find out why this fails -# vehicle_location_model(SDDP.ContinuousConicDuality())
vehicle_location_model (generic function with 1 method)
+# vehicle_location_model(SDDP.ContinuousConicDuality())
vehicle_location_model (generic function with 1 method)
diff --git a/previews/PR811/explanation/risk/index.html b/previews/PR811/explanation/risk/index.html index 0e851bb15..1077e6c3a 100644 --- a/previews/PR811/explanation/risk/index.html +++ b/previews/PR811/explanation/risk/index.html @@ -523,7 +523,7 @@ | | | Adding cut : 100 volume_out + cost_to_go ≥ 29998.641399238186 | Finished iteration | | lower_bound = 14998.641399238184 -Upper bound = 10049.65876179914 ± 899.907113235118

Finally, evaluate the decision rule:

evaluate_policy(
+Upper bound = 9974.700948126138 ± 842.9001753338523

Finally, evaluate the decision rule:

evaluate_policy(
     model;
     node = 1,
     incoming_state = Dict(:volume => 150.0),
@@ -536,4 +536,4 @@
   :volume_in          => 150.0
   :thermal_generation => 125.0
   :hydro_generation   => 25.0
-  :cost_to_go         => 9998.64
Info

For this trivial example, the risk-averse policy isn't very different from the policy obtained using the expectation risk-measure. If you try it on some bigger/more interesting problems, you should see the expected cost increase, and the upper tail of the policy decrease.

+ :cost_to_go => 9998.64
Info

For this trivial example, the risk-averse policy isn't very different from the policy obtained using the expectation risk-measure. If you try it on some bigger/more interesting problems, you should see the expected cost increase, and the upper tail of the policy decrease.

diff --git a/previews/PR811/explanation/theory_intro/index.html b/previews/PR811/explanation/theory_intro/index.html index 85b142ef4..a2b2f7d06 100644 --- a/previews/PR811/explanation/theory_intro/index.html +++ b/previews/PR811/explanation/theory_intro/index.html @@ -200,9 +200,9 @@ return error("We should never get here because P should sum to 1.0.") end
sample_uncertainty (generic function with 1 method)
Note

rand() samples a uniform random variable in [0, 1).

For example:

for i in 1:3
     println("ω = ", sample_uncertainty(model.nodes[1].uncertainty))
-end
ω = 50.0
+end
ω = 0.0
 ω = 50.0
-ω = 50.0

It's also going to be useful to define a function that generates a random walk through the nodes of the graph:

function sample_next_node(model::PolicyGraph, current::Int)
+ω = 0.0

It's also going to be useful to define a function that generates a random walk through the nodes of the graph:

function sample_next_node(model::PolicyGraph, current::Int)
     if length(model.arcs[current]) == 0
         # No outgoing arcs!
         return nothing
@@ -280,15 +280,15 @@
 | | | x′ = Dict(:volume => 50.0)
 | | | C(x, u, ω) = 0.0
 | | Visiting node 2
-| | | ω = 50.0
+| | | ω = 0.0
 | | | x = Dict(:volume => 50.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
+| | | C(x, u, ω) = 10000.0
 | | Visiting node 3
-| | | ω = 50.0
+| | | ω = 100.0
 | | | x = Dict(:volume => 0.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0

Implementation: the backward pass

From the forward pass, we obtained a vector of nodes visited and their corresponding outgoing state variables. Now we need to refine the approximation for each node at the candidate solution for the outgoing state variable. That is, we need to add a new cut:

\[\theta \ge \mathbb{E}_{j \in i^+, \varphi \in \Omega_j}\left[V_j^k(x^\prime_k, \varphi) + \frac{d}{dx^\prime}V_j^k(x^\prime_k, \varphi)^\top (x^\prime - x^\prime_k)\right]\]

or alternatively:

\[\theta \ge \sum\limits_{j \in i^+} \sum\limits_{\varphi \in \Omega_j} p_{ij} p_{\varphi}\left[V_j^k(x^\prime_k, \varphi) + \frac{d}{dx^\prime}V_j^k(x^\prime_k, \varphi)^\top (x^\prime - x^\prime_k)\right]\]

It doesn't matter what order we visit the nodes to generate these cuts for. For example, we could compute them all in parallel, using the current approximations of $V^K_i$.

However, we can be smarter than that.

If we traverse the list of nodes visited in the forward pass in reverse, then we come to refine the $i^{th}$ node in the trajectory, we will already have improved the approximation of the $(i+1)^{th}$ node in the trajectory as well! Therefore, our refinement of the $i^{th}$ node will be better than if we improved node $i$ first, and then refined node $(i+1)$.

Because we walk the nodes in reverse, we call this the backward pass.

Info

If you're into deep learning, you could view this as the equivalent of back-propagation: the forward pass pushes primal information through the graph (outgoing state variables), and the backward pass pulls dual information (cuts) back through the graph to improve our decisions on the next forward pass.

function backward_pass(
+| | | C(x, u, ω) = 7500.0

Implementation: the backward pass

From the forward pass, we obtained a vector of nodes visited and their corresponding outgoing state variables. Now we need to refine the approximation for each node at the candidate solution for the outgoing state variable. That is, we need to add a new cut:

\[\theta \ge \mathbb{E}_{j \in i^+, \varphi \in \Omega_j}\left[V_j^k(x^\prime_k, \varphi) + \frac{d}{dx^\prime}V_j^k(x^\prime_k, \varphi)^\top (x^\prime - x^\prime_k)\right]\]

or alternatively:

\[\theta \ge \sum\limits_{j \in i^+} \sum\limits_{\varphi \in \Omega_j} p_{ij} p_{\varphi}\left[V_j^k(x^\prime_k, \varphi) + \frac{d}{dx^\prime}V_j^k(x^\prime_k, \varphi)^\top (x^\prime - x^\prime_k)\right]\]

It doesn't matter what order we visit the nodes to generate these cuts for. For example, we could compute them all in parallel, using the current approximations of $V^K_i$.

However, we can be smarter than that.

If we traverse the list of nodes visited in the forward pass in reverse, then we come to refine the $i^{th}$ node in the trajectory, we will already have improved the approximation of the $(i+1)^{th}$ node in the trajectory as well! Therefore, our refinement of the $i^{th}$ node will be better than if we improved node $i$ first, and then refined node $(i+1)$.

Because we walk the nodes in reverse, we call this the backward pass.

Info

If you're into deep learning, you could view this as the equivalent of back-propagation: the forward pass pushes primal information through the graph (outgoing state variables), and the backward pass pulls dual information (cuts) back through the graph to improve our decisions on the next forward pass.

function backward_pass(
     model::PolicyGraph,
     trajectory::Vector{Tuple{Int,Dict{Symbol,Float64}}},
     io::IO = stdout,
@@ -382,15 +382,15 @@
 end
train (generic function with 1 method)

Using our model we defined earlier, we can go:

train(model; iteration_limit = 3, replications = 100)
Starting iteration 1
 | Forward Pass
 | | Visiting node 1
-| | | ω = 0.0
+| | | ω = 100.0
 | | | x = Dict(:volume => 200.0)
-| | | x′ = Dict(:volume => 50.0)
+| | | x′ = Dict(:volume => 150.0)
 | | | C(x, u, ω) = 0.0
 | | Visiting node 2
-| | | ω = 50.0
-| | | x = Dict(:volume => 50.0)
+| | | ω = 0.0
+| | | x = Dict(:volume => 150.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
+| | | C(x, u, ω) = 0.0
 | | Visiting node 3
 | | | ω = 50.0
 | | | x = Dict(:volume => 0.0)
@@ -412,33 +412,33 @@
 | | | Adding cut : 150 volume_out + cost_to_go ≥ 15000
 | | Visiting node 1
 | | | Solving φ = 0.0
-| | | | V = 22500.0
-| | | | dVdx′ = Dict(:volume => -150.0)
+| | | | V = 10000.0
+| | | | dVdx′ = Dict(:volume => -100.0)
 | | | Solving φ = 50.0
-| | | | V = 15000.0
-| | | | dVdx′ = Dict(:volume => -150.0)
+| | | | V = 5000.0
+| | | | dVdx′ = Dict(:volume => -100.0)
 | | | Solving φ = 100.0
-| | | | V = 10000.0
+| | | | V = 0.0
 | | | | dVdx′ = Dict(:volume => -100.0)
-| | | Adding cut : 133.33333333333331 volume_out + cost_to_go ≥ 22500
+| | | Adding cut : 99.99999999999999 volume_out + cost_to_go ≥ 20000
 | Finished iteration
-| | lower_bound = 3437.500000000001
+| | lower_bound = 5000.000000000002
 Starting iteration 2
 | Forward Pass
 | | Visiting node 1
-| | | ω = 50.0
+| | | ω = 100.0
 | | | x = Dict(:volume => 200.0)
-| | | x′ = Dict(:volume => 168.75)
-| | | C(x, u, ω) = 3437.500000000001
+| | | x′ = Dict(:volume => 200.00000000000003)
+| | | C(x, u, ω) = 2500.0000000000014
 | | Visiting node 2
-| | | ω = 0.0
-| | | x = Dict(:volume => 168.75)
+| | | ω = 100.0
+| | | x = Dict(:volume => 200.00000000000003)
 | | | x′ = Dict(:volume => 100.0)
-| | | C(x, u, ω) = 8125.0
+| | | C(x, u, ω) = 0.0
 | | Visiting node 3
-| | | ω = 100.0
+| | | ω = 50.0
 | | | x = Dict(:volume => 100.0)
-| | | x′ = Dict(:volume => 50.0)
+| | | x′ = Dict(:volume => 0.0)
 | | | C(x, u, ω) = 0.0
 | Backward pass
 | | Visiting node 3
@@ -456,34 +456,34 @@
 | | | Adding cut : 100 volume_out + cost_to_go ≥ 12500
 | | Visiting node 1
 | | | Solving φ = 0.0
-| | | | V = 10624.999999999998
+| | | | V = 7499.999999999997
 | | | | dVdx′ = Dict(:volume => -100.0)
 | | | Solving φ = 50.0
-| | | | V = 5624.999999999998
+| | | | V = 2499.9999999999973
 | | | | dVdx′ = Dict(:volume => -100.0)
 | | | Solving φ = 100.0
-| | | | V = 625.0
-| | | | dVdx′ = Dict(:volume => -100.0)
-| | | Adding cut : 99.99999999999999 volume_out + cost_to_go ≥ 22499.999999999996
+| | | | V = 0.0
+| | | | dVdx′ = Dict(:volume => 0.0)
+| | | Adding cut : 66.66666666666666 volume_out + cost_to_go ≥ 16666.666666666664
 | Finished iteration
-| | lower_bound = 7500.000000000004
+| | lower_bound = 8333.333333333332
 Starting iteration 3
 | Forward Pass
 | | Visiting node 1
-| | | ω = 50.0
+| | | ω = 0.0
 | | | x = Dict(:volume => 200.0)
 | | | x′ = Dict(:volume => 200.0)
-| | | C(x, u, ω) = 5000.0
+| | | C(x, u, ω) = 7500.0
 | | Visiting node 2
-| | | ω = 0.0
+| | | ω = 100.0
 | | | x = Dict(:volume => 200.0)
 | | | x′ = Dict(:volume => 124.99999999999997)
-| | | C(x, u, ω) = 7499.999999999998
+| | | C(x, u, ω) = 0.0
 | | Visiting node 3
-| | | ω = 0.0
+| | | ω = 50.0
 | | | x = Dict(:volume => 124.99999999999997)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 3750.000000000004
+| | | x′ = Dict(:volume => 24.99999999999997)
+| | | C(x, u, ω) = 0.0
 | Backward pass
 | | Visiting node 3
 | | | Skipping node because the cost-to-go is 0
@@ -512,7 +512,7 @@
 | Finished iteration
 | | lower_bound = 8333.333333333332
 Termination status: iteration limit
-Upper bound = 8600.0 ± 895.4805944014057

Success! We trained a policy for a finite horizon multistage stochastic program using stochastic dual dynamic programming.

Implementation: evaluating the policy

A final step is the ability to evaluate the policy at a given point.

function evaluate_policy(
+Upper bound = 8625.0 ± 876.469473155647

Success! We trained a policy for a finite horizon multistage stochastic program using stochastic dual dynamic programming.

Implementation: evaluating the policy

A final step is the ability to evaluate the policy at a given point.

function evaluate_policy(
     model::PolicyGraph;
     node::Int,
     incoming_state::Dict{Symbol,Float64},
@@ -556,130 +556,40 @@
 

Then, train a policy:

train(model; iteration_limit = 3, replications = 100)
Starting iteration 1
 | Forward Pass
 | | Visiting node 1
-| | | ω = 0.0
-| | | x = Dict(:volume => 200.0)
-| | | x′ = Dict(:volume => 50.0)
-| | | C(x, u, ω) = 0.0
-| | Visiting node 2
-| | | ω = 50.0
-| | | x = Dict(:volume => 50.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
-| | Visiting node 3
 | | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
+| | | x = Dict(:volume => 200.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 7500.0
+| | | C(x, u, ω) = 0.0
 | | Visiting node 2
-| | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
-| | Visiting node 3
 | | | ω = 0.0
 | | | x = Dict(:volume => 0.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 22500.0
-| | Visiting node 2
-| | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
-| | Visiting node 3
-| | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 7500.0
-| | Visiting node 2
-| | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
+| | | C(x, u, ω) = 15000.0
 | | Visiting node 3
 | | | ω = 0.0
 | | | x = Dict(:volume => 0.0)
 | | | x′ = Dict(:volume => 0.0)
 | | | C(x, u, ω) = 22500.0
 | | Visiting node 2
-| | | ω = 0.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 3
 | | | ω = 50.0
 | | | x = Dict(:volume => 0.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 2
-| | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
+| | | C(x, u, ω) = 10000.0
 | | Visiting node 3
-| | | ω = 50.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 2
-| | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
-| | Visiting node 3
-| | | ω = 50.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 2
 | | | ω = 0.0
 | | | x = Dict(:volume => 0.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 3
-| | | ω = 100.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 7500.0
+| | | C(x, u, ω) = 22500.0
 | | Visiting node 2
 | | | ω = 100.0
 | | | x = Dict(:volume => 0.0)
 | | | x′ = Dict(:volume => 0.0)
 | | | C(x, u, ω) = 5000.0
 | | Visiting node 3
-| | | ω = 50.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 2
-| | | ω = 0.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 3
-| | | ω = 50.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 2
-| | | ω = 0.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 3
-| | | ω = 50.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 15000.0
-| | Visiting node 2
 | | | ω = 100.0
 | | | x = Dict(:volume => 0.0)
 | | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 5000.0
-| | Visiting node 3
-| | | ω = 0.0
-| | | x = Dict(:volume => 0.0)
-| | | x′ = Dict(:volume => 0.0)
-| | | C(x, u, ω) = 22500.0
+| | | C(x, u, ω) = 7500.0
 | Backward pass
 | | Visiting node 3
 | | | Solving φ = 0.0
@@ -747,7 +657,7 @@
 | | | | V = 25625.0
 | | | | dVdx′ = Dict(:volume => -150.0)
 | | | Adding cut : 150 volume_out + cost_to_go ≥ 33125
-| | Visiting node 3
+| | Visiting node 1
 | | | Solving φ = 0.0
 | | | | V = 48125.0
 | | | | dVdx′ = Dict(:volume => -150.0)
@@ -757,347 +667,117 @@
 | | | Solving φ = 100.0
 | | | | V = 33125.0
 | | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 20312.5
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 42812.5
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 35312.5
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 27812.5
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 35312.5
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 50312.5
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 42812.5
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 35312.5
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 21406.25
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 43906.25
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 36406.25
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 28906.25
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 36406.25
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 51406.25
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 43906.25
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 36406.25
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 21953.124999999996
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 44453.125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 36953.125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29453.124999999996
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 36953.125
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 51953.125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 44453.125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 36953.125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 22226.5625
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 44726.5625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 37226.5625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29726.5625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 37226.5625
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 52226.5625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 44726.5625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 37226.5625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 22363.281249999996
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 44863.28125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 37363.28125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29863.281249999996
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 37363.28125
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 52363.28125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 44863.28125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 37363.28125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 22431.640625
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 44931.640625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 37431.640625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29931.640625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 37431.640625
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 52431.640625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 44931.640625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 37431.640625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 22465.820312499996
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 44965.8203125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 37465.8203125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29965.820312499996
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 37465.8203125
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 52465.8203125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 44965.8203125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 37465.8203125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 22482.91015625
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 44982.91015625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 37482.91015625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29982.91015625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 37482.91015625
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 52482.91015625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 44982.91015625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 37482.91015625
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 22491.455078124996
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 44991.455078125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 37491.455078125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29991.455078124996
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 37491.455078125
-| | Visiting node 1
-| | | Solving φ = 0.0
-| | | | V = 44991.455078125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 50.0
-| | | | V = 37491.455078125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Solving φ = 100.0
-| | | | V = 29991.455078125
-| | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 150 volume_out + cost_to_go ≥ 44991.455078125
+| | | Adding cut : 150 volume_out + cost_to_go ≥ 40625
 | Finished iteration
-| | lower_bound = 19991.455078125
+| | lower_bound = 15625.0
 Starting iteration 2
 | Forward Pass
 | | Visiting node 1
-| | | ω = 0.0
+| | | ω = 50.0
 | | | x = Dict(:volume => 200.0)
 | | | x′ = Dict(:volume => 200.0)
-| | | C(x, u, ω) = 7499.999999999998
+| | | C(x, u, ω) = 5000.0
 | | Visiting node 2
-| | | ω = 100.0
+| | | ω = 0.0
 | | | x = Dict(:volume => 200.0)
 | | | x′ = Dict(:volume => 200.0)
-| | | C(x, u, ω) = 5000.0
-| | Visiting node 3
-| | | ω = 50.0
-| | | x = Dict(:volume => 200.0)
-| | | x′ = Dict(:volume => 100.0)
-| | | C(x, u, ω) = 0.0
-| | Visiting node 2
-| | | ω = 50.0
-| | | x = Dict(:volume => 100.0)
-| | | x′ = Dict(:volume => 150.0)
 | | | C(x, u, ω) = 15000.0
 | | Visiting node 3
-| | | ω = 100.0
-| | | x = Dict(:volume => 150.0)
-| | | x′ = Dict(:volume => 100.0)
+| | | ω = 0.0
+| | | x = Dict(:volume => 200.0)
+| | | x′ = Dict(:volume => 50.0)
 | | | C(x, u, ω) = 0.0
 | Backward pass
 | | Visiting node 3
 | | | Solving φ = 0.0
-| | | | V = 37491.455078125
+| | | | V = 40625.0
 | | | | dVdx′ = Dict(:volume => -150.0)
 | | | Solving φ = 50.0
-| | | | V = 29991.455078125
+| | | | V = 33125.0
 | | | | dVdx′ = Dict(:volume => -150.0)
 | | | Solving φ = 100.0
-| | | | V = 22491.455078125
+| | | | V = 25625.0
 | | | | dVdx′ = Dict(:volume => -150.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 22495.7275390625
+| | | Adding cut : 75 volume_out + cost_to_go ≥ 20312.5
 | | Visiting node 2
 | | | Solving φ = 0.0
-| | | | V = 22495.7275390625
+| | | | V = 16562.5
 | | | | dVdx′ = Dict(:volume => -75.0)
 | | | Solving φ = 50.0
-| | | | V = 18745.7275390625
+| | | | V = 12812.5
 | | | | dVdx′ = Dict(:volume => -75.0)
 | | | Solving φ = 100.0
-| | | | V = 14995.7275390625
+| | | | V = 9062.5
 | | | | dVdx′ = Dict(:volume => -75.0)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 29995.7275390625
-| | Visiting node 3
-| | | Solving φ = 0.0
-| | | | V = 37494.303385416664
-| | | | dVdx′ = Dict(:volume => -100.0)
-| | | Solving φ = 50.0
-| | | | V = 32494.303385416664
-| | | | dVdx′ = Dict(:volume => -100.0)
-| | | Solving φ = 100.0
-| | | | V = 27494.303385416668
-| | | | dVdx′ = Dict(:volume => -100.0)
-| | | Adding cut : 49.99999999999999 volume_out + cost_to_go ≥ 21247.151692708332
-| | Visiting node 2
-| | | Solving φ = 0.0
-| | | | V = 18747.151692708332
-| | | | dVdx′ = Dict(:volume => -49.99999999999999)
-| | | Solving φ = 50.0
-| | | | V = 16247.151692708332
-| | | | dVdx′ = Dict(:volume => -49.99999999999999)
-| | | Solving φ = 100.0
-| | | | V = 13747.151692708332
-| | | | dVdx′ = Dict(:volume => -49.99999999999999)
-| | | Adding cut : 49.99999999999999 volume_out + cost_to_go ≥ 26247.15169270833
+| | | Adding cut : 75 volume_out + cost_to_go ≥ 27812.499999999996
 | | Visiting node 1
 | | | Solving φ = 0.0
-| | | | V = 27494.303385416668
+| | | | V = 24583.33333333333
 | | | | dVdx′ = Dict(:volume => -100.0)
 | | | Solving φ = 50.0
-| | | | V = 22495.7275390625
+| | | | V = 20312.5
 | | | | dVdx′ = Dict(:volume => -75.0)
 | | | Solving φ = 100.0
-| | | | V = 18747.151692708336
-| | | | dVdx′ = Dict(:volume => -50.00000000000001)
-| | | Adding cut : 75 volume_out + cost_to_go ≥ 37912.39420572917
+| | | | V = 16562.5
+| | | | dVdx′ = Dict(:volume => -75.0)
+| | | Adding cut : 83.33333333333333 volume_out + cost_to_go ≥ 37152.777777777774
 | Finished iteration
-| | lower_bound = 27912.39420572917
+| | lower_bound = 25486.11111111111
 Starting iteration 3
 | Forward Pass
 | | Visiting node 1
-| | | ω = 100.0
+| | | ω = 0.0
 | | | x = Dict(:volume => 200.0)
 | | | x′ = Dict(:volume => 200.0)
-| | | C(x, u, ω) = 2500.0
+| | | C(x, u, ω) = 7500.0
 | | Visiting node 2
-| | | ω = 50.0
+| | | ω = 0.0
 | | | x = Dict(:volume => 200.0)
-| | | x′ = Dict(:volume => 100.0)
-| | | C(x, u, ω) = 0.0
+| | | x′ = Dict(:volume => 70.83333333333337)
+| | | C(x, u, ω) = 2083.3333333333358
 | | Visiting node 3
-| | | ω = 50.0
-| | | x = Dict(:volume => 100.0)
-| | | x′ = Dict(:volume => -0.0)
+| | | ω = 100.0
+| | | x = Dict(:volume => 70.83333333333337)
+| | | x′ = Dict(:volume => 20.83333333333337)
 | | | C(x, u, ω) = 0.0
 | Backward pass
 | | Visiting node 3
 | | | Solving φ = 0.0
-| | | | V = 52491.455078125
+| | | | V = 44999.999999999985
 | | | | dVdx′ = Dict(:volume => -150.0)
 | | | Solving φ = 50.0
-| | | | V = 44991.455078125
+| | | | V = 37499.999999999985
 | | | | dVdx′ = Dict(:volume => -150.0)
 | | | Solving φ = 100.0
-| | | | V = 37494.30338541667
+| | | | V = 32499.999999999993
 | | | | dVdx′ = Dict(:volume => -100.0)
-| | | Adding cut : 66.66666666666666 volume_out + cost_to_go ≥ 22496.202256944445
+| | | Adding cut : 66.66666666666666 volume_out + cost_to_go ≥ 20555.55555555555
 | | Visiting node 2
 | | | Solving φ = 0.0
-| | | | V = 29996.202256944445
+| | | | V = 32430.555555555547
 | | | | dVdx′ = Dict(:volume => -150.0)
 | | | Solving φ = 50.0
-| | | | V = 22496.202256944445
+| | | | V = 24930.555555555547
 | | | | dVdx′ = Dict(:volume => -150.0)
 | | | Solving φ = 100.0
-| | | | V = 19162.868923611113
+| | | | V = 19166.66666666666
 | | | | dVdx′ = Dict(:volume => -66.66666666666666)
-| | | Adding cut : 122.22222222222221 volume_out + cost_to_go ≥ 36107.313368055555
+| | | Adding cut : 122.22222222222221 volume_out + cost_to_go ≥ 34166.666666666664
 | | Visiting node 1
 | | | Solving φ = 0.0
-| | | | V = 28231.272977941175
+| | | | V = 26176.470588235294
 | | | | dVdx′ = Dict(:volume => -100.0)
 | | | Solving φ = 50.0
-| | | | V = 23231.272977941175
+| | | | V = 21176.47058823529
 | | | | dVdx′ = Dict(:volume => -100.0)
 | | | Solving φ = 100.0
-| | | | V = 18747.15169270832
-| | | | dVdx′ = Dict(:volume => -50.0)
-| | | Adding cut : 83.33333333333331 volume_out + cost_to_go ≥ 40069.899216196885
+| | | | V = 16562.5
+| | | | dVdx′ = Dict(:volume => -75.0)
+| | | Adding cut : 91.66666666666666 volume_out + cost_to_go ≥ 39638.48039215685
 | Finished iteration
-| | lower_bound = 28403.23254953022
+| | lower_bound = 26305.147058823517
 Termination status: iteration limit
-Upper bound = 34625.08544921876 ± 7740.910609262855

Success! We trained a policy for an infinite horizon multistage stochastic program using stochastic dual dynamic programming. Note how some of the forward passes are different lengths!

evaluate_policy(
+Upper bound = 36509.55882352943 ± 7811.823051509411

Success! We trained a policy for an infinite horizon multistage stochastic program using stochastic dual dynamic programming. Note how some of the forward passes are different lengths!

evaluate_policy(
     model;
     node = 3,
     incoming_state = Dict(:volume => 100.0),
@@ -1110,4 +790,4 @@
   :volume_in          => 100.0
   :thermal_generation => 40.0
   :hydro_generation   => 110.0
-  :cost_to_go         => 22496.2
+ :cost_to_go => 20555.6 diff --git a/previews/PR811/guides/access_previous_variables/index.html b/previews/PR811/guides/access_previous_variables/index.html index 5e9c98ec1..f3b9edc94 100644 --- a/previews/PR811/guides/access_previous_variables/index.html +++ b/previews/PR811/guides/access_previous_variables/index.html @@ -98,4 +98,4 @@ end end endA policy graph with 20 nodes. - Node indices: 1, ..., 20 + Node indices: 1, ..., 20 diff --git a/previews/PR811/guides/add_a_multidimensional_state_variable/index.html b/previews/PR811/guides/add_a_multidimensional_state_variable/index.html index b6024fa67..0a461f1d4 100644 --- a/previews/PR811/guides/add_a_multidimensional_state_variable/index.html +++ b/previews/PR811/guides/add_a_multidimensional_state_variable/index.html @@ -19,4 +19,4 @@ end; Lower bound of outgoing x is: 0.0 Lower bound of outgoing y[1] is: 1.0 -Lower bound of outgoing z[3, :B] is: 3.0 +Lower bound of outgoing z[3, :B] is: 3.0 diff --git a/previews/PR811/guides/add_a_risk_measure/index.html b/previews/PR811/guides/add_a_risk_measure/index.html index 4726a201d..9074a8fe0 100644 --- a/previews/PR811/guides/add_a_risk_measure/index.html +++ b/previews/PR811/guides/add_a_risk_measure/index.html @@ -40,7 +40,7 @@ 0.0 0.0 0.0 - 0.0

Expectation

SDDP.ExpectationType
Expectation()

The Expectation risk measure. Identical to taking the expectation with respect to the nominal distribution.

source
julia> using SDDP
julia> SDDP.adjust_probability( + 0.0

Expectation

SDDP.ExpectationType
Expectation()

The Expectation risk measure. Identical to taking the expectation with respect to the nominal distribution.

source
julia> using SDDP
julia> SDDP.adjust_probability( SDDP.Expectation(), risk_adjusted_probability, nominal_probability, @@ -51,7 +51,7 @@ 0.1 0.2 0.3 - 0.4

SDDP.Expectation is the default risk measure in SDDP.jl.

Worst-case

SDDP.WorstCaseType
WorstCase()

The worst-case risk measure. Places all of the probability weight on the worst outcome.

source
julia> SDDP.adjust_probability(
+ 0.4

SDDP.Expectation is the default risk measure in SDDP.jl.

Worst-case

SDDP.WorstCaseType
WorstCase()

The worst-case risk measure. Places all of the probability weight on the worst outcome.

source
julia> SDDP.adjust_probability(
            SDDP.WorstCase(),
            risk_adjusted_probability,
            nominal_probability,
@@ -62,7 +62,7 @@
  0.0
  0.0
  1.0
- 0.0

Average value at risk (AV@R)

SDDP.AVaRType
AVaR(β)

The average value at risk (AV@R) risk measure.

Computes the expectation of the β fraction of worst outcomes. β must be in [0, 1]. When β=1, this is equivalent to the Expectation risk measure. When β=0, this is equivalent to the WorstCase risk measure.

AV@R is also known as the conditional value at risk (CV@R) or expected shortfall.

source
julia> SDDP.adjust_probability(
+ 0.0

Average value at risk (AV@R)

SDDP.AVaRType
AVaR(β)

The average value at risk (AV@R) risk measure.

Computes the expectation of the β fraction of worst outcomes. β must be in [0, 1]. When β=1, this is equivalent to the Expectation risk measure. When β=0, this is equivalent to the WorstCase risk measure.

AV@R is also known as the conditional value at risk (CV@R) or expected shortfall.

source
julia> SDDP.adjust_probability(
            SDDP.AVaR(0.5),
            risk_adjusted_probability,
            nominal_probability,
@@ -84,10 +84,10 @@
  0.05
  0.1
  0.65
- 0.2

As a special case, the SDDP.EAVaR risk-measure is a convex combination of SDDP.Expectation and SDDP.AVaR:

julia> SDDP.EAVaR(beta=0.25, lambda=0.4)A convex combination of 0.4 * SDDP.Expectation() + 0.6 * SDDP.AVaR(0.25)
SDDP.EAVaRFunction
EAVaR(;lambda=1.0, beta=1.0)

A risk measure that is a convex combination of Expectation and Average Value @ Risk (also called Conditional Value @ Risk).

    λ * E[x] + (1 - λ) * AV@R(β)[x]

Keyword Arguments

  • lambda: Convex weight on the expectation ((1-lambda) weight is put on the AV@R component. Inreasing values of lambda are less risk averse (more weight on expectation).

  • beta: The quantile at which to calculate the Average Value @ Risk. Increasing values of beta are less risk averse. If beta=0, then the AV@R component is the worst case risk measure.

source

Distributionally robust

SDDP.jl supports two types of distributionally robust risk measures: the modified Χ² method of Philpott et al. (2018), and a method based on the Wasserstein distance metric.

Modified Chi-squard

SDDP.ModifiedChiSquaredType
ModifiedChiSquared(radius::Float64; minimum_std=1e-5)

The distributionally robust SDDP risk measure of Philpott, A., de Matos, V., Kapelevich, L. Distributionally robust SDDP. Computational Management Science (2018) 165:431-454.

Explanation

In a Distributionally Robust Optimization (DRO) approach, we modify the probabilities we associate with all future scenarios so that the resulting probability distribution is the "worst case" probability distribution, in some sense.

In each backward pass we will compute a worst case probability distribution vector p. We compute p so that:

p ∈ argmax p'z
+ 0.2

As a special case, the SDDP.EAVaR risk-measure is a convex combination of SDDP.Expectation and SDDP.AVaR:

julia> SDDP.EAVaR(beta=0.25, lambda=0.4)A convex combination of 0.4 * SDDP.Expectation() + 0.6 * SDDP.AVaR(0.25)
SDDP.EAVaRFunction
EAVaR(;lambda=1.0, beta=1.0)

A risk measure that is a convex combination of Expectation and Average Value @ Risk (also called Conditional Value @ Risk).

    λ * E[x] + (1 - λ) * AV@R(β)[x]

Keyword Arguments

  • lambda: Convex weight on the expectation ((1-lambda) weight is put on the AV@R component. Inreasing values of lambda are less risk averse (more weight on expectation).

  • beta: The quantile at which to calculate the Average Value @ Risk. Increasing values of beta are less risk averse. If beta=0, then the AV@R component is the worst case risk measure.

source

Distributionally robust

SDDP.jl supports two types of distributionally robust risk measures: the modified Χ² method of Philpott et al. (2018), and a method based on the Wasserstein distance metric.

Modified Chi-squard

SDDP.ModifiedChiSquaredType
ModifiedChiSquared(radius::Float64; minimum_std=1e-5)

The distributionally robust SDDP risk measure of Philpott, A., de Matos, V., Kapelevich, L. Distributionally robust SDDP. Computational Management Science (2018) 165:431-454.

Explanation

In a Distributionally Robust Optimization (DRO) approach, we modify the probabilities we associate with all future scenarios so that the resulting probability distribution is the "worst case" probability distribution, in some sense.

In each backward pass we will compute a worst case probability distribution vector p. We compute p so that:

p ∈ argmax p'z
       s.t. [r; p - a] in SecondOrderCone()
            sum(p) == 1
-           p >= 0

where

  1. z is a vector of future costs. We assume that our aim is to minimize future cost p'z. If we maximize reward, we would have p ∈ argmin{p'z}.
  2. a is the uniform distribution
  3. r is a user specified radius - the larger the radius, the more conservative the policy.

Notes

The largest radius that will work with S scenarios is sqrt((S-1)/S).

If the uncorrected standard deviation of the objecive realizations is less than minimum_std, then the risk-measure will default to Expectation().

This code was contributed by Lea Kapelevich.

source
julia> SDDP.adjust_probability(
+           p >= 0

where

  1. z is a vector of future costs. We assume that our aim is to minimize future cost p'z. If we maximize reward, we would have p ∈ argmin{p'z}.
  2. a is the uniform distribution
  3. r is a user specified radius - the larger the radius, the more conservative the policy.

Notes

The largest radius that will work with S scenarios is sqrt((S-1)/S).

If the uncorrected standard deviation of the objecive realizations is less than minimum_std, then the risk-measure will default to Expectation().

This code was contributed by Lea Kapelevich.

source
julia> SDDP.adjust_probability(
            SDDP.ModifiedChiSquared(0.5),
            risk_adjusted_probability,
            [0.25, 0.25, 0.25, 0.25],
@@ -98,7 +98,7 @@
  0.3333333333333333
  0.044658198738520394
  0.6220084679281462
- 0.0

Wasserstein

SDDP.WassersteinType
Wasserstein(norm::Function, solver_factory; alpha::Float64)

A distributionally-robust risk measure based on the Wasserstein distance.

As alpha increases, the measure becomes more risk-averse. When alpha=0, the measure is equivalent to the expectation operator. As alpha increases, the measure approaches the Worst-case risk measure.

source
julia> import HiGHS
julia> SDDP.adjust_probability( + 0.0

Wasserstein

SDDP.WassersteinType
Wasserstein(norm::Function, solver_factory; alpha::Float64)

A distributionally-robust risk measure based on the Wasserstein distance.

As alpha increases, the measure becomes more risk-averse. When alpha=0, the measure is equivalent to the expectation operator. As alpha increases, the measure approaches the Worst-case risk measure.

source
julia> import HiGHS
julia> SDDP.adjust_probability( SDDP.Wasserstein(HiGHS.Optimizer; alpha=0.5) do x, y return abs(x - y) end, @@ -113,7 +113,7 @@ 0.7999999999999999 -0.0

Entropic

SDDP.EntropicType
Entropic(γ::Float64)

The entropic risk measure as described by:

Dowson, O., Morton, D.P. & Pagnoncelli, B.K. Incorporating convex risk
 measures into multistage stochastic programming algorithms. Annals of
-Operations Research (2022). [doi](https://doi.org/10.1007/s10479-022-04977-w).

As γ increases, the measure becomes more risk-averse.

source
julia> SDDP.adjust_probability(
+Operations Research (2022). [doi](https://doi.org/10.1007/s10479-022-04977-w).

As γ increases, the measure becomes more risk-averse.

source
julia> SDDP.adjust_probability(
            SDDP.Entropic(0.1),
            risk_adjusted_probability,
            nominal_probability,
@@ -124,4 +124,4 @@
  0.1100296362588547
  0.19911786395979578
  0.3648046623591841
- 0.3260478374221655
+ 0.3260478374221655 diff --git a/previews/PR811/guides/add_integrality/index.html b/previews/PR811/guides/add_integrality/index.html index 07dc38705..fd90c24a2 100644 --- a/previews/PR811/guides/add_integrality/index.html +++ b/previews/PR811/guides/add_integrality/index.html @@ -25,4 +25,4 @@ \max\limits_{\lambda}\min\limits_{\bar{x}, x^\prime, u} \;\; & C_i(\bar{x}, u, \omega) + \mathbb{E}_{j \in i^+, \varphi \in \Omega_j}[V_j(x^\prime, \varphi)] - \lambda^\top(\bar{x} - x)\\ & x^\prime = T_i(\bar{x}, u, \omega) \\ & u \in U_i(\bar{x}, \omega) -\end{aligned}\]

You can use Lagrangian duality in SDDP.jl by passing SDDP.LagrangianDuality to the duality_handler argument of SDDP.train.

Compared with linear programming duality, the Lagrangian problem is difficult to solve because it requires the solution of many mixed-integer programs instead of a single linear program. This is one reason why "SDDiP" has poor performance.

Convergence

The second part to SDDiP is a very tightly scoped claim: if all of the state variables are binary and the algorithm uses Lagrangian duality to compute a subgradient, then it will converge to an optimal policy.

In many cases, papers claim to "do SDDiP," but they have state variables which are not binary. In these cases, the algorithm is not guaranteed to converge to a globally optimal policy.

One work-around that has been suggested is to discretize the state variables into a set of binary state variables. However, this leads to a large number of binary state variables, which is another reason why "SDDiP" has poor performance.

In general, we recommend that you introduce integer variables into your model without fear of the consequences, and that you treat the resulting policy as a good heuristic, rather than an attempt to find a globally optimal policy.

+\end{aligned}\]

You can use Lagrangian duality in SDDP.jl by passing SDDP.LagrangianDuality to the duality_handler argument of SDDP.train.

Compared with linear programming duality, the Lagrangian problem is difficult to solve because it requires the solution of many mixed-integer programs instead of a single linear program. This is one reason why "SDDiP" has poor performance.

Convergence

The second part to SDDiP is a very tightly scoped claim: if all of the state variables are binary and the algorithm uses Lagrangian duality to compute a subgradient, then it will converge to an optimal policy.

In many cases, papers claim to "do SDDiP," but they have state variables which are not binary. In these cases, the algorithm is not guaranteed to converge to a globally optimal policy.

One work-around that has been suggested is to discretize the state variables into a set of binary state variables. However, this leads to a large number of binary state variables, which is another reason why "SDDiP" has poor performance.

In general, we recommend that you introduce integer variables into your model without fear of the consequences, and that you treat the resulting policy as a good heuristic, rather than an attempt to find a globally optimal policy.

diff --git a/previews/PR811/guides/add_multidimensional_noise/index.html b/previews/PR811/guides/add_multidimensional_noise/index.html index a038a4acd..546bde263 100644 --- a/previews/PR811/guides/add_multidimensional_noise/index.html +++ b/previews/PR811/guides/add_multidimensional_noise/index.html @@ -81,4 +81,4 @@ julia> SDDP.simulate(model, 1); ω is: [54, 38, 19] ω is: [43, 3, 13] -ω is: [43, 4, 17] +ω is: [43, 4, 17] diff --git a/previews/PR811/guides/add_noise_in_the_constraint_matrix/index.html b/previews/PR811/guides/add_noise_in_the_constraint_matrix/index.html index 60cce1ce5..902cf5f8d 100644 --- a/previews/PR811/guides/add_noise_in_the_constraint_matrix/index.html +++ b/previews/PR811/guides/add_noise_in_the_constraint_matrix/index.html @@ -20,4 +20,4 @@ julia> SDDP.simulate(model, 1); emissions : x_out <= 1 emissions : 0.2 x_out <= 1 -emissions : 0.5 x_out <= 1
Note

JuMP will normalize constraints by moving all variables to the left-hand side. Thus, @constraint(model, 0 <= 1 - x.out) becomes x.out <= 1. JuMP.set_normalized_coefficient sets the coefficient on the normalized constraint.

+emissions : 0.5 x_out <= 1
Note

JuMP will normalize constraints by moving all variables to the left-hand side. Thus, @constraint(model, 0 <= 1 - x.out) becomes x.out <= 1. JuMP.set_normalized_coefficient sets the coefficient on the normalized constraint.

diff --git a/previews/PR811/guides/choose_a_stopping_rule/index.html b/previews/PR811/guides/choose_a_stopping_rule/index.html index d32efd189..9842a8fe3 100644 --- a/previews/PR811/guides/choose_a_stopping_rule/index.html +++ b/previews/PR811/guides/choose_a_stopping_rule/index.html @@ -21,4 +21,4 @@ stopping_rules = [ SDDP.StoppingChain(SDDP.BoundStalling(10, 1e-4), SDDP.TimeLimit(100.0)), ], -)

See Stopping rules for a list of stopping rules supported by SDDP.jl.

+)

See Stopping rules for a list of stopping rules supported by SDDP.jl.

diff --git a/previews/PR811/guides/create_a_belief_state/index.html b/previews/PR811/guides/create_a_belief_state/index.html index 33d2abd1b..fb149675a 100644 --- a/previews/PR811/guides/create_a_belief_state/index.html +++ b/previews/PR811/guides/create_a_belief_state/index.html @@ -34,4 +34,4 @@ (1, 2) => (2, 2) w.p. 0.2 Partitions {(1, 1), (1, 2)} - {(2, 1), (2, 2)} + {(2, 1), (2, 2)} diff --git a/previews/PR811/guides/create_a_general_policy_graph/index.html b/previews/PR811/guides/create_a_general_policy_graph/index.html index ad98dcdb3..f9bde2364 100644 --- a/previews/PR811/guides/create_a_general_policy_graph/index.html +++ b/previews/PR811/guides/create_a_general_policy_graph/index.html @@ -110,4 +110,4 @@ @variable(subproblem, x >= 0, SDDP.State, initial_value = 1) @constraint(subproblem, x.out <= x.in) @stageobjective(subproblem, price * x.out) -end +end diff --git a/previews/PR811/guides/debug_a_model/index.html b/previews/PR811/guides/debug_a_model/index.html index 6f008b32b..885cf91f1 100644 --- a/previews/PR811/guides/debug_a_model/index.html +++ b/previews/PR811/guides/debug_a_model/index.html @@ -68,4 +68,4 @@ julia> optimize!(det_equiv) julia> objective_value(det_equiv) --5.472500000000001
Warning

The deterministic equivalent scales poorly with problem size. Only use this on small problems!

+-5.472500000000001
Warning

The deterministic equivalent scales poorly with problem size. Only use this on small problems!

diff --git a/previews/PR811/guides/improve_computational_performance/index.html b/previews/PR811/guides/improve_computational_performance/index.html index 196d8c9df..99d1910e6 100644 --- a/previews/PR811/guides/improve_computational_performance/index.html +++ b/previews/PR811/guides/improve_computational_performance/index.html @@ -45,4 +45,4 @@ env = Gurobi.Env() set_optimizer(m, () -> Gurobi.Optimizer(env)) end, -) +) diff --git a/previews/PR811/guides/simulate_using_a_different_sampling_scheme/index.html b/previews/PR811/guides/simulate_using_a_different_sampling_scheme/index.html index 54afcfdd7..dadd66075 100644 --- a/previews/PR811/guides/simulate_using_a_different_sampling_scheme/index.html +++ b/previews/PR811/guides/simulate_using_a_different_sampling_scheme/index.html @@ -165,4 +165,4 @@ ], [0.3, 0.7], ) -A Historical sampler with 2 scenarios sampled probabilistically.
Tip

Your sample space doesn't have to be a NamedTuple. It an be any Julia type! Use a Vector if that is easier, or define your own struct.

+A Historical sampler with 2 scenarios sampled probabilistically.
Tip

Your sample space doesn't have to be a NamedTuple. It an be any Julia type! Use a Vector if that is easier, or define your own struct.

diff --git a/previews/PR811/index.html b/previews/PR811/index.html index eef79d0e6..510281885 100644 --- a/previews/PR811/index.html +++ b/previews/PR811/index.html @@ -47,4 +47,4 @@ journal = {Annals of Operations Research}, author = {Dowson, O. and Morton, D.P. and Pagnoncelli, B.K.}, year = {2022}, -}

Here is an earlier preprint.

+}

Here is an earlier preprint.

diff --git a/previews/PR811/release_notes/index.html b/previews/PR811/release_notes/index.html index fad1682ee..b048bb66d 100644 --- a/previews/PR811/release_notes/index.html +++ b/previews/PR811/release_notes/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-HZQQDVMPZW', {'page_path': location.pathname + location.search + location.hash}); -

Release notes

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

v1.10.1 (November 28, 2024)

Fixed

Other

  • Documentation updates (#801)

v1.10.0 (November 19, 2024)

Added

  • Added root_node_risk_measure keyword to train (#804)

Fixed

  • Fixed a bug with cut sharing in a graph with zero-probability arcs (#797)

Other

v1.9.0 (October 17, 2024)

Added

Fixed

  • Fixed the tests to skip threading tests if running in serial (#770)
  • Fixed BanditDuality to handle the case where the standard deviation is NaN (#779)
  • Fixed an error when lagged state variables are encountered in MSPFormat (#786)
  • Fixed publication_plot with replications of different lengths (#788)
  • Fixed CTRL+C interrupting the code at unsafe points (#789)

Other

  • Documentation improvements (#771) (#772)
  • Updated printing because of changes in JuMP (#773)

v1.8.1 (August 5, 2024)

Fixed

  • Fixed various issues with SDDP.Threaded() (#761)
  • Fixed a deprecation warning for sorting a dictionary (#763)

Other

  • Updated copyright notices (#762)
  • Updated .JuliaFormatter.toml (#764)

v1.8.0 (July 24, 2024)

Added

  • Added SDDP.Threaded(), which is an experimental parallel scheme that supports solving problems using multiple threads. Some parts of SDDP.jl may not be thread-safe, and this can cause incorrect results, segfaults, or other errors. Please use with care and report any issues by opening a GitHub issue. (#758)

Other

  • Documentation improvements and fixes (#747) (#759)

v1.7.0 (June 4, 2024)

Added

  • Added sample_backward_noise_terms_with_state for creating backward pass sampling schemes that depend on the current primal state. (#742) (Thanks @arthur-brigatto)

Fixed

  • Fixed error message when publication_plot has non-finite data (#738)

Other

  • Updated the logo constructor (#730)

v1.6.7 (February 1, 2024)

Fixed

  • Fixed non-constant state dimension in the MSPFormat reader (#695)
  • Fixed SimulatorSamplingScheme for deterministic nodes (#710)
  • Fixed line search in BFGS (#711)
  • Fixed handling of NEARLY_FEASIBLE_POINT status (#726)

Other

  • Documentation improvements (#692) (#694) (#706) (#716) (#727)
  • Updated to StochOptFormat v1.0 (#705)
  • Added an experimental OuterApproximation algorithm (#709)
  • Updated .gitignore (#717)
  • Added code for MDP paper (#720) (#721)
  • Added Google analytics (#723)

v1.6.6 (September 29, 2023)

Other

v1.6.5 (September 25, 2023)

Fixed

Other

v1.6.4 (September 23, 2023)

Fixed

Other

  • Documentation updates (#658) (#666) (#671)
  • Switch to GitHub action for deploying docs (#668) (#670)
  • Update to Documenter@1 (#669)

v1.6.3 (September 8, 2023)

Fixed

  • Fixed default stopping rule with iteration_limit or time_limit set (#662)

Other

v1.6.2 (August 24, 2023)

Fixed

  • MSPFormat now detect and exploit stagewise independent lattices (#653)
  • Fixed set_optimizer for models read from file (#654)

Other

  • Fixed typo in pglib_opf.jl (#647)
  • Fixed documentation build and added color (#652)

v1.6.1 (July 20, 2023)

Fixed

  • Fixed bugs in MSPFormat reader (#638) (#639)

Other

  • Clarified OutOfSampleMonteCarlo docstring (#643)

v1.6.0 (July 3, 2023)

Added

Other

v1.5.1 (June 30, 2023)

This release contains a number of minor code changes, but it has a large impact on the content that is printed to screen. In particular, we now log periodically, instead of each iteration, and a "good" stopping rule is used as the default if none are specified. Try using SDDP.train(model) to see the difference.

Other

  • Fixed various typos in the documentation (#617)
  • Fixed printing test after changes in JuMP (#618)
  • Set SimulationStoppingRule as the default stopping rule (#619)
  • Changed the default logging frequency. Pass log_every_seconds = 0.0 to train to revert to the old behavior. (#620)
  • Added example usage with Distributions.jl (@slwu89) (#622)
  • Removed the numerical issue @warn (#627)
  • Improved the quality of docstrings (#630)

v1.5.0 (May 14, 2023)

Added

  • Added the ability to use a different model for the forward pass. This is a novel feature that lets you train better policies when the model is non-convex or does not have a well-defined dual. See the Alternative forward models tutorial in which we train convex and non-convex formulations of the optimal power flow problem. (#611)

Other

  • Updated missing changelog entries (#608)
  • Removed global variables (#610)
  • Converted the Options struct to keyword arguments. This struct was a private implementation detail, but the change is breaking if you developed an extension to SDDP that touched these internals. (#612)
  • Fixed some typos (#613)

v1.4.0 (May 8, 2023)

Added

Fixed

  • Fixed parsing of some MSPFormat files (#602) (#604)
  • Fixed printing in header (#605)

v1.3.0 (May 3, 2023)

Added

  • Added experimental support for SDDP.MSPFormat.read_from_file (#593)

Other

  • Updated to StochOptFormat v0.3 (#600)

v1.2.1 (May 1, 2023)

Fixed

  • Fixed log_every_seconds (#597)

v1.2.0 (May 1, 2023)

Added

Other

  • Tweaked how the log is printed (#588)
  • Updated to StochOptFormat v0.2 (#592)

v1.1.4 (April 10, 2023)

Fixed

  • Logs are now flushed every iteration (#584)

Other

  • Added docstrings to various functions (#581)
  • Minor documentation updates (#580)
  • Clarified integrality documentation (#582)
  • Updated the README (#585)
  • Number of numerical issues is now printed to the log (#586)

v1.1.3 (April 2, 2023)

Other

v1.1.2 (March 18, 2023)

Other

v1.1.1 (March 16, 2023)

Other

  • Fixed email in Project.toml
  • Added notebook to documentation tutorials (#571)

v1.1.0 (January 12, 2023)

Added

v1.0.0 (January 3, 2023)

Although we're bumping MAJOR version, this is a non-breaking release. Going forward:

  • New features will bump the MINOR version
  • Bug fixes, maintenance, and documentation updates will bump the PATCH version
  • We will support only the Long Term Support (currently v1.6.7) and the latest patch (currently v1.8.4) releases of Julia. Updates to the LTS version will bump the MINOR version
  • Updates to the compat bounds of package dependencies will bump the PATCH version.

We do not intend any breaking changes to the public API, which would require a new MAJOR release. The public API is everything defined in the documentation. Anything not in the documentation is considered private and may change in any PATCH release.

Added

Other

v0.4.9 (January 3, 2023)

Added

Other

  • Added tutorial on Markov Decision Processes (#556)
  • Added two-stage newsvendor tutorial (#557)
  • Refactored the layout of the documentation (#554) (#555)
  • Updated copyright to 2023 (#558)
  • Fixed errors in the documentation (#561)

v0.4.8 (December 19, 2022)

Added

Fixed

  • Reverted then fixed (#531) because it failed to account for problems with integer variables (#546) (#551)

v0.4.7 (December 17, 2022)

Added

  • Added initial_node support to InSampleMonteCarlo and OutOfSampleMonteCarlo (#535)

Fixed

  • Rethrow InterruptException when solver is interrupted (#534)
  • Fixed numerical recovery when we need dual solutions (#531) (Thanks @bfpc)
  • Fixed re-using the dashboard = true option between solves (#538)
  • Fixed bug when no @stageobjective is set (now defaults to 0.0) (#539)
  • Fixed errors thrown when invalid inputs are provided to add_objective_state (#540)

Other

  • Drop support for Julia versions prior to 1.6 (#533)
  • Updated versions of dependencies (#522) (#533)
  • Switched to HiGHS in the documentation and tests (#533)
  • Added license headers (#519)
  • Fixed link in air conditioning example (#521) (Thanks @conema)
  • Clarified variable naming in deterministic equivalent (#525) (Thanks @lucasprocessi)
  • Added this change log (#536)
  • Cuts are now written to model.cuts.json when numerical instability is discovered. This can aid debugging because it allows to you reload the cuts as of the iteration that caused the numerical issue (#537)

v0.4.6 (March 25, 2022)

Other

  • Updated to JuMP v1.0 (#517)

v0.4.5 (March 9, 2022)

Fixed

  • Fixed issue with set_silent in a subproblem (#510)

Other

v0.4.4 (December 11, 2021)

Added

  • Added BanditDuality (#471)
  • Added benchmark scripts (#475) (#476) (#490)
  • write_cuts_to_file now saves visited states (#468)

Fixed

  • Fixed BoundStalling in a deterministic policy (#470) (#474)
  • Fixed magnitude warning with zero coefficients (#483)

Other

  • Improvements to LagrangianDuality (#481) (#482) (#487)
  • Improvements to StrengthenedConicDuality (#486)
  • Switch to functional form for the tests (#478)
  • Fixed typos (#472) (Thanks @vfdev-5)
  • Update to JuMP v0.22 (#498)

v0.4.3 (August 31, 2021)

Added

  • Added biobjective solver (#462)
  • Added forward_pass_callback (#466)

Other

  • Update tutorials and documentation (#459) (#465)
  • Organize how paper materials are stored (#464)

v0.4.2 (August 24, 2021)

Fixed

  • Fixed a bug in Lagrangian duality (#457)

v0.4.1 (August 23, 2021)

Other

  • Minor changes to our implementation of LagrangianDuality (#454) (#455)

v0.4.0 (August 17, 2021)

Breaking

Other

v0.3.17 (July 6, 2021)

Added

Other

  • Display more model attributes (#438)
  • Documentation improvements (#433) (#437) (#439)

v0.3.16 (June 17, 2021)

Added

Other

  • Update risk measure docstrings (#418)

v0.3.15 (June 1, 2021)

Added

Fixed

Other

  • Add JuliaFormatter (#412)
  • Documentation improvements (#406) (#408)

v0.3.14 (March 30, 2021)

Fixed

  • Fixed O(N^2) behavior in get_same_children (#393)

v0.3.13 (March 27, 2021)

Fixed

  • Fixed bug in print.jl
  • Fixed compat of Reexport (#388)

v0.3.12 (March 22, 2021)

Added

  • Added problem statistics to header (#385) (#386)

Fixed

  • Fixed subtypes in visualization (#384)

v0.3.11 (March 22, 2021)

Fixed

  • Fixed constructor in direct mode (#383)

Other

  • Fix documentation (#379)

v0.3.10 (February 23, 2021)

Fixed

  • Fixed seriescolor in publication plot (#376)

v0.3.9 (February 20, 2021)

Added

  • Add option to simulate with different incoming state (#372)
  • Added warning for cuts with high dynamic range (#373)

Fixed

  • Fixed seriesalpha in publication plot (#375)

v0.3.8 (January 19, 2021)

Other

v0.3.7 (January 8, 2021)

Other

v0.3.6 (December 17, 2020)

Other

  • Fix typos (#358)
  • Collapse navigation bar in docs (#359)
  • Update TagBot.yml (#361)

v0.3.5 (November 18, 2020)

Other

  • Update citations (#348)
  • Switch to GitHub actions (#355)

v0.3.4 (August 25, 2020)

Added

  • Added non-uniform distributionally robust risk measure (#328)
  • Added numerical recovery functions (#330)
  • Added experimental StochOptFormat (#332) (#336) (#337) (#341) (#343) (#344)
  • Added entropic risk measure (#347)

Other

v0.3.3 (June 19, 2020)

Added

  • Added asynchronous support for price and belief states (#325)
  • Added ForwardPass plug-in system (#320)

Fixed

  • Fix check for probabilities in Markovian graph (#322)

v0.3.2 (April 6, 2020)

Added

Other

  • Improve error message in deterministic equivalent (#312)
  • Update to RecipesBase 1.0 (#313)

v0.3.1 (February 26, 2020)

Fixed

  • Fixed filename in integrality_handlers.jl (#304)

v0.3.0 (February 20, 2020)

Breaking

  • Breaking changes to update to JuMP v0.21 (#300).

v0.2.4 (February 7, 2020)

Added

  • Added a counter for the number of total subproblem solves (#301)

Other

  • Update formatter (#298)
  • Added tests (#299)

v0.2.3 (January 24, 2020)

Added

  • Added support for convex risk measures (#294)

Fixed

  • Fixed bug when subproblem is infeasible (#296)
  • Fixed bug in deterministic equivalent (#297)

Other

  • Added example from IJOC paper (#293)

v0.2.2 (January 10, 2020)

Fixed

  • Fixed flakey time limit in tests (#291)

Other

  • Removed MathOptFormat.jl (#289)
  • Update copyright (#290)

v0.2.1 (December 19, 2019)

Added

  • Added support for approximating a Markov lattice (#282) (#285)
  • Add tools for visualizing the value function (#272) (#286)
  • Write .mof.json files on error (#284)

Other

  • Improve documentation (#281) (#283)
  • Update tests for Julia 1.3 (#287)

v0.2.0 (December 16, 2019)

This version added the asynchronous parallel implementation with a few minor breaking changes in how we iterated internally. It didn't break basic user-facing models, only implementations that implemented some of the extension features. It probably could have been a v1.1 release.

Added

  • Added asynchronous parallel implementation (#277)
  • Added roll-out algorithm for cyclic graphs (#279)

Other

  • Improved error messages in PolicyGraph (#271)
  • Added JuliaFormatter (#273) (#276)
  • Fixed compat bounds (#274) (#278)
  • Added documentation for simulating non-standard graphs (#280)

v0.1.0 (October 17, 2019)

A complete rewrite of SDDP.jl based on the policy graph framework. This was essentially a new package. It has minimal code in common with the previous implementation.

Development started on September 28, 2018 in Kokako.jl, and the code was merged into SDDP.jl on March 14, 2019.

The pull request SDDP.jl#180 lists the 29 issues that the rewrite closed.

v0.0.1 (April 18, 2018)

Initial release. Development had been underway since January 22, 2016 in the StochDualDynamicProgram.jl repository. The last development commit there was April 5, 2017. Work then continued in this repository for a year before the first tagged release.

+

Release notes

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

v1.10.1 (November 28, 2024)

Fixed

Other

  • Documentation updates (#801)

v1.10.0 (November 19, 2024)

Added

  • Added root_node_risk_measure keyword to train (#804)

Fixed

  • Fixed a bug with cut sharing in a graph with zero-probability arcs (#797)

Other

v1.9.0 (October 17, 2024)

Added

Fixed

  • Fixed the tests to skip threading tests if running in serial (#770)
  • Fixed BanditDuality to handle the case where the standard deviation is NaN (#779)
  • Fixed an error when lagged state variables are encountered in MSPFormat (#786)
  • Fixed publication_plot with replications of different lengths (#788)
  • Fixed CTRL+C interrupting the code at unsafe points (#789)

Other

  • Documentation improvements (#771) (#772)
  • Updated printing because of changes in JuMP (#773)

v1.8.1 (August 5, 2024)

Fixed

  • Fixed various issues with SDDP.Threaded() (#761)
  • Fixed a deprecation warning for sorting a dictionary (#763)

Other

  • Updated copyright notices (#762)
  • Updated .JuliaFormatter.toml (#764)

v1.8.0 (July 24, 2024)

Added

  • Added SDDP.Threaded(), which is an experimental parallel scheme that supports solving problems using multiple threads. Some parts of SDDP.jl may not be thread-safe, and this can cause incorrect results, segfaults, or other errors. Please use with care and report any issues by opening a GitHub issue. (#758)

Other

  • Documentation improvements and fixes (#747) (#759)

v1.7.0 (June 4, 2024)

Added

  • Added sample_backward_noise_terms_with_state for creating backward pass sampling schemes that depend on the current primal state. (#742) (Thanks @arthur-brigatto)

Fixed

  • Fixed error message when publication_plot has non-finite data (#738)

Other

  • Updated the logo constructor (#730)

v1.6.7 (February 1, 2024)

Fixed

  • Fixed non-constant state dimension in the MSPFormat reader (#695)
  • Fixed SimulatorSamplingScheme for deterministic nodes (#710)
  • Fixed line search in BFGS (#711)
  • Fixed handling of NEARLY_FEASIBLE_POINT status (#726)

Other

  • Documentation improvements (#692) (#694) (#706) (#716) (#727)
  • Updated to StochOptFormat v1.0 (#705)
  • Added an experimental OuterApproximation algorithm (#709)
  • Updated .gitignore (#717)
  • Added code for MDP paper (#720) (#721)
  • Added Google analytics (#723)

v1.6.6 (September 29, 2023)

Other

v1.6.5 (September 25, 2023)

Fixed

Other

v1.6.4 (September 23, 2023)

Fixed

Other

  • Documentation updates (#658) (#666) (#671)
  • Switch to GitHub action for deploying docs (#668) (#670)
  • Update to Documenter@1 (#669)

v1.6.3 (September 8, 2023)

Fixed

  • Fixed default stopping rule with iteration_limit or time_limit set (#662)

Other

v1.6.2 (August 24, 2023)

Fixed

  • MSPFormat now detect and exploit stagewise independent lattices (#653)
  • Fixed set_optimizer for models read from file (#654)

Other

  • Fixed typo in pglib_opf.jl (#647)
  • Fixed documentation build and added color (#652)

v1.6.1 (July 20, 2023)

Fixed

  • Fixed bugs in MSPFormat reader (#638) (#639)

Other

  • Clarified OutOfSampleMonteCarlo docstring (#643)

v1.6.0 (July 3, 2023)

Added

Other

v1.5.1 (June 30, 2023)

This release contains a number of minor code changes, but it has a large impact on the content that is printed to screen. In particular, we now log periodically, instead of each iteration, and a "good" stopping rule is used as the default if none are specified. Try using SDDP.train(model) to see the difference.

Other

  • Fixed various typos in the documentation (#617)
  • Fixed printing test after changes in JuMP (#618)
  • Set SimulationStoppingRule as the default stopping rule (#619)
  • Changed the default logging frequency. Pass log_every_seconds = 0.0 to train to revert to the old behavior. (#620)
  • Added example usage with Distributions.jl (@slwu89) (#622)
  • Removed the numerical issue @warn (#627)
  • Improved the quality of docstrings (#630)

v1.5.0 (May 14, 2023)

Added

  • Added the ability to use a different model for the forward pass. This is a novel feature that lets you train better policies when the model is non-convex or does not have a well-defined dual. See the Alternative forward models tutorial in which we train convex and non-convex formulations of the optimal power flow problem. (#611)

Other

  • Updated missing changelog entries (#608)
  • Removed global variables (#610)
  • Converted the Options struct to keyword arguments. This struct was a private implementation detail, but the change is breaking if you developed an extension to SDDP that touched these internals. (#612)
  • Fixed some typos (#613)

v1.4.0 (May 8, 2023)

Added

Fixed

  • Fixed parsing of some MSPFormat files (#602) (#604)
  • Fixed printing in header (#605)

v1.3.0 (May 3, 2023)

Added

  • Added experimental support for SDDP.MSPFormat.read_from_file (#593)

Other

  • Updated to StochOptFormat v0.3 (#600)

v1.2.1 (May 1, 2023)

Fixed

  • Fixed log_every_seconds (#597)

v1.2.0 (May 1, 2023)

Added

Other

  • Tweaked how the log is printed (#588)
  • Updated to StochOptFormat v0.2 (#592)

v1.1.4 (April 10, 2023)

Fixed

  • Logs are now flushed every iteration (#584)

Other

  • Added docstrings to various functions (#581)
  • Minor documentation updates (#580)
  • Clarified integrality documentation (#582)
  • Updated the README (#585)
  • Number of numerical issues is now printed to the log (#586)

v1.1.3 (April 2, 2023)

Other

v1.1.2 (March 18, 2023)

Other

v1.1.1 (March 16, 2023)

Other

  • Fixed email in Project.toml
  • Added notebook to documentation tutorials (#571)

v1.1.0 (January 12, 2023)

Added

v1.0.0 (January 3, 2023)

Although we're bumping MAJOR version, this is a non-breaking release. Going forward:

  • New features will bump the MINOR version
  • Bug fixes, maintenance, and documentation updates will bump the PATCH version
  • We will support only the Long Term Support (currently v1.6.7) and the latest patch (currently v1.8.4) releases of Julia. Updates to the LTS version will bump the MINOR version
  • Updates to the compat bounds of package dependencies will bump the PATCH version.

We do not intend any breaking changes to the public API, which would require a new MAJOR release. The public API is everything defined in the documentation. Anything not in the documentation is considered private and may change in any PATCH release.

Added

Other

v0.4.9 (January 3, 2023)

Added

Other

  • Added tutorial on Markov Decision Processes (#556)
  • Added two-stage newsvendor tutorial (#557)
  • Refactored the layout of the documentation (#554) (#555)
  • Updated copyright to 2023 (#558)
  • Fixed errors in the documentation (#561)

v0.4.8 (December 19, 2022)

Added

Fixed

  • Reverted then fixed (#531) because it failed to account for problems with integer variables (#546) (#551)

v0.4.7 (December 17, 2022)

Added

  • Added initial_node support to InSampleMonteCarlo and OutOfSampleMonteCarlo (#535)

Fixed

  • Rethrow InterruptException when solver is interrupted (#534)
  • Fixed numerical recovery when we need dual solutions (#531) (Thanks @bfpc)
  • Fixed re-using the dashboard = true option between solves (#538)
  • Fixed bug when no @stageobjective is set (now defaults to 0.0) (#539)
  • Fixed errors thrown when invalid inputs are provided to add_objective_state (#540)

Other

  • Drop support for Julia versions prior to 1.6 (#533)
  • Updated versions of dependencies (#522) (#533)
  • Switched to HiGHS in the documentation and tests (#533)
  • Added license headers (#519)
  • Fixed link in air conditioning example (#521) (Thanks @conema)
  • Clarified variable naming in deterministic equivalent (#525) (Thanks @lucasprocessi)
  • Added this change log (#536)
  • Cuts are now written to model.cuts.json when numerical instability is discovered. This can aid debugging because it allows to you reload the cuts as of the iteration that caused the numerical issue (#537)

v0.4.6 (March 25, 2022)

Other

  • Updated to JuMP v1.0 (#517)

v0.4.5 (March 9, 2022)

Fixed

  • Fixed issue with set_silent in a subproblem (#510)

Other

v0.4.4 (December 11, 2021)

Added

  • Added BanditDuality (#471)
  • Added benchmark scripts (#475) (#476) (#490)
  • write_cuts_to_file now saves visited states (#468)

Fixed

  • Fixed BoundStalling in a deterministic policy (#470) (#474)
  • Fixed magnitude warning with zero coefficients (#483)

Other

  • Improvements to LagrangianDuality (#481) (#482) (#487)
  • Improvements to StrengthenedConicDuality (#486)
  • Switch to functional form for the tests (#478)
  • Fixed typos (#472) (Thanks @vfdev-5)
  • Update to JuMP v0.22 (#498)

v0.4.3 (August 31, 2021)

Added

  • Added biobjective solver (#462)
  • Added forward_pass_callback (#466)

Other

  • Update tutorials and documentation (#459) (#465)
  • Organize how paper materials are stored (#464)

v0.4.2 (August 24, 2021)

Fixed

  • Fixed a bug in Lagrangian duality (#457)

v0.4.1 (August 23, 2021)

Other

  • Minor changes to our implementation of LagrangianDuality (#454) (#455)

v0.4.0 (August 17, 2021)

Breaking

Other

v0.3.17 (July 6, 2021)

Added

Other

  • Display more model attributes (#438)
  • Documentation improvements (#433) (#437) (#439)

v0.3.16 (June 17, 2021)

Added

Other

  • Update risk measure docstrings (#418)

v0.3.15 (June 1, 2021)

Added

Fixed

Other

  • Add JuliaFormatter (#412)
  • Documentation improvements (#406) (#408)

v0.3.14 (March 30, 2021)

Fixed

  • Fixed O(N^2) behavior in get_same_children (#393)

v0.3.13 (March 27, 2021)

Fixed

  • Fixed bug in print.jl
  • Fixed compat of Reexport (#388)

v0.3.12 (March 22, 2021)

Added

  • Added problem statistics to header (#385) (#386)

Fixed

  • Fixed subtypes in visualization (#384)

v0.3.11 (March 22, 2021)

Fixed

  • Fixed constructor in direct mode (#383)

Other

  • Fix documentation (#379)

v0.3.10 (February 23, 2021)

Fixed

  • Fixed seriescolor in publication plot (#376)

v0.3.9 (February 20, 2021)

Added

  • Add option to simulate with different incoming state (#372)
  • Added warning for cuts with high dynamic range (#373)

Fixed

  • Fixed seriesalpha in publication plot (#375)

v0.3.8 (January 19, 2021)

Other

v0.3.7 (January 8, 2021)

Other

v0.3.6 (December 17, 2020)

Other

  • Fix typos (#358)
  • Collapse navigation bar in docs (#359)
  • Update TagBot.yml (#361)

v0.3.5 (November 18, 2020)

Other

  • Update citations (#348)
  • Switch to GitHub actions (#355)

v0.3.4 (August 25, 2020)

Added

  • Added non-uniform distributionally robust risk measure (#328)
  • Added numerical recovery functions (#330)
  • Added experimental StochOptFormat (#332) (#336) (#337) (#341) (#343) (#344)
  • Added entropic risk measure (#347)

Other

v0.3.3 (June 19, 2020)

Added

  • Added asynchronous support for price and belief states (#325)
  • Added ForwardPass plug-in system (#320)

Fixed

  • Fix check for probabilities in Markovian graph (#322)

v0.3.2 (April 6, 2020)

Added

Other

  • Improve error message in deterministic equivalent (#312)
  • Update to RecipesBase 1.0 (#313)

v0.3.1 (February 26, 2020)

Fixed

  • Fixed filename in integrality_handlers.jl (#304)

v0.3.0 (February 20, 2020)

Breaking

  • Breaking changes to update to JuMP v0.21 (#300).

v0.2.4 (February 7, 2020)

Added

  • Added a counter for the number of total subproblem solves (#301)

Other

  • Update formatter (#298)
  • Added tests (#299)

v0.2.3 (January 24, 2020)

Added

  • Added support for convex risk measures (#294)

Fixed

  • Fixed bug when subproblem is infeasible (#296)
  • Fixed bug in deterministic equivalent (#297)

Other

  • Added example from IJOC paper (#293)

v0.2.2 (January 10, 2020)

Fixed

  • Fixed flakey time limit in tests (#291)

Other

  • Removed MathOptFormat.jl (#289)
  • Update copyright (#290)

v0.2.1 (December 19, 2019)

Added

  • Added support for approximating a Markov lattice (#282) (#285)
  • Add tools for visualizing the value function (#272) (#286)
  • Write .mof.json files on error (#284)

Other

  • Improve documentation (#281) (#283)
  • Update tests for Julia 1.3 (#287)

v0.2.0 (December 16, 2019)

This version added the asynchronous parallel implementation with a few minor breaking changes in how we iterated internally. It didn't break basic user-facing models, only implementations that implemented some of the extension features. It probably could have been a v1.1 release.

Added

  • Added asynchronous parallel implementation (#277)
  • Added roll-out algorithm for cyclic graphs (#279)

Other

  • Improved error messages in PolicyGraph (#271)
  • Added JuliaFormatter (#273) (#276)
  • Fixed compat bounds (#274) (#278)
  • Added documentation for simulating non-standard graphs (#280)

v0.1.0 (October 17, 2019)

A complete rewrite of SDDP.jl based on the policy graph framework. This was essentially a new package. It has minimal code in common with the previous implementation.

Development started on September 28, 2018 in Kokako.jl, and the code was merged into SDDP.jl on March 14, 2019.

The pull request SDDP.jl#180 lists the 29 issues that the rewrite closed.

v0.0.1 (April 18, 2018)

Initial release. Development had been underway since January 22, 2016 in the StochDualDynamicProgram.jl repository. The last development commit there was April 5, 2017. Work then continued in this repository for a year before the first tagged release.

diff --git a/previews/PR811/tutorial/SDDP.log b/previews/PR811/tutorial/SDDP.log index 7d318451e..3e3022f39 100644 --- a/previews/PR811/tutorial/SDDP.log +++ b/previews/PR811/tutorial/SDDP.log @@ -4,7 +4,7 @@ problem nodes : 30 state variables : 5 - scenarios : 9.84375e+11 + scenarios : 1.10547e+12 existing cuts : false options solver : serial mode @@ -23,24 +23,24 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 -4.206878e+01 5.941262e+01 1.281221e+00 162 1 - 55 8.572786e+00 7.917480e+00 2.284350e+00 8910 1 - 101 7.981373e+00 7.897983e+00 3.300510e+00 16362 1 - 143 8.677458e+00 7.897777e+00 4.325968e+00 23166 1 - 179 8.493768e+00 7.897068e+00 5.335664e+00 28998 1 - 215 6.033131e+00 7.896217e+00 6.343685e+00 34830 1 - 249 3.130692e+00 7.895975e+00 7.348002e+00 40338 1 - 281 7.805216e+00 7.895890e+00 8.365414e+00 45522 1 - 311 9.433888e+00 7.895849e+00 9.384863e+00 50382 1 - 446 1.051951e+01 7.895307e+00 1.441280e+01 72252 1 - 562 7.960151e+00 7.895061e+00 1.943070e+01 91044 1 - 574 1.035700e+01 7.895061e+00 2.000098e+01 92988 1 + 1 -2.800297e+01 6.046266e+01 1.302636e+00 162 1 + 62 9.110901e+00 7.919372e+00 2.310957e+00 10044 1 + 112 9.587047e+00 7.892281e+00 3.313653e+00 18144 1 + 153 1.132638e+01 7.891248e+00 4.314246e+00 24786 1 + 193 9.701241e+00 7.890591e+00 5.341025e+00 31266 1 + 229 9.204296e+00 7.890388e+00 6.342482e+00 37098 1 + 263 7.930002e+00 7.889763e+00 7.344264e+00 42606 1 + 297 8.093624e+00 7.886211e+00 8.349875e+00 48114 1 + 330 8.667298e+00 7.886186e+00 9.363293e+00 53460 1 + 468 8.824978e+00 7.886167e+00 1.438189e+01 75816 1 + 590 7.919321e+00 7.885395e+00 1.938828e+01 95580 1 + 604 8.764670e+00 7.885338e+00 2.000715e+01 97848 1 ------------------------------------------------------------------- status : time_limit -total time (s) : 2.000098e+01 -total solves : 92988 -best bound : 7.895061e+00 -simulation ci : 8.851335e+00 ± 3.582455e-01 +total time (s) : 2.000715e+01 +total solves : 97848 +best bound : 7.885338e+00 +simulation ci : 8.894186e+00 ± 3.152135e-01 numeric issues : 0 ------------------------------------------------------------------- @@ -70,52 +70,52 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 7.390041e+02 6.404877e-03 103 1 - 2 2.986205e+02 5.948838e+02 2.317381e-02 406 1 - 3 5.948838e+02 5.595833e+02 2.796483e-02 509 1 - 4 6.453132e+02 5.549646e+02 3.261399e-02 612 1 - 5 4.686292e+02 5.531378e+02 3.716588e-02 715 1 - 6 5.567797e+02 5.527552e+02 4.177380e-02 818 1 - 7 6.110663e+02 5.525985e+02 4.650092e-02 921 1 - 8 6.086563e+02 5.525940e+02 5.112600e-02 1024 1 - 9 4.675566e+02 5.525916e+02 5.579400e-02 1127 1 - 10 5.901527e+02 5.525916e+02 6.063986e-02 1230 1 - 11 4.280262e+02 5.525916e+02 6.545496e-02 1333 1 - 12 6.109591e+02 5.525916e+02 7.044291e-02 1436 1 - 13 5.358535e+02 5.525916e+02 7.526088e-02 1539 1 - 14 6.109591e+02 5.525916e+02 8.004189e-02 1642 1 - 15 4.302809e+02 5.525916e+02 8.492184e-02 1745 1 - 16 4.504226e+02 5.525916e+02 8.970380e-02 1848 1 - 17 6.109591e+02 5.525916e+02 9.451890e-02 1951 1 - 18 4.623350e+02 5.525916e+02 9.925580e-02 2054 1 - 19 5.000355e+02 5.525916e+02 1.042149e-01 2157 1 - 20 4.816761e+02 5.525916e+02 1.091499e-01 2260 1 - 21 6.109591e+02 5.525916e+02 1.292350e-01 2563 1 - 22 4.494532e+02 5.525916e+02 1.342900e-01 2666 1 - 23 6.021570e+02 5.525916e+02 1.391129e-01 2769 1 - 24 5.343076e+02 5.525916e+02 2.482328e-01 2872 1 - 25 5.224628e+02 5.525916e+02 2.532270e-01 2975 1 - 26 6.109591e+02 5.525916e+02 2.582688e-01 3078 1 - 27 5.677323e+02 5.525916e+02 2.632589e-01 3181 1 - 28 4.969335e+02 5.525916e+02 2.682159e-01 3284 1 - 29 4.647519e+02 5.525916e+02 2.732718e-01 3387 1 - 30 6.109591e+02 5.525916e+02 2.781549e-01 3490 1 - 31 6.109591e+02 5.525916e+02 2.830799e-01 3593 1 - 32 6.109591e+02 5.525916e+02 2.880180e-01 3696 1 - 33 5.440677e+02 5.525916e+02 2.930539e-01 3799 1 - 34 4.669924e+02 5.525916e+02 2.980690e-01 3902 1 - 35 5.224628e+02 5.525916e+02 3.030598e-01 4005 1 - 36 5.438199e+02 5.525916e+02 3.081069e-01 4108 1 - 37 6.109591e+02 5.525916e+02 3.131750e-01 4211 1 - 38 4.510160e+02 5.525916e+02 3.181119e-01 4314 1 - 39 3.770820e+02 5.525916e+02 3.231230e-01 4417 1 - 40 6.109591e+02 5.525916e+02 3.281329e-01 4520 1 + 1 0.000000e+00 7.288656e+02 6.253004e-03 103 1 + 2 4.149257e+02 6.047939e+02 2.256107e-02 406 1 + 3 6.047939e+02 5.687644e+02 2.714705e-02 509 1 + 4 6.562646e+02 5.649475e+02 3.169394e-02 612 1 + 5 5.580831e+02 5.633213e+02 3.614902e-02 715 1 + 6 5.364529e+02 5.627452e+02 4.063010e-02 818 1 + 7 6.208254e+02 5.627143e+02 4.503107e-02 921 1 + 8 6.186186e+02 5.626895e+02 4.952002e-02 1024 1 + 9 4.698379e+02 5.626867e+02 5.395007e-02 1127 1 + 10 6.006088e+02 5.626867e+02 5.840397e-02 1230 1 + 11 6.166476e+02 5.626867e+02 6.302094e-02 1333 1 + 12 4.999140e+02 5.626867e+02 6.770802e-02 1436 1 + 13 4.551252e+02 5.626867e+02 7.229900e-02 1539 1 + 14 5.154644e+02 5.626867e+02 7.689691e-02 1642 1 + 15 5.300583e+02 5.626867e+02 8.158302e-02 1745 1 + 16 6.166476e+02 5.626867e+02 8.621788e-02 1848 1 + 17 6.166476e+02 5.626867e+02 9.091806e-02 1951 1 + 18 6.166476e+02 5.626867e+02 9.555793e-02 2054 1 + 19 6.166476e+02 5.626867e+02 1.002660e-01 2157 1 + 20 6.166476e+02 5.626867e+02 1.049111e-01 2260 1 + 21 6.166476e+02 5.626867e+02 1.240809e-01 2563 1 + 22 3.926782e+02 5.626867e+02 1.287379e-01 2666 1 + 23 4.608279e+02 5.626867e+02 1.335170e-01 2769 1 + 24 4.934783e+02 5.626867e+02 1.382120e-01 2872 1 + 25 6.134071e+02 5.626867e+02 1.428580e-01 2975 1 + 26 3.738141e+02 5.626867e+02 1.477699e-01 3078 1 + 27 4.608279e+02 5.626867e+02 1.524570e-01 3181 1 + 28 6.166476e+02 5.626867e+02 1.571741e-01 3284 1 + 29 5.858490e+02 5.626867e+02 1.619849e-01 3387 1 + 30 6.166476e+02 5.626867e+02 1.667149e-01 3490 1 + 31 6.166476e+02 5.626867e+02 1.715641e-01 3593 1 + 32 6.166476e+02 5.626867e+02 1.762819e-01 3696 1 + 33 6.166476e+02 5.626867e+02 1.810620e-01 3799 1 + 34 6.166476e+02 5.626867e+02 1.859241e-01 3902 1 + 35 5.428217e+02 5.626867e+02 1.906929e-01 4005 1 + 36 6.134071e+02 5.626867e+02 1.955221e-01 4108 1 + 37 6.166476e+02 5.626867e+02 2.002940e-01 4211 1 + 38 6.166476e+02 5.626867e+02 2.051721e-01 4314 1 + 39 6.076516e+02 5.626867e+02 2.099750e-01 4417 1 + 40 3.944552e+02 5.626867e+02 2.148480e-01 4520 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.281329e-01 +total time (s) : 2.148480e-01 total solves : 4520 -best bound : 5.525916e+02 -simulation ci : 5.195779e+02 ± 3.595635e+01 +best bound : 5.626867e+02 +simulation ci : 5.467476e+02 ± 3.663772e+01 numeric issues : 0 ------------------------------------------------------------------- @@ -145,11 +145,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.079600e+03 3.157700e+02 4.467511e-02 104 1 - 10 6.829100e+02 6.829100e+02 1.466031e-01 1040 1 + 1 1.079600e+03 3.157700e+02 4.390097e-02 104 1 + 10 6.829100e+02 6.829100e+02 1.390100e-01 1040 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.466031e-01 +total time (s) : 1.390100e-01 total solves : 1040 best bound : 6.829100e+02 simulation ci : 7.289889e+02 ± 7.726064e+01 @@ -181,16 +181,16 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 0.000000e+00 4.471517e-02 208 1 - 45 1.015970e+02 2.501284e+02 1.047305e+00 9360 1 - 82 8.881599e+01 2.632311e+02 2.054002e+00 17056 1 - 100 1.198882e+02 2.666197e+02 2.653225e+00 20800 1 + 1 5.619600e+02 2.548809e+01 4.797482e-02 208 1 + 47 2.794782e+02 2.493251e+02 1.068635e+00 9776 1 + 87 1.498337e+02 2.645551e+02 2.081532e+00 18096 1 + 100 1.959000e+02 2.664853e+02 2.432085e+00 20800 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 2.653225e+00 +total time (s) : 2.432085e+00 total solves : 20800 -best bound : 2.666197e+02 -simulation ci : 2.769728e+02 ± 3.705277e+01 +best bound : 2.664853e+02 +simulation ci : 3.200237e+02 ± 4.569034e+01 numeric issues : 0 ------------------------------------------------------------------- @@ -219,34 +219,35 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 7.522165e+04 4.709469e+04 2.835579e-01 3123 1 - 5 7.105922e+04 8.759186e+04 1.462410e+00 15407 1 - 10 2.946450e+04 9.198956e+04 2.644696e+00 26238 1 - 14 1.437630e+05 9.298395e+04 4.136594e+00 38314 1 - 17 2.713174e+05 9.318512e+04 6.652679e+00 54963 1 - 20 7.015304e+04 9.326356e+04 7.956363e+00 63084 1 - 26 9.499089e+04 9.335268e+04 1.377707e+01 95550 1 - 33 1.479632e+05 9.336211e+04 1.898816e+01 120947 1 - 38 2.005318e+04 9.337136e+04 2.399276e+01 142178 1 - 43 1.095355e+05 9.337361e+04 2.953139e+01 163617 1 - 45 4.395784e+05 9.337447e+04 3.802440e+01 189415 1 - 52 1.007213e+05 9.338021e+04 4.371206e+01 207740 1 - 57 2.110075e+05 9.338044e+04 5.113286e+01 231051 1 - 62 3.033249e+05 9.338277e+04 6.057021e+01 258730 1 - 67 1.521672e+05 9.338428e+04 6.777268e+01 278713 1 - 70 3.297146e+05 9.338575e+04 7.466152e+01 296194 1 - 74 3.027746e+04 9.338646e+04 8.015764e+01 309518 1 - 76 3.305361e+05 9.338672e+04 8.630700e+01 324292 1 - 79 4.865088e+05 9.338733e+04 9.911923e+01 354045 1 - 82 2.669285e+05 9.338975e+04 1.053440e+02 367366 1 - 85 3.459473e+05 9.339063e+04 1.146121e+02 386927 1 - 100 1.279878e+05 9.339284e+04 1.363094e+02 430860 1 + 1 1.765543e+05 7.531437e+04 6.209869e-01 7075 1 + 2 5.306559e+05 9.226252e+04 2.842379e+00 29958 1 + 5 1.299119e+05 9.294558e+04 3.900052e+00 39743 1 + 8 1.226027e+05 9.328028e+04 5.514643e+00 52648 1 + 13 1.797956e+05 9.329892e+04 7.201875e+00 64935 1 + 15 1.720022e+05 9.334951e+04 9.283951e+00 78669 1 + 21 1.395994e+05 9.336543e+04 1.497240e+01 111551 1 + 27 2.927228e+04 9.337078e+04 2.021347e+01 137569 1 + 35 1.351935e+05 9.337539e+04 2.587091e+01 163177 1 + 40 1.604219e+05 9.337752e+04 3.147526e+01 183160 1 + 45 3.820557e+05 9.337910e+04 4.066478e+01 216663 1 + 48 5.434189e+05 9.338040e+04 4.991359e+01 247040 1 + 51 1.816256e+05 9.338269e+04 5.725287e+01 269721 1 + 57 2.367720e+05 9.338618e+04 6.374079e+01 288043 1 + 61 8.216129e+04 9.338772e+04 6.904948e+01 303031 1 + 67 2.897234e+04 9.338862e+04 7.445199e+01 317817 1 + 70 2.994891e+05 9.338943e+04 8.239305e+01 338210 1 + 73 3.456753e+05 9.338961e+04 8.954896e+01 355899 1 + 77 6.458147e+04 9.339040e+04 9.533064e+01 369847 1 + 82 1.301077e+05 9.339071e+04 1.026668e+02 386918 1 + 84 4.595395e+04 9.339108e+04 1.081708e+02 399404 1 + 88 1.197247e+05 9.339259e+04 1.147888e+02 414184 1 + 100 6.965854e+04 9.339391e+04 1.385869e+02 463724 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.363094e+02 -total solves : 430860 -best bound : 9.339284e+04 -simulation ci : 9.681754e+04 ± 1.884197e+04 +total time (s) : 1.385869e+02 +total solves : 463724 +best bound : 9.339391e+04 +simulation ci : 1.048370e+05 ± 2.107734e+04 numeric issues : 0 ------------------------------------------------------------------- @@ -275,14 +276,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.750000e+04 2.500000e+03 3.675938e-03 12 1 - 10 7.500000e+03 8.333333e+03 1.411986e-02 120 1 + 1 2.750000e+04 3.437500e+03 3.633022e-03 12 1 + 10 2.000000e+04 8.333333e+03 1.367593e-02 120 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.411986e-02 +total time (s) : 1.367593e-02 total solves : 120 best bound : 8.333333e+03 -simulation ci : 1.287500e+04 ± 4.165000e+03 +simulation ci : 1.303125e+04 ± 4.925497e+03 numeric issues : 0 ------------------------------------------------------------------- @@ -312,19 +313,18 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 4.044053e+05 4.573582e+04 1.952600e-02 212 1 - 48 1.898816e+05 1.443368e+05 1.030853e+00 13476 1 - 102 1.572079e+05 1.443373e+05 2.031849e+00 27124 1 - 164 1.290816e+05 1.443373e+05 3.049588e+00 40268 1 - 213 1.482816e+05 1.443373e+05 4.051144e+00 51756 1 - 266 1.142605e+05 1.443373e+05 5.057745e+00 62992 1 - 287 1.179658e+05 1.443373e+05 5.513835e+00 67444 1 + 1 4.456684e+05 4.573582e+04 1.931691e-02 212 1 + 58 2.019242e+05 1.443354e+05 1.032120e+00 15596 1 + 115 1.146395e+05 1.443372e+05 2.035309e+00 29880 1 + 178 9.863947e+04 1.443374e+05 3.049769e+00 43236 1 + 234 9.085000e+04 1.443374e+05 4.052715e+00 56208 1 + 286 9.085000e+04 1.443374e+05 5.023869e+00 67232 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 5.513835e+00 -total solves : 67444 -best bound : 1.443373e+05 -simulation ci : 1.437148e+05 ± 3.669326e+03 +total time (s) : 5.023869e+00 +total solves : 67232 +best bound : 1.443374e+05 +simulation ci : 1.463885e+05 ± 3.909823e+03 numeric issues : 0 ------------------------------------------------------------------- @@ -353,32 +353,30 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.261395e+05 4.629033e+04 1.603484e-02 253 1 - 40 8.223870e+05 3.110268e+05 1.056395e+00 14467 1 - 59 1.325037e+06 3.124707e+05 2.061967e+00 25175 1 - 82 1.487445e+06 3.126509e+05 3.163571e+00 36118 1 - 101 7.947975e+05 3.126628e+05 4.216599e+00 45335 1 - 126 4.517778e+05 3.126648e+05 5.298299e+00 54075 1 - 145 3.713553e+05 3.126650e+05 6.389154e+00 61633 1 - 160 5.611658e+05 3.126650e+05 7.436390e+00 67864 1 - 177 1.160661e+06 3.126650e+05 8.623258e+00 74454 1 - 186 2.550605e+05 3.126650e+05 9.682608e+00 79356 1 - 238 7.567026e+05 3.126650e+05 1.469167e+01 100345 1 - 270 7.641132e+05 3.126650e+05 1.983227e+01 114993 1 - 299 2.758605e+05 3.126650e+05 2.497983e+01 127391 1 - 316 5.273974e+05 3.126650e+05 3.041085e+01 137593 1 - 332 4.783868e+05 3.126650e+05 3.567293e+01 147101 1 - 349 6.081553e+05 3.126650e+05 4.075312e+01 154972 1 - 358 1.381797e+06 3.126650e+05 4.595205e+01 161680 1 - 373 8.825974e+05 3.126650e+05 5.139970e+01 168688 1 - 384 5.303447e+05 3.126650e+05 5.664452e+01 174915 1 - 400 8.032368e+04 3.126650e+05 6.061250e+01 179614 1 + 1 5.925000e+04 4.040190e+04 9.183168e-03 127 1 + 31 1.404778e+06 3.013109e+05 1.167548e+00 15655 1 + 52 1.019353e+05 3.118068e+05 2.167894e+00 26386 1 + 79 3.556378e+05 3.126211e+05 3.197883e+00 37207 1 + 102 1.127161e+06 3.126629e+05 4.355690e+00 48171 1 + 123 3.268071e+05 3.126649e+05 5.394886e+00 56634 1 + 139 7.257613e+04 3.126650e+05 6.402684e+00 64651 1 + 152 6.472711e+05 3.126650e+05 7.438318e+00 72455 1 + 167 2.473132e+05 3.126650e+05 8.447790e+00 79358 1 + 177 2.345974e+05 3.126650e+05 9.471624e+00 85794 1 + 226 9.373342e+05 3.126650e+05 1.448742e+01 112912 1 + 274 9.666395e+05 3.126650e+05 1.996113e+01 134611 1 + 306 5.097553e+05 3.126650e+05 2.514281e+01 151254 1 + 333 1.631026e+05 3.126650e+05 3.018784e+01 163230 1 + 363 1.145974e+05 3.126650e+05 3.527018e+01 173802 1 + 382 1.915658e+05 3.126650e+05 4.031261e+01 183355 1 + 399 1.344745e+06 3.126650e+05 4.644930e+01 192402 1 + 400 1.908921e+05 3.126650e+05 4.663174e+01 192655 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 6.061250e+01 -total solves : 179614 +total time (s) : 4.663174e+01 +total solves : 192655 best bound : 3.126650e+05 -simulation ci : 3.221874e+05 ± 2.709090e+04 +simulation ci : 3.471375e+05 ± 3.227828e+04 numeric issues : 0 ------------------------------------------------------------------- @@ -407,14 +405,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.562500e+04 1.991887e+03 5.845070e-03 18 1 - 40 1.312500e+04 8.072917e+03 1.328571e-01 1320 1 + 1 2.812500e+04 1.991887e+03 5.608082e-03 18 1 + 40 1.250000e+04 8.072917e+03 1.342120e-01 1320 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.328571e-01 +total time (s) : 1.342120e-01 total solves : 1320 best bound : 8.072917e+03 -simulation ci : 9.055480e+03 ± 2.372164e+03 +simulation ci : 7.955223e+03 ± 2.209038e+03 numeric issues : 0 ------------------------------------------------------------------- @@ -445,11 +443,11 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.499895e+01 1.562631e+00 1.605582e-02 6 1 - 40 8.333333e+00 8.333333e+00 7.100549e-01 246 1 + 1 2.499895e+01 1.562631e+00 1.610589e-02 6 1 + 40 8.333333e+00 8.333333e+00 6.816051e-01 246 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.100549e-01 +total time (s) : 6.816051e-01 total solves : 246 best bound : 8.333333e+00 simulation ci : 8.810723e+00 ± 8.167195e-01 @@ -482,14 +480,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 1.000000e+01 1.208591e-02 35 1 - 40 9.000000e+00 6.561000e+00 7.349939e-01 2884 1 + 1 0.000000e+00 1.000000e+01 4.554033e-03 11 1 + 43 0.000000e+00 6.561000e+00 6.500010e-01 2729 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.349939e-01 -total solves : 2884 +total time (s) : 6.500010e-01 +total solves : 2729 best bound : 6.561000e+00 -simulation ci : 5.950000e+00 ± 3.334032e+00 +simulation ci : 3.953488e+00 ± 1.863137e+00 numeric issues : 0 ------------------------------------------------------------------- @@ -514,14 +512,14 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.515625e+03 2.307692e+03 2.280307e-02 39 1 - 69 8.122500e+03 5.092593e+03 3.268039e-01 3591 1 + 1 1.856250e+03 3.792977e+03 2.103996e-02 39 1 + 75 2.578125e+03 5.092593e+03 3.317330e-01 3825 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.268039e-01 -total solves : 3591 +total time (s) : 3.317330e-01 +total solves : 3825 best bound : 5.092593e+03 -simulation ci : 5.045107e+03 ± 9.521140e+02 +simulation ci : 5.035567e+03 ± 8.906509e+02 numeric issues : 0 ------------------------------------------------------------------- @@ -546,15 +544,15 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 8.687500e+03 2.123386e+03 2.507806e-02 39 1 - 186 2.875000e+03 5.135984e+03 1.026699e+00 8754 1 - 288 1.237500e+04 5.135984e+03 1.520157e+00 13032 1 + 1 5.250000e+03 1.944444e+03 2.288103e-02 39 1 + 197 2.437500e+03 5.135984e+03 1.026698e+00 9483 1 + 286 3.187500e+03 5.135984e+03 1.389911e+00 12954 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.520157e+00 -total solves : 13032 +total time (s) : 1.389911e+00 +total solves : 12954 best bound : 5.135984e+03 -simulation ci : 5.093300e+03 ± 4.706043e+02 +simulation ci : 5.047210e+03 ± 4.909091e+02 numeric issues : 0 ------------------------------------------------------------------- @@ -583,14 +581,14 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 5.625000e+04 3.958333e+03 3.849983e-03 12 1 - 40 5.000000e+03 1.062500e+04 7.199407e-02 642 1 + 1 1.875000e+04 3.958333e+03 3.413916e-03 12 1 + 40 1.875000e+03 1.062500e+04 6.562400e-02 642 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.199407e-02 +total time (s) : 6.562400e-02 total solves : 642 best bound : 1.062500e+04 -simulation ci : 1.144952e+04 ± 3.560509e+03 +simulation ci : 1.192119e+04 ± 2.615892e+03 numeric issues : 0 ------------------------------------------------------------------- @@ -620,16 +618,16 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 8.739943e+04 8.392522e+04 1.107059e-01 23 1 - 4 8.366643e+05 1.610511e+05 1.459596e+00 244 1 - 6 5.727988e+05 3.666291e+05 2.661353e+00 446 1 - 10 5.935476e+05 3.934937e+05 3.845967e+00 630 1 + 1 1.060565e+07 4.875069e+04 6.346560e-01 187 1 + 4 4.933798e+05 3.565300e+05 1.900154e+00 420 1 + 7 1.614108e+06 3.925867e+05 3.791182e+00 729 1 + 10 6.561330e+05 4.110306e+05 4.558589e+00 842 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.845967e+00 -total solves : 630 -best bound : 3.934937e+05 -simulation ci : 5.365945e+05 ± 2.532734e+05 +total time (s) : 4.558589e+00 +total solves : 842 +best bound : 4.110306e+05 +simulation ci : 1.610035e+06 ± 1.988407e+06 numeric issues : 0 ------------------------------------------------------------------- @@ -661,18 +659,17 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 7.020752e+04 8.234303e+04 1.911960e-01 19 1 - 4 4.524619e+06 1.547063e+05 2.931659e+00 216 1 - 5 4.818629e+05 3.312624e+05 4.277423e+00 307 1 - 7 5.479908e+06 3.466548e+05 7.722080e+00 565 1 - 8 5.374182e+05 3.886731e+05 9.032286e+00 660 1 - 10 1.929004e+05 4.106854e+05 9.837247e+00 714 1 + 1 2.472437e+06 3.367377e+04 8.638709e-01 107 1 + 4 5.823863e+05 2.024327e+05 3.085034e+00 260 1 + 6 5.819908e+06 3.758174e+05 6.724806e+00 518 1 + 8 1.337292e+06 3.967638e+05 9.274130e+00 644 1 + 10 1.582847e+05 4.195723e+05 1.031384e+01 710 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 9.837247e+00 -total solves : 714 -best bound : 4.106854e+05 -simulation ci : 1.145677e+06 ± 1.272700e+06 +total time (s) : 1.031384e+01 +total solves : 710 +best bound : 4.195723e+05 +simulation ci : 1.116875e+06 ± 1.128810e+06 numeric issues : 0 ------------------------------------------------------------------- @@ -702,17 +699,17 @@ numerical stability report ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.051620e+06 1.018342e+05 2.495060e-01 36 1 - 3 2.811369e+05 2.192570e+05 1.461578e+00 156 1 - 5 1.148674e+05 2.465873e+05 2.556314e+00 270 1 - 6 7.866119e+05 3.728553e+05 3.877495e+00 375 1 - 10 1.761483e+04 3.911610e+05 4.789682e+00 465 1 + 1 3.510376e+04 4.945735e+04 5.675817e-02 9 1 + 3 7.173198e+05 1.184728e+05 1.626347e+00 183 1 + 6 1.089690e+05 3.415483e+05 2.661640e+00 285 1 + 7 3.504677e+06 3.623161e+05 4.114105e+00 435 1 + 10 7.135552e+05 3.966804e+05 5.825555e+00 609 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 4.789682e+00 -total solves : 465 -best bound : 3.911610e+05 -simulation ci : 4.427065e+05 ± 2.573449e+05 +total time (s) : 5.825555e+00 +total solves : 609 +best bound : 3.966804e+05 +simulation ci : 1.157820e+06 ± 1.092722e+06 numeric issues : 0 ------------------------------------------------------------------- @@ -736,14 +733,14 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 4.375000e+04 1.991887e+03 1.675916e-02 18 1 - 20 1.875000e+03 8.072917e+03 5.456901e-02 360 1 + 1 1.875000e+04 1.991887e+03 1.411796e-02 18 1 + 20 1.875000e+03 8.072917e+03 4.841495e-02 360 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 5.456901e-02 +total time (s) : 4.841495e-02 total solves : 360 best bound : 8.072917e+03 -simulation ci : 9.822043e+03 ± 4.952850e+03 +simulation ci : 7.710737e+03 ± 3.157375e+03 numeric issues : 0 ------------------------------------------------------------------- @@ -767,11 +764,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 6.500000e+00 3.000000e+00 3.309965e-03 6 1 - 5 3.500000e+00 3.500000e+00 6.183863e-03 30 1 + 1 6.500000e+00 3.000000e+00 3.022909e-03 6 1 + 5 3.500000e+00 3.500000e+00 5.645990e-03 30 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 6.183863e-03 +total time (s) : 5.645990e-03 total solves : 30 best bound : 3.500000e+00 simulation ci : 4.100000e+00 ± 1.176000e+00 @@ -798,11 +795,11 @@ subproblem structure ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 6.500000e+00 1.100000e+01 3.236055e-03 6 1 - 5 5.500000e+00 1.100000e+01 5.764008e-03 30 1 + 1 6.500000e+00 1.100000e+01 3.062963e-03 6 1 + 5 5.500000e+00 1.100000e+01 5.445957e-03 30 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 5.764008e-03 +total time (s) : 5.445957e-03 total solves : 30 best bound : 1.100000e+01 simulation ci : 5.700000e+00 ± 3.920000e-01 diff --git a/previews/PR811/tutorial/arma/index.html b/previews/PR811/tutorial/arma/index.html index e51d2267d..e13c2eec5 100644 --- a/previews/PR811/tutorial/arma/index.html +++ b/previews/PR811/tutorial/arma/index.html @@ -44,34 +44,34 @@ end return inflow end
simulator (generic function with 1 method)

When called with no arguments, it produces a vector of inflows:

simulator()
3-element Vector{Float64}:
- 59.6
- 59.7
- 49.7
Warning

The simulator must return a Vector{Float64}, so it is limited to a uni-variate random variable. It is possible to do something similar for multi-variate random variable, but you'll have to manually construct the Markov transition matrix, and solution times scale poorly, even in the two-dimensional case.

The next step is to call SDDP.MarkovianGraph with our simulator. This function will attempt to fit a Markov chain to the stochastic process produced by your simulator. There are two key arguments:

graph = SDDP.MarkovianGraph(simulator; budget = 8, scenarios = 30)
Root
+ 40.0
+ 49.6
+ 59.2
Warning

The simulator must return a Vector{Float64}, so it is limited to a uni-variate random variable. It is possible to do something similar for multi-variate random variable, but you'll have to manually construct the Markov transition matrix, and solution times scale poorly, even in the two-dimensional case.

The next step is to call SDDP.MarkovianGraph with our simulator. This function will attempt to fit a Markov chain to the stochastic process produced by your simulator. There are two key arguments:

graph = SDDP.MarkovianGraph(simulator; budget = 8, scenarios = 30)
Root
  (0, 0.0)
 Nodes
- (1, 48.066115762203786)
+ (1, 52.41944346212964)
  (1, 59.6)
- (2, 47.21467215472091)
- (2, 67.68492807212756)
- (3, 38.38112693422999)
- (3, 41.0244342347352)
- (3, 59.344825356680126)
- (3, 69.3)
+ (2, 53.32095060479907)
+ (2, 66.35298664485829)
+ (3, 30.1)
+ (3, 40.195600564927126)
+ (3, 50.3333387062991)
+ (3, 68.66505708549907)
 Arcs
- (0, 0.0) => (1, 48.066115762203786) w.p. 0.6333333333333333
- (0, 0.0) => (1, 59.6) w.p. 0.36666666666666664
- (1, 48.066115762203786) => (2, 47.21467215472091) w.p. 0.8421052631578947
- (1, 48.066115762203786) => (2, 67.68492807212756) w.p. 0.15789473684210525
- (1, 59.6) => (2, 47.21467215472091) w.p. 0.2727272727272727
- (1, 59.6) => (2, 67.68492807212756) w.p. 0.7272727272727273
- (2, 47.21467215472091) => (3, 38.38112693422999) w.p. 0.47368421052631576
- (2, 47.21467215472091) => (3, 41.0244342347352) w.p. 0.2631578947368421
- (2, 47.21467215472091) => (3, 59.344825356680126) w.p. 0.2631578947368421
- (2, 47.21467215472091) => (3, 69.3) w.p. 0.0
- (2, 67.68492807212756) => (3, 38.38112693422999) w.p. 0.0
- (2, 67.68492807212756) => (3, 41.0244342347352) w.p. 0.09090909090909091
- (2, 67.68492807212756) => (3, 59.344825356680126) w.p. 0.5454545454545454
- (2, 67.68492807212756) => (3, 69.3) w.p. 0.36363636363636365

Here we can see we have created a MarkovianGraph with nodes like (2, 59.7). The first element of each node is the stage, and the second element is the inflow.

Create a SDDP.PolicyGraph using graph as follows:

model = SDDP.PolicyGraph(
+ (0, 0.0) => (1, 59.6) w.p. 0.26666666666666666
+ (0, 0.0) => (1, 52.41944346212964) w.p. 0.7333333333333333
+ (1, 52.41944346212964) => (2, 53.32095060479907) w.p. 0.9545454545454546
+ (1, 52.41944346212964) => (2, 66.35298664485829) w.p. 0.045454545454545456
+ (1, 59.6) => (2, 53.32095060479907) w.p. 0.875
+ (1, 59.6) => (2, 66.35298664485829) w.p. 0.125
+ (2, 53.32095060479907) => (3, 30.1) w.p. 0.14285714285714285
+ (2, 53.32095060479907) => (3, 40.195600564927126) w.p. 0.25
+ (2, 53.32095060479907) => (3, 50.3333387062991) w.p. 0.5
+ (2, 53.32095060479907) => (3, 68.66505708549907) w.p. 0.10714285714285714
+ (2, 66.35298664485829) => (3, 30.1) w.p. 0.0
+ (2, 66.35298664485829) => (3, 40.195600564927126) w.p. 0.0
+ (2, 66.35298664485829) => (3, 50.3333387062991) w.p. 0.0
+ (2, 66.35298664485829) => (3, 68.66505708549907) w.p. 1.0

Here we can see we have created a MarkovianGraph with nodes like (2, 59.7). The first element of each node is the stage, and the second element is the inflow.

Create a SDDP.PolicyGraph using graph as follows:

model = SDDP.PolicyGraph(
     graph;  # <--- New stuff
     sense = :Min,
     lower_bound = 0.0,
@@ -88,7 +88,7 @@
     # The new water balance constraint using the node:
     @constraint(sp, x.out == x.in - g_h - s + inflow)
 end
A policy graph with 8 nodes.
- Node indices: (1, 48.066115762203786), (1, 59.6), (2, 47.21467215472091), (2, 67.68492807212756), (3, 38.38112693422999), (3, 41.0244342347352), (3, 59.344825356680126), (3, 69.3)
+ Node indices: (1, 52.41944346212964), (1, 59.6), (2, 53.32095060479907), (2, 66.35298664485829), (3, 30.1), (3, 40.195600564927126), (3, 50.3333387062991), (3, 68.66505708549907)
 

When can this trick be used?

The Markov chain approach should be used when:

Vector auto-regressive models

The state-space expansion section assumed that the random variable was uni-variate. However, the approach naturally extends to vector auto-regressive models. For example, if inflow is a 2-dimensional vector, then we can model a vector auto-regressive model to it as follows:

\[inflow_{t} = A \times inflow_{t-1} + b + \varepsilon\]

Here A is a 2-by-2 matrix, and b and $\varepsilon$ are 2-by-1 vectors.

model = SDDP.LinearPolicyGraph(;
     stages = 3,
     sense = :Min,
@@ -128,4 +128,4 @@
     end
 end
A policy graph with 3 nodes.
  Node indices: 1, 2, 3
-
+ diff --git a/previews/PR811/tutorial/convex.cuts.json b/previews/PR811/tutorial/convex.cuts.json index b38bc9d70..32af2f098 100644 --- a/previews/PR811/tutorial/convex.cuts.json +++ b/previews/PR811/tutorial/convex.cuts.json @@ -1 +1 @@ -[{"risk_set_cuts":[],"node":"1","single_cuts":[{"state":{"x":0.674729216314269},"intercept":29021.348695582157,"coefficients":{"x":-317616.66568720294}},{"state":{"x":3.339783118244046},"intercept":18028.2953155917,"coefficients":{"x":-1583.3331337572254}},{"state":{"x":8.004837035485709},"intercept":30223.04776364777,"coefficients":{"x":-1504.166485178031}},{"state":{"x":7.669890949778228},"intercept":49128.33964351715,"coefficients":{"x":-1428.9581654292265}},{"state":{"x":7.33494488161516},"intercept":66897.83932797123,"coefficients":{"x":-1357.5102625343775}},{"state":{"x":5.236549100725652e-9},"intercept":316194.9516700634,"coefficients":{"x":-318046.5449208454}},{"state":{"x":1.0048451757364296},"intercept":138623.38099274563,"coefficients":{"x":-102094.61750004558}},{"state":{"x":0.669896785362958},"intercept":179903.65959814418,"coefficients":{"x":-318249.99974361644}},{"state":{"x":0.334948394578774},"intercept":310853.71500940755,"coefficients":{"x":-318250.0023112238}},{"state":{"x":5.006722804913794e-9},"intercept":435566.7414925364,"coefficients":{"x":-349629.96219836635}},{"state":{"x":0.0},"intercept":441303.38195601525,"coefficients":{"x":-349629.96221390896}},{"state":{"x":0.33494839375571595},"intercept":326118.65439018165,"coefficients":{"x":-318250.0023112231}},{"state":{"x":4.183663961328636e-9},"intercept":443119.9827526264,"coefficients":{"x":-349629.96221755573}},{"state":{"x":0.334948394578774},"intercept":326693.9115110879,"coefficients":{"x":-318250.00231159513}},{"state":{"x":5.00672280079552e-9},"intercept":443695.23984698835,"coefficients":{"x":-349629.96221792314}},{"state":{"x":5.0067228014731465e-9},"intercept":443877.40468466264,"coefficients":{"x":-349629.96221800195}},{"state":{"x":4.183663992145389e-9},"intercept":443935.09050435916,"coefficients":{"x":-349629.962218027}},{"state":{"x":0.3349483895720521},"intercept":326952.0305591943,"coefficients":{"x":-318250.00231159653}},{"state":{"x":0.0},"intercept":443953.3590522049,"coefficients":{"x":-349629.962218091}},{"state":{"x":0.33494839372530355},"intercept":326957.81381437415,"coefficients":{"x":-318250.0023115931}},{"state":{"x":4.153252381668108e-9},"intercept":443959.1421770553,"coefficients":{"x":-349629.96221809473}},{"state":{"x":0.33979356310774406},"intercept":325417.670441109,"coefficients":{"x":-318250.0009389167}},{"state":{"x":0.004845173538135633},"intercept":442266.9575708248,"coefficients":{"x":-349629.962217086}},{"state":{"x":2.6698967812507908},"intercept":90777.1354797575,"coefficients":{"x":-2013.211636401865}},{"state":{"x":5.334948390707172},"intercept":102181.99069890552,"coefficients":{"x":-1912.5510843886887}},{"state":{"x":1.285931900992525},"intercept":169320.1656560454,"coefficients":{"x":-102334.80816880228}},{"state":{"x":1.285931900992525},"intercept":169530.93786848136,"coefficients":{"x":-102362.49998576904}},{"state":{"x":1.2859321673514166},"intercept":169531.6306086448,"coefficients":{"x":-102362.49997567377}},{"state":{"x":0.5859322556357984},"intercept":269105.7543199941,"coefficients":{"x":-318250.00112716755}},{"state":{"x":1.285932166915499},"intercept":176505.17894641886,"coefficients":{"x":-102362.50027996152}},{"state":{"x":0.0},"intercept":479696.00475046603,"coefficients":{"x":-349714.79175859474}},{"state":{"x":0.0},"intercept":487333.1528312298,"coefficients":{"x":-349714.7917588191}},{"state":{"x":0.5859322556250226},"intercept":284842.4062976413,"coefficients":{"x":-349714.7915654303}},{"state":{"x":1.2859321669047237},"intercept":181514.28100734652,"coefficients":{"x":-112326.35060523174}},{"state":{"x":5.334948575821724},"intercept":117950.3510313089,"coefficients":{"x":-1844.6157142085976}},{"state":{"x":1.0936638590738732},"intercept":212887.64326292224,"coefficients":{"x":-112326.35063466082}},{"state":{"x":1.7936637709502257},"intercept":167750.1198287955,"coefficients":{"x":-37104.13939030896}},{"state":{"x":1.4286121701294463},"intercept":184928.7817676128,"coefficients":{"x":-47952.9885911171}},{"state":{"x":2.128612082005488},"intercept":158826.6348452969,"coefficients":{"x":-16768.44642651453}},{"state":{"x":1.7936636309236182},"intercept":174938.76436051435,"coefficients":{"x":-41830.0189883765}},{"state":{"x":1.7936636308629625},"intercept":174938.7643642067,"coefficients":{"x":-41830.01899636268}},{"state":{"x":1.7635606923371074},"intercept":176197.97085588114,"coefficients":{"x":-41830.01897059619}},{"state":{"x":2.463560604209196},"intercept":159219.35305040146,"coefficients":{"x":-19189.514045397897}},{"state":{"x":2.128612082005488},"intercept":166847.65644596057,"coefficients":{"x":-20272.852078617434}},{"state":{"x":1.7936636309236182},"intercept":176432.03393928125,"coefficients":{"x":-42939.74729877364}},{"state":{"x":1.7936636309236182},"intercept":176432.0339396597,"coefficients":{"x":-42939.74733611353}},{"state":{"x":1.793663630923618},"intercept":176432.03393965974,"coefficients":{"x":-42939.747336113534}},{"state":{"x":1.793663631009667},"intercept":176432.0339359648,"coefficients":{"x":-42939.747336113534}},{"state":{"x":1.30000008812383},"intercept":201297.95010614485,"coefficients":{"x":-118112.75349971278}},{"state":{"x":0.0},"intercept":505798.48696427216,"coefficients":{"x":-360145.7174676698}},{"state":{"x":0.3936638082372608},"intercept":378113.7449944699,"coefficients":{"x":-331214.25331750285}},{"state":{"x":1.093663719486565},"intercept":233912.44273942552,"coefficients":{"x":-112254.25002901703}},{"state":{"x":1.793663631362918},"intercept":183089.88212367104,"coefficients":{"x":-42916.91554427434}},{"state":{"x":1.0936637844262789},"intercept":233912.43544976943,"coefficients":{"x":-112254.25005269394}},{"state":{"x":1.7936636963026305},"intercept":183089.87934285967,"coefficients":{"x":-42916.91557155998}},{"state":{"x":3.004845439265756},"intercept":152404.54481284367,"coefficients":{"x":-13129.74944727836}},{"state":{"x":7.669896993373437},"intercept":129041.55395669381,"coefficients":{"x":-2167.461634163069}},{"state":{"x":7.3349484962527915},"intercept":144373.65449221391,"coefficients":{"x":-2059.088592645202}},{"state":{"x":5.899984775408838},"intercept":161018.69303019036,"coefficients":{"x":-1956.134226747091}},{"state":{"x":6.599985411412777},"intercept":172608.7151454897,"coefficients":{"x":-1872.218331766242}},{"state":{"x":4.299986014582269},"intercept":188991.64711943854,"coefficients":{"x":-2176.2023007832217}},{"state":{"x":1.9999868272779238},"intercept":210795.72800392396,"coefficients":{"x":-37186.30972563604}},{"state":{"x":2.6999867406668745},"intercept":209913.96138099313,"coefficients":{"x":-13414.79545927185}},{"state":{"x":1.3999866603721793},"intercept":238624.520175476,"coefficients":{"x":-110082.53190984738}},{"state":{"x":2.099986574005376},"intercept":222981.50518505287,"coefficients":{"x":-39796.61769499393}},{"state":{"x":2.799986487387522},"intercept":214571.8797537872,"coefficients":{"x":-17539.411494464384}},{"state":{"x":3.4999864069472917},"intercept":210260.88912983908,"coefficients":{"x":-7193.277740024596}},{"state":{"x":4.199987512906317},"intercept":211313.0285982329,"coefficients":{"x":-5505.742594860334}},{"state":{"x":6.899987609396673},"intercept":204121.559898164,"coefficients":{"x":-5230.455484074682}},{"state":{"x":7.599988201963328},"intercept":208360.79290901628,"coefficients":{"x":-4968.932722891469}},{"state":{"x":8.299988774166565},"intercept":212967.77332202956,"coefficients":{"x":-4720.486098525}},{"state":{"x":5.999988870657907},"intercept":231348.51573524316,"coefficients":{"x":-4484.461809866152}},{"state":{"x":3.6999895012148065},"intercept":248660.7367448546,"coefficients":{"x":-4260.238747593989}},{"state":{"x":6.399989597703045},"intercept":244729.2070278785,"coefficients":{"x":-4047.226821234833}},{"state":{"x":9.099990209554019},"intercept":241871.15094944104,"coefficients":{"x":-3844.865488026404}},{"state":{"x":6.7999910651360365},"intercept":258252.16214250366,"coefficients":{"x":-3652.622223889366}},{"state":{"x":7.499991661089564},"intercept":263282.39644366293,"coefficients":{"x":-3469.9911219952305}},{"state":{"x":10.19999223599982},"intercept":261872.96836150083,"coefficients":{"x":-3296.4915728649758}},{"state":{"x":7.899992184923234},"intercept":276906.58853378135,"coefficients":{"x":-3131.667002960133}},{"state":{"x":5.599992750208794},"intercept":291084.1369737693,"coefficients":{"x":-2975.083664728957}},{"state":{"x":6.299993403671319},"intercept":295927.30890419916,"coefficients":{"x":-2826.329499890771}},{"state":{"x":3.9999940198746695},"intercept":308630.46701546735,"coefficients":{"x":-2685.0130619887354}},{"state":{"x":6.699995492048317},"intercept":307586.65143536177,"coefficients":{"x":-2550.7624230136357}},{"state":{"x":7.399996091687653},"intercept":311739.0664647268,"coefficients":{"x":-2423.2243140690425}},{"state":{"x":5.099996669281772},"intercept":322630.43723675836,"coefficients":{"x":-2302.0631120878074}},{"state":{"x":5.7999973597176195},"intercept":326109.41771050805,"coefficients":{"x":-2186.9599676220173}},{"state":{"x":3.499997638227653},"intercept":335683.7353410472,"coefficients":{"x":-2077.612008548371}},{"state":{"x":4.19999874417788},"intercept":338581.1264066871,"coefficients":{"x":-1973.731420352024}},{"state":{"x":6.899998840668236},"intercept":337567.4176071008,"coefficients":{"x":-1875.0448669105012}},{"state":{"x":9.599999433234517},"intercept":336638.92060737987,"coefficients":{"x":-1781.2926316162216}},{"state":{"x":12.2999997580995},"intercept":335789.64984782925,"coefficients":{"x":-1692.2280054124074}},{"state":{"x":0.46096087584346396},"intercept":483556.61886703165,"coefficients":{"x":-318152.5388628973}},{"state":{"x":0.7959092992272729},"intercept":436409.7146424382,"coefficients":{"x":-102234.17630323643}},{"state":{"x":0.4609608762708987},"intercept":522650.29240251763,"coefficients":{"x":-318250.00000762835}},{"state":{"x":0.4609608762708986},"intercept":535044.182227266,"coefficients":{"x":-318250.0000076175}},{"state":{"x":0.4609608762708985},"intercept":538968.9140066036,"coefficients":{"x":-318250.00000873866}},{"state":{"x":0.4609608762708987},"intercept":540211.7457369929,"coefficients":{"x":-318250.00000887754}},{"state":{"x":0.4609608762708986},"intercept":540605.3091173717,"coefficients":{"x":-318250.00000833574}},{"state":{"x":0.46096089881251445},"intercept":540729.9303472076,"coefficients":{"x":-318250.0000083358}},{"state":{"x":0.0},"intercept":696993.6091511933,"coefficients":{"x":-349674.15582100867}},{"state":{"x":0.46096090741005813},"intercept":543797.6364105177,"coefficients":{"x":-318250.00000836817}},{"state":{"x":1.465806179128141},"intercept":387296.09705633647,"coefficients":{"x":-102265.03871846902}},{"state":{"x":1.1308577394622854},"intercept":421661.5119532637,"coefficients":{"x":-102362.50000462124}},{"state":{"x":0.7959092989173602},"intercept":457050.320362421,"coefficients":{"x":-112313.48269997138}},{"state":{"x":0.4609608759609864},"intercept":545002.3660142148,"coefficients":{"x":-349714.79143358645}},{"state":{"x":2.6698968765552875},"intercept":355958.46258291707,"coefficients":{"x":-2119.205631730213}},{"state":{"x":5.33494843909195},"intercept":353872.81726573466,"coefficients":{"x":-2013.2453816943305}},{"state":{"x":1.7220413082529082},"intercept":387217.6890842888,"coefficients":{"x":-34002.31949402582}},{"state":{"x":1.0220414017996187},"intercept":441609.426769977,"coefficients":{"x":-122147.94612017144}},{"state":{"x":1.7220413137674198},"intercept":390261.93565060437,"coefficients":{"x":-40267.710684838385}},{"state":{"x":1.72204131376742},"intercept":390261.93559721287,"coefficients":{"x":-40267.71065493021}},{"state":{"x":1.7220413080341843},"intercept":390261.93583041814,"coefficients":{"x":-40267.71062868403}},{"state":{"x":3.199989617993015},"intercept":362315.11902704765,"coefficients":{"x":-12354.928298977315}},{"state":{"x":3.8999902477579353},"intercept":362026.87990305794,"coefficients":{"x":-5499.921662826556}},{"state":{"x":6.599990877520847},"intercept":355272.3046933106,"coefficients":{"x":-2225.0554414416015}},{"state":{"x":7.299995474866699},"intercept":357143.5693604867,"coefficients":{"x":-2113.802727684274}},{"state":{"x":12.499999288463005},"intercept":349919.99622051633,"coefficients":{"x":-2008.112609076287}},{"state":{"x":13.199999398012107},"intercept":352127.58441162785,"coefficients":{"x":-1907.7069931684048}},{"state":{"x":13.89999959757423},"intercept":354084.2956318021,"coefficients":{"x":-1812.321661294266}},{"state":{"x":11.599999737450158},"intercept":360960.4282684454,"coefficients":{"x":-1721.7056011548239}},{"state":{"x":12.299999893057786},"intercept":362187.17063681135,"coefficients":{"x":-1635.6203387065711}},{"state":{"x":7.669896851580298},"intercept":371501.2562837557,"coefficients":{"x":-1553.83937396}},{"state":{"x":7.334948425795633},"intercept":373468.47906768514,"coefficients":{"x":-1476.1474691805408}},{"state":{"x":0.1763154699072086},"intercept":660768.9091683581,"coefficients":{"x":-330051.44175958727}},{"state":{"x":0.8763153811564967},"intercept":473950.1037844789,"coefficients":{"x":-106099.6232690733}},{"state":{"x":1.5763152929589668},"intercept":413682.48222102167,"coefficients":{"x":-35181.54712470029}},{"state":{"x":2.2763152065217653},"intercept":393878.4067184598,"coefficients":{"x":-12558.270105849298}},{"state":{"x":1.941366818636665},"intercept":402427.8328513403,"coefficients":{"x":-38208.332805679}},{"state":{"x":2.276315204238449},"intercept":395316.7966695349,"coefficients":{"x":-13682.63878709331}},{"state":{"x":1.94136681635335},"intercept":402541.41859246494,"coefficients":{"x":-38564.38285623251}},{"state":{"x":1.9112636918959405},"intercept":403702.3270131018,"coefficients":{"x":-38564.382886787185}},{"state":{"x":2.6112636054152816},"intercept":390779.83557841607,"coefficients":{"x":-13795.38786086989}},{"state":{"x":2.276315206531523},"intercept":395400.57864363375,"coefficients":{"x":-13795.387937953132}},{"state":{"x":1.9413668186464221},"intercept":402541.41849719366,"coefficients":{"x":-38564.38289871243}},{"state":{"x":1.2413669045339482},"intercept":439305.3407623938,"coefficients":{"x":-109518.16267030322}},{"state":{"x":1.9413668163331002},"intercept":403835.6561819555,"coefficients":{"x":-39646.92038060361}},{"state":{"x":1.9413668163331004},"intercept":403835.6561782292,"coefficients":{"x":-39646.92040830744}},{"state":{"x":1.9413668616958877},"intercept":403835.6543834463,"coefficients":{"x":-39646.92035241858}},{"state":{"x":1.2413669498967375},"intercept":439305.33580122376,"coefficients":{"x":-109518.16264172875}},{"state":{"x":1.9413668616958883},"intercept":403835.6543926543,"coefficients":{"x":-39646.9202877896}},{"state":{"x":1.2413669068375133},"intercept":439305.340516079,"coefficients":{"x":-109518.1625976455}},{"state":{"x":1.941366818636665},"intercept":403835.65610461286,"coefficients":{"x":-39646.920342238}},{"state":{"x":2.2763152065217653},"intercept":395935.5615387441,"coefficients":{"x":-14138.191580696766}},{"state":{"x":1.941366818636665},"intercept":403893.4565678668,"coefficients":{"x":-39791.17867134088}},{"state":{"x":2.2763152042182018},"intercept":395974.7435123235,"coefficients":{"x":-14183.873386893174}},{"state":{"x":1.941366816333101},"intercept":403893.4566614089,"coefficients":{"x":-39791.178785163975}},{"state":{"x":1.9413668681053085},"intercept":403893.4546007704,"coefficients":{"x":-39791.17871827775}},{"state":{"x":3.0048452044782517},"intercept":387585.6542888775,"coefficients":{"x":-6074.893292632419}},{"state":{"x":7.669896803337161},"intercept":374479.76638210303,"coefficients":{"x":-1568.2268155359052}},{"state":{"x":7.334948401649754},"intercept":376555.97292324645,"coefficients":{"x":-1626.5437221508282}}],"multi_cuts":[]}] \ No newline at end of file +[{"risk_set_cuts":[],"node":"1","single_cuts":[{"state":{"x":0.3349461006592544},"intercept":136942.1292824911,"coefficients":{"x":-317616.66663406935}},{"state":{"x":0.0},"intercept":321380.8754720096,"coefficients":{"x":-318249.99997748446}},{"state":{"x":0.0},"intercept":346483.98067931633,"coefficients":{"x":-318250.0000028512}},{"state":{"x":0.0},"intercept":354558.18839951465,"coefficients":{"x":-318250.0000165849}},{"state":{"x":0.0},"intercept":357155.19103184337,"coefficients":{"x":-318250.00002266077}},{"state":{"x":0.0},"intercept":357990.4956098225,"coefficients":{"x":-318250.0000249221}},{"state":{"x":0.3349461006592544},"intercept":251662.56793549343,"coefficients":{"x":-318249.99996930273}},{"state":{"x":0.0},"intercept":358345.5796008263,"coefficients":{"x":-318250.0000259382}},{"state":{"x":0.6698921986092845},"intercept":145180.18211190167,"coefficients":{"x":-318249.9996490429}},{"state":{"x":0.3349461006592544},"intercept":251785.71765585398,"coefficients":{"x":-318249.9999694142}},{"state":{"x":0.0},"intercept":358385.1896974615,"coefficients":{"x":-318250.00002605375}},{"state":{"x":0.0},"intercept":358386.11458359665,"coefficients":{"x":-318250.0000260564}},{"state":{"x":0.0},"intercept":358386.41206562973,"coefficients":{"x":-318250.0000260573}},{"state":{"x":0.0},"intercept":358386.50774828374,"coefficients":{"x":-318250.0000260576}},{"state":{"x":0.0},"intercept":358386.5385238239,"coefficients":{"x":-318250.00002605765}},{"state":{"x":0.0},"intercept":358386.54842252383,"coefficients":{"x":-318250.0000260577}},{"state":{"x":0.3349461006592544},"intercept":251789.95507151555,"coefficients":{"x":-318249.99996941804}},{"state":{"x":0.0},"intercept":358386.55262742494,"coefficients":{"x":-318250.0000260577}},{"state":{"x":0.0},"intercept":358386.55295883084,"coefficients":{"x":-318250.0000260577}},{"state":{"x":0.0},"intercept":358386.55306542525,"coefficients":{"x":-318250.0000260577}},{"state":{"x":0.0},"intercept":358386.5530997103,"coefficients":{"x":-318250.0000260577}},{"state":{"x":0.6698921986092845},"intercept":145193.36090146867,"coefficients":{"x":-318249.99964914017}},{"state":{"x":0.3349461006592544},"intercept":251789.95659979622,"coefficients":{"x":-318249.99996875366}},{"state":{"x":0.0},"intercept":358386.5531189161,"coefficients":{"x":-318250.0000260577}},{"state":{"x":0.6698921986092845},"intercept":145193.36092999516,"coefficients":{"x":-318249.99963676813}},{"state":{"x":0.3349461006592544},"intercept":251789.95659055997,"coefficients":{"x":-318249.99998185696}},{"state":{"x":0.0},"intercept":358386.5531257224,"coefficients":{"x":-318250.0000324919}},{"state":{"x":0.3349461006592544},"intercept":251789.95663582522,"coefficients":{"x":-318249.99996716034}},{"state":{"x":0.0},"intercept":358386.5531303416,"coefficients":{"x":-318250.0000260577}},{"state":{"x":0.6698921986092845},"intercept":145193.3609375475,"coefficients":{"x":-318249.99963676813}},{"state":{"x":0.3349461006592544},"intercept":251789.9566352705,"coefficients":{"x":-318249.999968001}},{"state":{"x":0.0},"intercept":358386.5531538555,"coefficients":{"x":-318250.00002568756}},{"state":{"x":0.0},"intercept":358386.5531766487,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.0},"intercept":358386.5531790936,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.0},"intercept":358386.55317935586,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.0},"intercept":358386.55317938403,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.0},"intercept":358386.55317938706,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.0},"intercept":358386.5531793876,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.0},"intercept":358386.5531793876,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.3349461006592544},"intercept":251789.95664430724,"coefficients":{"x":-318249.999968001}},{"state":{"x":0.0},"intercept":358386.5531583228,"coefficients":{"x":-318250.00002568756}},{"state":{"x":0.0},"intercept":358386.55318236543,"coefficients":{"x":-318250.0000252671}},{"state":{"x":0.0},"intercept":358386.55315880204,"coefficients":{"x":-318250.00002568756}},{"state":{"x":0.0},"intercept":358386.5531826847,"coefficients":{"x":-318250.0000252671}},{"state":{"x":2.6698924476020394},"intercept":19658.979234376697,"coefficients":{"x":-1583.3333438552538}},{"state":{"x":7.33494488161516},"intercept":31772.19925219899,"coefficients":{"x":-1504.1666966973937}},{"state":{"x":1.6662205682966815},"intercept":62819.90104031612,"coefficients":{"x":-102205.48518514885}},{"state":{"x":1.3312721635563878},"intercept":101030.99219393416,"coefficients":{"x":-33948.40391561198}},{"state":{"x":0.9963237692103882},"intercept":141351.6242514023,"coefficients":{"x":-112162.82795046843}},{"state":{"x":0.2963238008595775},"intercept":307201.4727537404,"coefficients":{"x":-328366.9945951471}},{"state":{"x":0.9963237121393074},"intercept":155006.28755286417,"coefficients":{"x":-115366.54293844668}},{"state":{"x":0.9963237121393073},"intercept":155006.2875527982,"coefficients":{"x":-115366.54293611186}},{"state":{"x":0.9963237126815496},"intercept":155006.28749472921,"coefficients":{"x":-115366.54290282917}},{"state":{"x":0.2963238008595775},"intercept":321805.4666843404,"coefficients":{"x":-328366.99475617165}},{"state":{"x":0.9963237121393074},"intercept":159630.88563548762,"coefficients":{"x":-115366.54297347793}},{"state":{"x":0.9963237121393071},"intercept":159630.8856354809,"coefficients":{"x":-115366.54297316419}},{"state":{"x":0.9963237692103869},"intercept":159630.87905120305,"coefficients":{"x":-115366.54296340926}},{"state":{"x":0.29632385690842733},"intercept":326430.0463735921,"coefficients":{"x":-328366.995699183}},{"state":{"x":0.9963237681881565},"intercept":161095.3352320355,"coefficients":{"x":-115366.54325624784}},{"state":{"x":5.334948405275394},"intercept":53630.95094409666,"coefficients":{"x":-2059.65276430356}},{"state":{"x":2.559098836645133},"intercept":85310.43043539891,"coefficients":{"x":-12352.55131388784}},{"state":{"x":4.8590982934410105},"intercept":76813.92019771648,"coefficients":{"x":-5513.864624582748}},{"state":{"x":2.55909883615434},"intercept":102695.36566912093,"coefficients":{"x":-7403.755466311508}},{"state":{"x":1.8590989225805339},"intercept":126299.79077003789,"coefficients":{"x":-41221.7838387114}},{"state":{"x":2.559098836649224},"intercept":117945.49589654182,"coefficients":{"x":-17742.610022689893}},{"state":{"x":3.699998118394972},"intercept":107473.05090243719,"coefficients":{"x":-10307.538327023312}},{"state":{"x":4.399998742331552},"intercept":105290.50546681153,"coefficients":{"x":-9792.16143697754}},{"state":{"x":5.099999306794971},"intercept":104359.5069781802,"coefficients":{"x":-9302.553384526922}},{"state":{"x":5.799999841015147},"intercept":104560.35683475134,"coefficients":{"x":-8837.425726711628}},{"state":{"x":8.500000029477393},"intercept":88991.09147073675,"coefficients":{"x":-8395.55444699993}},{"state":{"x":6.199999976056536},"intercept":115898.21181202834,"coefficients":{"x":-7975.776735391045}},{"state":{"x":8.899999922809451},"intercept":103309.17743860988,"coefficients":{"x":-7576.987905587949}},{"state":{"x":9.59999986923584},"intercept":107387.5525030547,"coefficients":{"x":-7198.138514458278}},{"state":{"x":10.300000162875191},"intercept":112101.78926970427,"coefficients":{"x":-6838.231592732858}},{"state":{"x":13.000000526583019},"intercept":104385.46752392295,"coefficients":{"x":-6496.3200160703755}},{"state":{"x":10.700000474120836},"intercept":129320.02064780761,"coefficients":{"x":-6171.504019439492}},{"state":{"x":13.400000421528153},"intercept":123487.4852373182,"coefficients":{"x":-5862.928821762568}},{"state":{"x":11.100000369009722},"intercept":147065.7897414143,"coefficients":{"x":-5569.7823848877615}},{"state":{"x":13.80000031683253},"intercept":142823.05329038878,"coefficients":{"x":-5291.293269066212}},{"state":{"x":11.500000264174101},"intercept":165072.54356224104,"coefficients":{"x":-5026.728609792624}},{"state":{"x":14.200000212140768},"intercept":162165.04081255652,"coefficients":{"x":-4775.392182754453}},{"state":{"x":11.900000159280014},"intercept":183120.6943723047,"coefficients":{"x":-4536.622577720531}},{"state":{"x":14.600000107186487},"intercept":181328.387264861,"coefficients":{"x":-4309.791452259844}},{"state":{"x":12.300000054389693},"intercept":201030.9930549059,"coefficients":{"x":-4094.3018836513515}},{"state":{"x":34.40000073437894},"intercept":124706.07132262652,"coefficients":{"x":-3889.586790808601}},{"state":{"x":30.100000693537325},"intercept":154363.87816337103,"coefficients":{"x":-3695.107452999475}},{"state":{"x":30.800000652693278},"intercept":164494.35327990665,"coefficients":{"x":-3510.352082083248}},{"state":{"x":31.500000611854414},"intercept":174527.84572083392,"coefficients":{"x":-3334.8344797058144}},{"state":{"x":27.20000057101563},"intercept":200289.19134418547,"coefficients":{"x":-3168.092757726771}},{"state":{"x":25.90000053021359},"intercept":215310.99296844786,"coefficients":{"x":-3009.688121937851}},{"state":{"x":24.60000048941355},"intercept":229631.86598118447,"coefficients":{"x":-2859.203717964431}},{"state":{"x":20.30000044857687},"intercept":251165.56641232653,"coefficients":{"x":-2716.2435348862846}},{"state":{"x":19.000000407775016},"intercept":263247.4976050964,"coefficients":{"x":-2580.4313611264524}},{"state":{"x":19.70000036698319},"intercept":269607.47671313887,"coefficients":{"x":-2451.409795938218}},{"state":{"x":18.400000326189726},"intercept":280347.99230949715,"coefficients":{"x":-2328.8393091837333}},{"state":{"x":19.10000028539936},"intercept":285932.61750228977,"coefficients":{"x":-2212.39734664269}},{"state":{"x":14.800000244607293},"intercept":301783.7721228548,"coefficients":{"x":-2101.7774830209337}},{"state":{"x":10.500000203824586},"intercept":316351.95428382873,"coefficients":{"x":-1996.6886140081301}},{"state":{"x":11.20000016305738},"intercept":320235.3806539682,"coefficients":{"x":-1896.8541855075632}},{"state":{"x":9.900000122287773},"intercept":327373.9021590422,"coefficients":{"x":-1802.011484297264}},{"state":{"x":10.600000081525016},"intercept":330404.4558960324,"coefficients":{"x":-1711.9109167911224}},{"state":{"x":9.300000040757185},"intercept":336396.4448886099,"coefficients":{"x":-1626.315378755718}},{"state":{"x":2.6698968480868346},"intercept":350395.86900853785,"coefficients":{"x":-2098.3331212311623}},{"state":{"x":7.334948424225662},"intercept":344651.76826596505,"coefficients":{"x":-1962.277725246773}},{"state":{"x":0.6698973934711014},"intercept":391574.0172035411,"coefficients":{"x":-318238.05431921425}},{"state":{"x":0.33494903068284704},"intercept":555684.2676846669,"coefficients":{"x":-318249.99990080995}},{"state":{"x":0.0},"intercept":680558.6845530192,"coefficients":{"x":-318250.00000606006}},{"state":{"x":0.1981835770069176},"intercept":623294.1216944011,"coefficients":{"x":-318249.99997894274}},{"state":{"x":0.19818357448766016},"intercept":625139.3729406762,"coefficients":{"x":-318249.9999917996}},{"state":{"x":0.6698973934711014},"intercept":475602.76622959704,"coefficients":{"x":-318249.99950941437}},{"state":{"x":0.33494903068284704},"intercept":582386.3806801566,"coefficients":{"x":-318249.99996357755}},{"state":{"x":0.0},"intercept":689043.1047613845,"coefficients":{"x":-318249.99997911754}},{"state":{"x":0.19818357700691785},"intercept":625989.9901856347,"coefficients":{"x":-318249.9999923138}},{"state":{"x":0.19818357576718854},"intercept":625995.9669538655,"coefficients":{"x":-318249.99999231746}},{"state":{"x":0.0},"intercept":689069.7889338494,"coefficients":{"x":-318249.9999791891}},{"state":{"x":0.5331319373200144},"intercept":519401.15326574125,"coefficients":{"x":-318249.9999064534}},{"state":{"x":0.19818357700692052},"intercept":625998.6606108254,"coefficients":{"x":-318249.99999231903}},{"state":{"x":0.19818421757912225},"intercept":625998.5176675953,"coefficients":{"x":-318249.999992319}},{"state":{"x":3.0048468739085186},"intercept":356718.3834239737,"coefficients":{"x":-2204.7212378000886}},{"state":{"x":5.669897826287177},"intercept":354408.02294058946,"coefficients":{"x":-2094.485184889433}},{"state":{"x":10.334948991220955},"intercept":348474.3547854357,"coefficients":{"x":-1989.7609299405035}},{"state":{"x":0.31192691451378385},"intercept":596100.7700535427,"coefficients":{"x":-318249.99991371843}},{"state":{"x":1.011926825793519},"intercept":442669.6559923584,"coefficients":{"x":-102359.25766086402}},{"state":{"x":1.3468776413294974},"intercept":408619.3406333414,"coefficients":{"x":-102362.49970365928}},{"state":{"x":1.0119268270281114},"intercept":442906.4955433633,"coefficients":{"x":-102362.49998976279}},{"state":{"x":0.3119269152176095},"intercept":603248.7738341913,"coefficients":{"x":-349714.7916110776}},{"state":{"x":1.011926826497345},"intercept":445170.0326182718,"coefficients":{"x":-112326.35066052907}},{"state":{"x":1.0119268257935192},"intercept":445170.0327256123,"coefficients":{"x":-112326.35065825064}},{"state":{"x":1.3468776407800678},"intercept":407566.2262462233,"coefficients":{"x":-37153.374109998615}},{"state":{"x":1.0119268264786825},"intercept":447649.65908483416,"coefficients":{"x":-123141.58576255105}},{"state":{"x":2.6866768734793953},"intercept":373269.08085496735,"coefficients":{"x":-13345.326132663053}},{"state":{"x":2.351728544672368},"intercept":378065.3157797626,"coefficients":{"x":-13348.568579378523}},{"state":{"x":2.0167792685529506},"intercept":384292.59912361036,"coefficients":{"x":-37275.171609223886}},{"state":{"x":1.681828454330855},"intercept":398477.9980320368,"coefficients":{"x":-43855.21551451213}},{"state":{"x":1.3468776400949034},"intercept":413167.3382175225,"coefficients":{"x":-43855.21590626746}},{"state":{"x":1.0119268257935186},"intercept":449911.3973873253,"coefficients":{"x":-115920.06408263385}},{"state":{"x":1.3468776406484302},"intercept":413167.3381922739,"coefficients":{"x":-43855.215760470935}},{"state":{"x":1.0119268263470458},"intercept":449911.39732255775,"coefficients":{"x":-115920.06407715993}},{"state":{"x":0.0},"intercept":719091.5086735892,"coefficients":{"x":-354324.68543592584}},{"state":{"x":0.3119269150921447},"intercept":617416.2379859467,"coefficients":{"x":-331504.1516707148}},{"state":{"x":1.011926826371881},"intercept":454397.7609554409,"coefficients":{"x":-110153.36145339496}},{"state":{"x":2.0167792692567774},"intercept":387179.39626993716,"coefficients":{"x":-39742.27767797587}},{"state":{"x":1.6818284550346816},"intercept":400491.1045626552,"coefficients":{"x":-39742.27785945511}},{"state":{"x":1.3468776407987297},"intercept":417529.82323507464,"coefficients":{"x":-109836.69463666106}},{"state":{"x":1.011926826497345},"intercept":454397.76094243606,"coefficients":{"x":-110153.36148765493}},{"state":{"x":1.0119268270281114},"intercept":454397.76088397036,"coefficients":{"x":-110153.36148765491}},{"state":{"x":0.31192691521761085},"intercept":618510.4487988751,"coefficients":{"x":-330201.72134197084}},{"state":{"x":1.0119268264973464},"intercept":454744.261046483,"coefficients":{"x":-109740.9252181228}},{"state":{"x":1.0119276280115392},"intercept":454744.17308743735,"coefficients":{"x":-109740.9252267822}},{"state":{"x":0.3119269157483759},"intercept":618728.2987497336,"coefficients":{"x":-330201.72134442563}},{"state":{"x":1.0119268270281114},"intercept":454813.24686150847,"coefficients":{"x":-109740.92521910439}},{"state":{"x":0.3119269152176095},"intercept":618797.2847978052,"coefficients":{"x":-330201.72130497353}},{"state":{"x":1.011926826497345},"intercept":454835.09244600777,"coefficients":{"x":-109740.92521521286}},{"state":{"x":1.011926826497345},"intercept":454835.09244600765,"coefficients":{"x":-109740.92521521158}},{"state":{"x":1.0119268270281114},"intercept":454835.0923878991,"coefficients":{"x":-109740.92520665219}},{"state":{"x":0.31192934090660385},"intercept":618818.3293536174,"coefficients":{"x":-330201.721305035}},{"state":{"x":1.01192925218634},"intercept":454841.74399744277,"coefficients":{"x":-109740.9252152389}},{"state":{"x":0.6468777295190384},"intercept":508224.7126384296,"coefficients":{"x":-330201.7211171793}},{"state":{"x":1.3468776407987297},"intercept":418114.40897801705,"coefficients":{"x":-109424.25831586501}},{"state":{"x":1.011926826497345},"intercept":454844.2007967892,"coefficients":{"x":-109740.9251472647}},{"state":{"x":1.011926826497345},"intercept":454844.2007967893,"coefficients":{"x":-109740.92514726457}},{"state":{"x":1.011926826497345},"intercept":454844.2007967892,"coefficients":{"x":-109740.92514726457}},{"state":{"x":1.0119268270281114},"intercept":454844.2007386836,"coefficients":{"x":-109740.9251386669}},{"state":{"x":0.31192934090660335},"intercept":618827.4376864128,"coefficients":{"x":-330201.72134510585}},{"state":{"x":1.0119292521863397},"intercept":454844.6283029665,"coefficients":{"x":-109740.92521943928}},{"state":{"x":0.6468777295190395},"intercept":508227.5969477678,"coefficients":{"x":-330201.7211318887}},{"state":{"x":1.3468776407987313},"intercept":418115.32234179927,"coefficients":{"x":-109424.25820437164}},{"state":{"x":1.0119268264973462},"intercept":454845.11416297324,"coefficients":{"x":-109740.9251519246}},{"state":{"x":1.0119276899660667},"intercept":454845.019405117,"coefficients":{"x":-109740.92515192331}},{"state":{"x":4.6795867588691005},"intercept":363270.7426389699,"coefficients":{"x":-2213.424348924656}},{"state":{"x":4.344638413969858},"intercept":367313.82569244073,"coefficients":{"x":-2351.8354883297984}},{"state":{"x":4.00969007068063},"intercept":371182.2771285706,"coefficients":{"x":-2439.495871757911}},{"state":{"x":3.6747417314776873},"intercept":374879.2489885295,"coefficients":{"x":-2495.0141289563085}},{"state":{"x":3.33979338845989},"intercept":378393.0343210399,"coefficients":{"x":-2530.175693251031}},{"state":{"x":8.004845055065195},"intercept":369480.98730993445,"coefficients":{"x":-2403.666934245616}},{"state":{"x":7.669896703020875},"intercept":372948.55482054903,"coefficients":{"x":-2283.4836155914613}},{"state":{"x":10.334948353176532},"intercept":369654.70935203275,"coefficients":{"x":-2169.309452530926}},{"state":{"x":5.599999056712626},"intercept":382025.0989468521,"coefficients":{"x":-2060.8440305381428}},{"state":{"x":3.2999991711784933},"intercept":388887.88724111114,"coefficients":{"x":-2255.2012845027284}},{"state":{"x":5.99999917770125},"intercept":384783.95384159766,"coefficients":{"x":-2142.4412583100293}},{"state":{"x":6.699999290538212},"intercept":385205.8067007416,"coefficients":{"x":-2035.3192232001647}},{"state":{"x":9.399999401136597},"intercept":381773.38235746295,"coefficients":{"x":-1933.5532761538298}},{"state":{"x":12.099999460156598},"intercept":378614.11784971156,"coefficients":{"x":-1836.8756249066619}},{"state":{"x":12.799999507804577},"intercept":379136.70468450605,"coefficients":{"x":-1745.0318575102729}},{"state":{"x":10.499999602245563},"intercept":384464.1329057676,"coefficients":{"x":-1657.7802838009122}},{"state":{"x":8.19999968429602},"intercept":389141.2712728858,"coefficients":{"x":-1574.891301715074}},{"state":{"x":10.899999776839316},"intercept":385739.09653677035,"coefficients":{"x":-1496.1467542614073}},{"state":{"x":11.599999859004619},"intercept":385377.25956181285,"coefficients":{"x":-1421.3394324223734}},{"state":{"x":9.299999940723906},"intercept":388968.3705747114,"coefficients":{"x":-1350.2724911753076}},{"state":{"x":5.339793545747089},"intercept":394542.55407191935,"coefficients":{"x":-1511.0105455484008}},{"state":{"x":5.004845160081884},"intercept":395458.72831529373,"coefficients":{"x":-1590.30672212257}},{"state":{"x":7.6698967776659135},"intercept":391797.389083334,"coefficients":{"x":-1434.7806733186144}},{"state":{"x":10.33494838937286},"intercept":388359.06487842416,"coefficients":{"x":-1363.0416633708128}},{"state":{"x":0.0},"intercept":734922.1430060425,"coefficients":{"x":-351951.0153137165}},{"state":{"x":0.27521720668618066},"intercept":645878.6356444366,"coefficients":{"x":-329885.05453321803}},{"state":{"x":0.9752171179536436},"intercept":480895.16860086634,"coefficients":{"x":-106046.93389654302}},{"state":{"x":1.6752170298507165},"intercept":427610.7760442344,"coefficients":{"x":-35035.126227663925}},{"state":{"x":1.6752170298004245},"intercept":428004.72306987084,"coefficients":{"x":-35164.86238470423}},{"state":{"x":0.9752171614763746},"intercept":483518.57908221264,"coefficients":{"x":-116232.47358294684}},{"state":{"x":1.6752170733734457},"intercept":428840.44203200773,"coefficients":{"x":-38390.283250302135}},{"state":{"x":5.004845170529627},"intercept":396246.2099585703,"coefficients":{"x":-2014.9630926257928}},{"state":{"x":7.669896777739427},"intercept":392810.2496233158,"coefficients":{"x":-1703.0348687860637}},{"state":{"x":7.334948389382957},"intercept":394089.9846113733,"coefficients":{"x":-1617.8832084903934}}],"multi_cuts":[]}] \ No newline at end of file diff --git a/previews/PR811/tutorial/decision_hazard/index.html b/previews/PR811/tutorial/decision_hazard/index.html index 1f3b1f93d..652e5b019 100644 --- a/previews/PR811/tutorial/decision_hazard/index.html +++ b/previews/PR811/tutorial/decision_hazard/index.html @@ -74,4 +74,4 @@ end end -train_and_compute_cost(decision_hazard_2)
Cost = $410.0

Now we find that the cost of choosing the thermal generation before observing the inflow adds a much more reasonable cost of $10.

Summary

To summarize, the difference between here-and-now and wait-and-see variables is a modeling choice.

To create a here-and-now decision, add it as a state variable to the previous stage

In some cases, you'll need to add an additional "first-stage" problem to enable the model to choose an optimal value for the here-and-now decision variable. You do not need to do this if the first stage is deterministic. You must make sure that the subproblem is feasible for all possible incoming values of the here-and-now decision variable.

+train_and_compute_cost(decision_hazard_2)
Cost = $410.0

Now we find that the cost of choosing the thermal generation before observing the inflow adds a much more reasonable cost of $10.

Summary

To summarize, the difference between here-and-now and wait-and-see variables is a modeling choice.

To create a here-and-now decision, add it as a state variable to the previous stage

In some cases, you'll need to add an additional "first-stage" problem to enable the model to choose an optimal value for the here-and-now decision variable. You do not need to do this if the first stage is deterministic. You must make sure that the subproblem is feasible for all possible incoming values of the here-and-now decision variable.

diff --git a/previews/PR811/tutorial/example_milk_producer/9d2ee323.svg b/previews/PR811/tutorial/example_milk_producer/9d2ee323.svg deleted file mode 100644 index 4a91f7a92..000000000 --- a/previews/PR811/tutorial/example_milk_producer/9d2ee323.svg +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR811/tutorial/example_milk_producer/bc65f40c.svg b/previews/PR811/tutorial/example_milk_producer/bc65f40c.svg new file mode 100644 index 000000000..717239891 --- /dev/null +++ b/previews/PR811/tutorial/example_milk_producer/bc65f40c.svg @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_milk_producer/ca87dee4.svg b/previews/PR811/tutorial/example_milk_producer/ca87dee4.svg deleted file mode 100644 index bc9cfd025..000000000 --- a/previews/PR811/tutorial/example_milk_producer/ca87dee4.svg +++ /dev/null @@ -1,544 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR811/tutorial/example_milk_producer/edacd57b.svg b/previews/PR811/tutorial/example_milk_producer/edacd57b.svg new file mode 100644 index 000000000..d1e1bab0b --- /dev/null +++ b/previews/PR811/tutorial/example_milk_producer/edacd57b.svg @@ -0,0 +1,625 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_milk_producer/f2d4d145.svg b/previews/PR811/tutorial/example_milk_producer/f2d4d145.svg new file mode 100644 index 000000000..57056bf6d --- /dev/null +++ b/previews/PR811/tutorial/example_milk_producer/f2d4d145.svg @@ -0,0 +1,544 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_milk_producer/f35ffeba.svg b/previews/PR811/tutorial/example_milk_producer/f35ffeba.svg deleted file mode 100644 index 456e6cd40..000000000 --- a/previews/PR811/tutorial/example_milk_producer/f35ffeba.svg +++ /dev/null @@ -1,625 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR811/tutorial/example_milk_producer/index.html b/previews/PR811/tutorial/example_milk_producer/index.html index 93df985c4..56a6ab800 100644 --- a/previews/PR811/tutorial/example_milk_producer/index.html +++ b/previews/PR811/tutorial/example_milk_producer/index.html @@ -18,18 +18,18 @@ end simulator()
12-element Vector{Float64}:
- 4.952346478882604
- 5.5314854651592595
- 5.7248797929756
- 5.625267194479447
- 5.282465815712926
- 4.976174000407448
- 5.022944070757975
- 5.16964174958043
- 5.427351142670469
- 6.205689977919373
- 6.010339598616227
- 5.4324768045232705

It may be helpful to visualize a number of simulations of the price process:

plot = Plots.plot(
+ 4.656953599739544
+ 4.914703365312209
+ 5.234167481529229
+ 5.432152073395316
+ 5.832271749380082
+ 5.666231361319928
+ 5.238242260642144
+ 5.116520761529232
+ 4.827549115102208
+ 5.213805113595358
+ 4.6150948204498174
+ 5.319896065772506

It may be helpful to visualize a number of simulations of the price process:

plot = Plots.plot(
     [simulator() for _ in 1:500];
     color = "gray",
     opacity = 0.2,
@@ -38,7 +38,7 @@
     ylabel = "Price [\$/kg]",
     xlims = (1, 12),
     ylims = (3, 9),
-)
Example block output

The prices gradually revert to the mean of $6/kg, and there is high volatility.

We can't incorporate this price process directly into SDDP.jl, but we can fit a SDDP.MarkovianGraph directly from the simulator:

graph = SDDP.MarkovianGraph(simulator; budget = 30, scenarios = 10_000);

Here budget is the number of nodes in the policy graph, and scenarios is the number of simulations to use when estimating the transition probabilities.

The graph contains too many nodes to be show, but we can plot it:

for ((t, price), edges) in graph.nodes
+)
Example block output

The prices gradually revert to the mean of $6/kg, and there is high volatility.

We can't incorporate this price process directly into SDDP.jl, but we can fit a SDDP.MarkovianGraph directly from the simulator:

graph = SDDP.MarkovianGraph(simulator; budget = 30, scenarios = 10_000);

Here budget is the number of nodes in the policy graph, and scenarios is the number of simulations to use when estimating the transition probabilities.

The graph contains too many nodes to be show, but we can plot it:

for ((t, price), edges) in graph.nodes
     for ((t′, price′), probability) in edges
         Plots.plot!(
             plot,
@@ -50,7 +50,7 @@
     end
 end
 
-plot
Example block output

That looks okay. Try changing budget and scenarios to see how different Markovian policy graphs can be created.

Model

Now that we have a Markovian graph, we can build the model. See if you can work out how we arrived at this formulation by reading the background description. Do all the variables and constraints make sense?

model = SDDP.PolicyGraph(
+plot
Example block output

That looks okay. Try changing budget and scenarios to see how different Markovian policy graphs can be created.

Model

Now that we have a Markovian graph, we can build the model. See if you can work out how we arrived at this formulation by reading the background description. Do all the variables and constraints make sense?

model = SDDP.PolicyGraph(
     graph;
     sense = :Max,
     upper_bound = 1e2,
@@ -111,7 +111,7 @@
     end
     return
 end
A policy graph with 30 nodes.
- Node indices: (1, 4.586078944322009), ..., (12, 7.7995494444745965)
+ Node indices: (1, 4.5775596651941735), ..., (12, 7.618983408519292)
 

Training a policy

Now we have a model, we train a policy. The SDDP.SimulatorSamplingScheme is used in the forward pass. It generates an out-of-sample sequence of prices using simulator and traverses the closest sequence of nodes in the policy graph. When calling SDDP.parameterize for each subproblem, it uses the new out-of-sample price instead of the price associated with the Markov node.

SDDP.train(
     model;
     time_limit = 20,
@@ -123,7 +123,7 @@
 problem
   nodes           : 30
   state variables : 5
-  scenarios       : 9.84375e+11
+  scenarios       : 1.10547e+12
   existing cuts   : false
 options
   solver          : serial mode
@@ -142,31 +142,31 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1  -4.206878e+01  5.941262e+01  1.281221e+00       162   1
-        55   8.572786e+00  7.917480e+00  2.284350e+00      8910   1
-       101   7.981373e+00  7.897983e+00  3.300510e+00     16362   1
-       143   8.677458e+00  7.897777e+00  4.325968e+00     23166   1
-       179   8.493768e+00  7.897068e+00  5.335664e+00     28998   1
-       215   6.033131e+00  7.896217e+00  6.343685e+00     34830   1
-       249   3.130692e+00  7.895975e+00  7.348002e+00     40338   1
-       281   7.805216e+00  7.895890e+00  8.365414e+00     45522   1
-       311   9.433888e+00  7.895849e+00  9.384863e+00     50382   1
-       446   1.051951e+01  7.895307e+00  1.441280e+01     72252   1
-       562   7.960151e+00  7.895061e+00  1.943070e+01     91044   1
-       574   1.035700e+01  7.895061e+00  2.000098e+01     92988   1
+         1  -2.800297e+01  6.046266e+01  1.302636e+00       162   1
+        62   9.110901e+00  7.919372e+00  2.310957e+00     10044   1
+       112   9.587047e+00  7.892281e+00  3.313653e+00     18144   1
+       153   1.132638e+01  7.891248e+00  4.314246e+00     24786   1
+       193   9.701241e+00  7.890591e+00  5.341025e+00     31266   1
+       229   9.204296e+00  7.890388e+00  6.342482e+00     37098   1
+       263   7.930002e+00  7.889763e+00  7.344264e+00     42606   1
+       297   8.093624e+00  7.886211e+00  8.349875e+00     48114   1
+       330   8.667298e+00  7.886186e+00  9.363293e+00     53460   1
+       468   8.824978e+00  7.886167e+00  1.438189e+01     75816   1
+       590   7.919321e+00  7.885395e+00  1.938828e+01     95580   1
+       604   8.764670e+00  7.885338e+00  2.000715e+01     97848   1
 -------------------------------------------------------------------
 status         : time_limit
-total time (s) : 2.000098e+01
-total solves   : 92988
-best bound     :  7.895061e+00
-simulation ci  :  8.851335e+00 ± 3.582455e-01
+total time (s) : 2.000715e+01
+total solves   : 97848
+best bound     :  7.885338e+00
+simulation ci  :  8.894186e+00 ± 3.152135e-01
 numeric issues : 0
 -------------------------------------------------------------------
Warning

We're intentionally terminating the training early so that the documentation doesn't take too long to build. If you run this example locally, increase the time limit.

Simulating the policy

When simulating the policy, we can also use the SDDP.SimulatorSamplingScheme.

simulations = SDDP.simulate(
     model,
     200,
     Symbol[:x_stock, :u_forward_sell, :u_spot_sell, :u_spot_buy];
     sampling_scheme = SDDP.SimulatorSamplingScheme(simulator),
-);

To show how the sampling scheme uses the new out-of-sample price instead of the price associated with the Markov node, compare the index of the Markov state visited in stage 12 of the first simulation:

simulations[1][12][:node_index]
(12, 5.429381736143134)

to the realization of the noise (price, ω) passed to SDDP.parameterize:

simulations[1][12][:noise_term]
(5.474838515998973, 0.2)

Visualizing the policy

Finally, we can plot the policy to gain insight (although note that we terminated the training early, so we should run the re-train the policy for more iterations before making too many judgements).

plot = Plots.plot(
+);

To show how the sampling scheme uses the new out-of-sample price instead of the price associated with the Markov node, compare the index of the Markov state visited in stage 12 of the first simulation:

simulations[1][12][:node_index]
(12, 5.315538933690341)

to the realization of the noise (price, ω) passed to SDDP.parameterize:

simulations[1][12][:noise_term]
(5.263419005289087, 0.15)

Visualizing the policy

Finally, we can plot the policy to gain insight (although note that we terminated the training early, so we should run the re-train the policy for more iterations before making too many judgements).

plot = Plots.plot(
     SDDP.publication_plot(simulations; title = "x_stock.out") do data
         return data[:x_stock].out
     end,
@@ -180,4 +180,4 @@
         return data[:u_spot_sell]
     end;
     layout = (2, 2),
-)
Example block output

Next steps

+)Example block output

Next steps

diff --git a/previews/PR811/tutorial/example_newsvendor/15015e06.svg b/previews/PR811/tutorial/example_newsvendor/15015e06.svg deleted file mode 100644 index 7d41aca37..000000000 --- a/previews/PR811/tutorial/example_newsvendor/15015e06.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR811/tutorial/example_newsvendor/2e3bd7a2.svg b/previews/PR811/tutorial/example_newsvendor/2e3bd7a2.svg deleted file mode 100644 index 901f887d5..000000000 --- a/previews/PR811/tutorial/example_newsvendor/2e3bd7a2.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR811/tutorial/example_newsvendor/abf5cbed.svg b/previews/PR811/tutorial/example_newsvendor/abf5cbed.svg new file mode 100644 index 000000000..a9a615ed2 --- /dev/null +++ b/previews/PR811/tutorial/example_newsvendor/abf5cbed.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_newsvendor/c38e8548.svg b/previews/PR811/tutorial/example_newsvendor/c38e8548.svg new file mode 100644 index 000000000..66f15cd3e --- /dev/null +++ b/previews/PR811/tutorial/example_newsvendor/c38e8548.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_newsvendor/index.html b/previews/PR811/tutorial/example_newsvendor/index.html index ad06b2fc8..880d110ef 100644 --- a/previews/PR811/tutorial/example_newsvendor/index.html +++ b/previews/PR811/tutorial/example_newsvendor/index.html @@ -15,7 +15,7 @@ d = sort!(rand(D, N)); Ω = 1:N P = fill(1 / N, N); -StatsPlots.histogram(d; bins = 20, label = "", xlabel = "Demand")Example block output

Kelley's cutting plane algorithm

Kelley's cutting plane algorithm is an iterative method for maximizing concave functions. Given a concave function $f(x)$, Kelley's constructs an outer-approximation of the function at the minimum by a set of first-order Taylor series approximations (called cuts) constructed at a set of points $k = 1,\ldots,K$:

\[\begin{aligned} +StatsPlots.histogram(d; bins = 20, label = "", xlabel = "Demand")Example block output

Kelley's cutting plane algorithm

Kelley's cutting plane algorithm is an iterative method for maximizing concave functions. Given a concave function $f(x)$, Kelley's constructs an outer-approximation of the function at the minimum by a set of first-order Taylor series approximations (called cuts) constructed at a set of points $k = 1,\ldots,K$:

\[\begin{aligned} f^K = \max\limits_{\theta \in \mathbb{R}, x \in \mathbb{R}^N} \;\; & \theta\\ & \theta \le f(x_k) + \nabla f(x_k)^\top (x - x_k),\quad k=1,\ldots,K\\ & \theta \le M, @@ -168,55 +168,55 @@ println(" Added cut: $c") end

Solving iteration k = 1
   xᵏ = -0.0
-  V̅ = 1231.6734987634309
+  V̅ = 1214.775985522808
   V̲ = 0.0
   Added cut: -4.99999999999999 x_out + θ ≤ 0
 Solving iteration k = 2
-  xᵏ = 246.33469975268665
-  V̅ = 739.0040992580575
-  V̲ = 493.9996547962299
-  Added cut: 0.10000000000000007 x_out + θ ≤ 1011.3025242768714
+  xᵏ = 242.95519710456207
+  V̅ = 728.8655913136838
+  V̲ = 517.9437351666181
+  Added cut: 0.10000000000000007 x_out + θ ≤ 1028.1496490861982
 Solving iteration k = 3
-  xᵏ = 198.2946126033085
-  V̅ = 594.8838378099235
-  V̲ = 551.1615796630273
-  Added cut: -2.5009999999999994 x_out + θ ≤ 451.8159787487699
+  xᵏ = 201.59797040905886
+  V̅ = 604.7939112271746
+  V̲ = 561.9187898557478
+  Added cut: -2.399 x_out + θ ≤ 481.4811996625327
 Solving iteration k = 4
-  xᵏ = 215.10440043371847
-  V̅ = 559.5832833660628
-  V̲ = 545.9484330631037
-  Added cut: -1.0220000000000002 x_out + θ ≤ 756.3205366872812
+  xᵏ = 218.75488172215512
+  V̅ = 568.7643974696725
+  V̲ = 556.079522562153
+  Added cut: -1.0730000000000004 x_out + θ ≤ 758.8652979185914
 Solving iteration k = 5
-  xᵏ = 205.88543471163726
-  V̅ = 554.9645815393001
-  V̲ = 552.1752445110496
-  Added cut: -1.7360000000000009 x_out + θ ≤ 606.5289992749204
+  xᵏ = 209.18861105283472
+  V̅ = 564.9474554726139
+  V̲ = 562.037471869558
+  Added cut: -1.685000000000001 x_out + θ ≤ 627.9318843512015
 Solving iteration k = 6
-  xᵏ = 202.2392425178441
-  V̅ = 553.1378392502097
-  V̲ = 552.4725090106001
-  Added cut: -2.1950000000000007 x_out + θ ≤ 513.0358567196204
+  xᵏ = 205.1130037656428
+  V̅ = 563.321288165024
+  V̲ = 562.668403928687
+  Added cut: -2.042000000000001 x_out + θ ≤ 554.0536577705284
 Solving iteration k = 7
-  xᵏ = 203.68876373703705
-  V̅ = 552.7551656483428
-  V̲ = 552.5912867102036
-  Added cut: -1.9910000000000012 x_out + θ ≤ 554.4244855838382
+  xᵏ = 206.94181115034462
+  V̅ = 562.745213838843
+  V̲ = 562.5576341710762
+  Added cut: -1.787000000000001 x_out + θ ≤ 606.6362399460982
 Solving iteration k = 8
-  xᵏ = 202.88543560891077
-  V̅ = 552.598516663358
-  V̲ = 552.5476268627128
-  Added cut: -2.093000000000001 x_out + θ ≤ 533.679281351082
+  xᵏ = 206.2062046100767
+  V̅ = 562.7143183641517
+  V̲ = 562.6540609403166
+  Added cut: -1.940000000000001 x_out + θ ≤ 575.0264332169193
 Solving iteration k = 9
-  xᵏ = 203.3843552230947
-  V̅ = 552.5940263868306
-  V̲ = 552.5803243598313
-  Added cut: -2.042000000000001 x_out + θ ≤ 544.0381814404606
+  xᵏ = 205.6154455528556
+  V̅ = 562.6895064837486
+  V̲ = 562.6861283366654
+  Added cut: -1.9910000000000012 x_out + θ ≤ 564.5366673466417
 Solving iteration k = 10
-  xᵏ = 203.65302241915765
-  V̅ = 552.5916083820659
-  V̲ = 552.5916083820653
+  xᵏ = 205.5492073747986
+  V̅ = 562.6867244802702
+  V̲ = 562.6867244802706
 Terminating with near-optimal solution

To get the first-stage solution, we do:

optimize!(model)
-xᵏ = value(x_out)
203.65302241915765

To compute a second-stage solution, we do:

solve_second_stage(xᵏ, 170.0)
(V = 846.6346977580843, λ = -0.1, x = 33.65302241915765, u = 170.0)

Policy Graph

Now let's see how we can formulate and train a policy for the two-stage newsvendor problem using SDDP.jl. Under the hood, SDDP.jl implements the exact algorithm that we just wrote by hand.

model = SDDP.LinearPolicyGraph(;
+xᵏ = value(x_out)
205.5492073747986

To compute a second-stage solution, we do:

solve_second_stage(xᵏ, 170.0)
(V = 846.4450792625202, λ = -0.1, x = 35.54920737479861, u = 170.0)

Policy Graph

Now let's see how we can formulate and train a policy for the two-stage newsvendor problem using SDDP.jl. Under the hood, SDDP.jl implements the exact algorithm that we just wrote by hand.

model = SDDP.LinearPolicyGraph(;
     stages = 2,
     sense = :Max,
     upper_bound = 5 * maximum(d),  # The `M` in θ <= M
@@ -266,87 +266,87 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1   0.000000e+00  7.390041e+02  6.404877e-03       103   1
-         2   2.986205e+02  5.948838e+02  2.317381e-02       406   1
-         3   5.948838e+02  5.595833e+02  2.796483e-02       509   1
-         4   6.453132e+02  5.549646e+02  3.261399e-02       612   1
-         5   4.686292e+02  5.531378e+02  3.716588e-02       715   1
-         6   5.567797e+02  5.527552e+02  4.177380e-02       818   1
-         7   6.110663e+02  5.525985e+02  4.650092e-02       921   1
-         8   6.086563e+02  5.525940e+02  5.112600e-02      1024   1
-         9   4.675566e+02  5.525916e+02  5.579400e-02      1127   1
-        10   5.901527e+02  5.525916e+02  6.063986e-02      1230   1
-        11   4.280262e+02  5.525916e+02  6.545496e-02      1333   1
-        12   6.109591e+02  5.525916e+02  7.044291e-02      1436   1
-        13   5.358535e+02  5.525916e+02  7.526088e-02      1539   1
-        14   6.109591e+02  5.525916e+02  8.004189e-02      1642   1
-        15   4.302809e+02  5.525916e+02  8.492184e-02      1745   1
-        16   4.504226e+02  5.525916e+02  8.970380e-02      1848   1
-        17   6.109591e+02  5.525916e+02  9.451890e-02      1951   1
-        18   4.623350e+02  5.525916e+02  9.925580e-02      2054   1
-        19   5.000355e+02  5.525916e+02  1.042149e-01      2157   1
-        20   4.816761e+02  5.525916e+02  1.091499e-01      2260   1
-        21   6.109591e+02  5.525916e+02  1.292350e-01      2563   1
-        22   4.494532e+02  5.525916e+02  1.342900e-01      2666   1
-        23   6.021570e+02  5.525916e+02  1.391129e-01      2769   1
-        24   5.343076e+02  5.525916e+02  2.482328e-01      2872   1
-        25   5.224628e+02  5.525916e+02  2.532270e-01      2975   1
-        26   6.109591e+02  5.525916e+02  2.582688e-01      3078   1
-        27   5.677323e+02  5.525916e+02  2.632589e-01      3181   1
-        28   4.969335e+02  5.525916e+02  2.682159e-01      3284   1
-        29   4.647519e+02  5.525916e+02  2.732718e-01      3387   1
-        30   6.109591e+02  5.525916e+02  2.781549e-01      3490   1
-        31   6.109591e+02  5.525916e+02  2.830799e-01      3593   1
-        32   6.109591e+02  5.525916e+02  2.880180e-01      3696   1
-        33   5.440677e+02  5.525916e+02  2.930539e-01      3799   1
-        34   4.669924e+02  5.525916e+02  2.980690e-01      3902   1
-        35   5.224628e+02  5.525916e+02  3.030598e-01      4005   1
-        36   5.438199e+02  5.525916e+02  3.081069e-01      4108   1
-        37   6.109591e+02  5.525916e+02  3.131750e-01      4211   1
-        38   4.510160e+02  5.525916e+02  3.181119e-01      4314   1
-        39   3.770820e+02  5.525916e+02  3.231230e-01      4417   1
-        40   6.109591e+02  5.525916e+02  3.281329e-01      4520   1
+         1   0.000000e+00  7.288656e+02  6.253004e-03       103   1
+         2   4.149257e+02  6.047939e+02  2.256107e-02       406   1
+         3   6.047939e+02  5.687644e+02  2.714705e-02       509   1
+         4   6.562646e+02  5.649475e+02  3.169394e-02       612   1
+         5   5.580831e+02  5.633213e+02  3.614902e-02       715   1
+         6   5.364529e+02  5.627452e+02  4.063010e-02       818   1
+         7   6.208254e+02  5.627143e+02  4.503107e-02       921   1
+         8   6.186186e+02  5.626895e+02  4.952002e-02      1024   1
+         9   4.698379e+02  5.626867e+02  5.395007e-02      1127   1
+        10   6.006088e+02  5.626867e+02  5.840397e-02      1230   1
+        11   6.166476e+02  5.626867e+02  6.302094e-02      1333   1
+        12   4.999140e+02  5.626867e+02  6.770802e-02      1436   1
+        13   4.551252e+02  5.626867e+02  7.229900e-02      1539   1
+        14   5.154644e+02  5.626867e+02  7.689691e-02      1642   1
+        15   5.300583e+02  5.626867e+02  8.158302e-02      1745   1
+        16   6.166476e+02  5.626867e+02  8.621788e-02      1848   1
+        17   6.166476e+02  5.626867e+02  9.091806e-02      1951   1
+        18   6.166476e+02  5.626867e+02  9.555793e-02      2054   1
+        19   6.166476e+02  5.626867e+02  1.002660e-01      2157   1
+        20   6.166476e+02  5.626867e+02  1.049111e-01      2260   1
+        21   6.166476e+02  5.626867e+02  1.240809e-01      2563   1
+        22   3.926782e+02  5.626867e+02  1.287379e-01      2666   1
+        23   4.608279e+02  5.626867e+02  1.335170e-01      2769   1
+        24   4.934783e+02  5.626867e+02  1.382120e-01      2872   1
+        25   6.134071e+02  5.626867e+02  1.428580e-01      2975   1
+        26   3.738141e+02  5.626867e+02  1.477699e-01      3078   1
+        27   4.608279e+02  5.626867e+02  1.524570e-01      3181   1
+        28   6.166476e+02  5.626867e+02  1.571741e-01      3284   1
+        29   5.858490e+02  5.626867e+02  1.619849e-01      3387   1
+        30   6.166476e+02  5.626867e+02  1.667149e-01      3490   1
+        31   6.166476e+02  5.626867e+02  1.715641e-01      3593   1
+        32   6.166476e+02  5.626867e+02  1.762819e-01      3696   1
+        33   6.166476e+02  5.626867e+02  1.810620e-01      3799   1
+        34   6.166476e+02  5.626867e+02  1.859241e-01      3902   1
+        35   5.428217e+02  5.626867e+02  1.906929e-01      4005   1
+        36   6.134071e+02  5.626867e+02  1.955221e-01      4108   1
+        37   6.166476e+02  5.626867e+02  2.002940e-01      4211   1
+        38   6.166476e+02  5.626867e+02  2.051721e-01      4314   1
+        39   6.076516e+02  5.626867e+02  2.099750e-01      4417   1
+        40   3.944552e+02  5.626867e+02  2.148480e-01      4520   1
 -------------------------------------------------------------------
 status         : simulation_stopping
-total time (s) : 3.281329e-01
+total time (s) : 2.148480e-01
 total solves   : 4520
-best bound     :  5.525916e+02
-simulation ci  :  5.195779e+02 ± 3.595635e+01
+best bound     :  5.626867e+02
+simulation ci  :  5.467476e+02 ± 3.663772e+01
 numeric issues : 0
--------------------------------------------------------------------

One way to query the optimal policy is with SDDP.DecisionRule:

first_stage_rule = SDDP.DecisionRule(model; node = 1)
A decision rule for node 1
solution_1 = SDDP.evaluate(first_stage_rule; incoming_state = Dict(:x => 0.0))
(stage_objective = -407.3060448382587, outgoing_state = Dict(:x => 203.65302241912934), controls = Dict{Any, Any}())

Here's the second stage:

second_stage_rule = SDDP.DecisionRule(model; node = 2)
+-------------------------------------------------------------------

One way to query the optimal policy is with SDDP.DecisionRule:

first_stage_rule = SDDP.DecisionRule(model; node = 1)
A decision rule for node 1
solution_1 = SDDP.evaluate(first_stage_rule; incoming_state = Dict(:x => 0.0))
(stage_objective = -411.0984147495424, outgoing_state = Dict(:x => 205.5492073747712), controls = Dict{Any, Any}())

Here's the second stage:

second_stage_rule = SDDP.DecisionRule(model; node = 2)
 solution = SDDP.evaluate(
     second_stage_rule;
     incoming_state = Dict(:x => solution_1.outgoing_state[:x]),
     noise = 170.0,  # A value of d[ω], can be out-of-sample.
     controls_to_record = [:u_sell],
-)
(stage_objective = 846.6346977580871, outgoing_state = Dict(:x => 33.65302241912934), controls = Dict(:u_sell => 170.0))

Simulation

Querying the decision rules is tedious. It's often more useful to simulate the policy:

simulations = SDDP.simulate(
+)
(stage_objective = 846.4450792625229, outgoing_state = Dict(:x => 35.549207374771214), controls = Dict(:u_sell => 170.0))

Simulation

Querying the decision rules is tedious. It's often more useful to simulate the policy:

simulations = SDDP.simulate(
     model,
     10,  #= number of replications =#
     [:x, :u_sell, :u_make];  #= variables to record =#
     skip_undefined_variables = true,
 );

simulations is a vector with 10 elements

length(simulations)
10

and each element is a vector with two elements (one for each stage)

length(simulations[1])
2

The first stage contains:

simulations[1][1]
Dict{Symbol, Any} with 9 entries:
-  :u_make          => 203.653
-  :bellman_term    => 959.898
+  :u_make          => 205.549
+  :bellman_term    => 973.785
   :noise_term      => nothing
   :node_index      => 1
-  :stage_objective => -407.306
+  :stage_objective => -411.098
   :objective_state => nothing
   :u_sell          => NaN
   :belief          => Dict(1=>1.0)
-  :x               => State{Float64}(0.0, 203.653)

The second stage contains:

simulations[1][2]
Dict{Symbol, Any} with 9 entries:
+  :x               => State{Float64}(0.0, 205.549)

The second stage contains:

simulations[1][2]
Dict{Symbol, Any} with 9 entries:
   :u_make          => NaN
   :bellman_term    => 0.0
-  :noise_term      => 178.303
+  :noise_term      => 174.429
   :node_index      => 2
-  :stage_objective => 888.982
+  :stage_objective => 869.033
   :objective_state => nothing
-  :u_sell          => 178.303
+  :u_sell          => 174.429
   :belief          => Dict(2=>1.0)
-  :x               => State{Float64}(203.653, 25.3496)

We can compute aggregated statistics across the simulations:

objectives = map(simulations) do simulation
+  :x               => State{Float64}(205.549, 31.1203)

We can compute aggregated statistics across the simulations:

objectives = map(simulations) do simulation
     return sum(data[:stage_objective] for data in simulation)
 end
 μ, t = SDDP.confidence_interval(objectives)
-println("Simulation ci : $μ ± $t")
Simulation ci : 568.0876073846063 ± 30.126772853336654

Risk aversion revisited

SDDP.jl contains a number of risk measures. One example is:

0.5 * SDDP.Expectation() + 0.5 * SDDP.WorstCase()
A convex combination of 0.5 * SDDP.Expectation() + 0.5 * SDDP.WorstCase()

You can construct a risk-averse policy by passing a risk measure to the risk_measure keyword argument of SDDP.train.

We can explore how the optimal decision changes with risk by creating a function:

function solve_newsvendor(risk_measure::SDDP.AbstractRiskMeasure)
+println("Simulation ci : $μ ± $t")
Simulation ci : 554.2598594023665 ± 56.66579450161904

Risk aversion revisited

SDDP.jl contains a number of risk measures. One example is:

0.5 * SDDP.Expectation() + 0.5 * SDDP.WorstCase()
A convex combination of 0.5 * SDDP.Expectation() + 0.5 * SDDP.WorstCase()

You can construct a risk-averse policy by passing a risk measure to the risk_measure keyword argument of SDDP.train.

We can explore how the optimal decision changes with risk by creating a function:

function solve_newsvendor(risk_measure::SDDP.AbstractRiskMeasure)
     model = SDDP.LinearPolicyGraph(;
         stages = 2,
         sense = :Max,
@@ -372,7 +372,7 @@
     first_stage_rule = SDDP.DecisionRule(model; node = 1)
     solution = SDDP.evaluate(first_stage_rule; incoming_state = Dict(:x => 0.0))
     return solution.outgoing_state[:x]
-end
solve_newsvendor (generic function with 1 method)

Now we can see how many units a decision maker would order using CVaR:

solve_newsvendor(SDDP.CVaR(0.4))
180.52901393095172

as well as a decision-maker who cares only about the worst-case outcome:

solve_newsvendor(SDDP.WorstCase())
155.1051137651416

In general, the decision-maker will be somewhere between the two extremes. The SDDP.Entropic risk measure is a risk measure that has a single parameter that lets us explore the space of policies between the two extremes. When the parameter is small, the measure acts like SDDP.Expectation, and when it is large, it acts like SDDP.WorstCase.

Here is what we get if we solve our problem multiple times for different values of the risk aversion parameter $\gamma$:

Γ = [10^i for i in -4:0.5:1]
+end
solve_newsvendor (generic function with 1 method)

Now we can see how many units a decision maker would order using CVaR:

solve_newsvendor(SDDP.CVaR(0.4))
185.7093540877131

as well as a decision-maker who cares only about the worst-case outcome:

solve_newsvendor(SDDP.WorstCase())
157.9347845819746

In general, the decision-maker will be somewhere between the two extremes. The SDDP.Entropic risk measure is a risk measure that has a single parameter that lets us explore the space of policies between the two extremes. When the parameter is small, the measure acts like SDDP.Expectation, and when it is large, it acts like SDDP.WorstCase.

Here is what we get if we solve our problem multiple times for different values of the risk aversion parameter $\gamma$:

Γ = [10^i for i in -4:0.5:1]
 buy = [solve_newsvendor(SDDP.Entropic(γ)) for γ in Γ]
 Plots.plot(
     Γ,
@@ -381,4 +381,4 @@
     xlabel = "Risk aversion parameter γ",
     ylabel = "Number of pies to make",
     legend = false,
-)
Example block output

Things to try

There are a number of things you can try next:

+)Example block output

Things to try

There are a number of things you can try next:

diff --git a/previews/PR811/tutorial/example_reservoir/c7490ec7.svg b/previews/PR811/tutorial/example_reservoir/03e3fba2.svg similarity index 85% rename from previews/PR811/tutorial/example_reservoir/c7490ec7.svg rename to previews/PR811/tutorial/example_reservoir/03e3fba2.svg index f2953e243..5fb64e314 100644 --- a/previews/PR811/tutorial/example_reservoir/c7490ec7.svg +++ b/previews/PR811/tutorial/example_reservoir/03e3fba2.svg @@ -1,46 +1,46 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_reservoir/42a7af5b.svg b/previews/PR811/tutorial/example_reservoir/3da19098.svg similarity index 84% rename from previews/PR811/tutorial/example_reservoir/42a7af5b.svg rename to previews/PR811/tutorial/example_reservoir/3da19098.svg index 1e9a9bf3d..97b168308 100644 --- a/previews/PR811/tutorial/example_reservoir/42a7af5b.svg +++ b/previews/PR811/tutorial/example_reservoir/3da19098.svg @@ -1,52 +1,52 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_reservoir/55b77741.svg b/previews/PR811/tutorial/example_reservoir/4cbd35d6.svg similarity index 68% rename from previews/PR811/tutorial/example_reservoir/55b77741.svg rename to previews/PR811/tutorial/example_reservoir/4cbd35d6.svg index 715e9d43c..7636f789e 100644 --- a/previews/PR811/tutorial/example_reservoir/55b77741.svg +++ b/previews/PR811/tutorial/example_reservoir/4cbd35d6.svg @@ -1,148 +1,148 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_reservoir/864f7c2b.svg b/previews/PR811/tutorial/example_reservoir/864f7c2b.svg deleted file mode 100644 index f5c39f5d6..000000000 --- a/previews/PR811/tutorial/example_reservoir/864f7c2b.svg +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR811/tutorial/example_reservoir/6b57b71f.svg b/previews/PR811/tutorial/example_reservoir/8721dae3.svg similarity index 85% rename from previews/PR811/tutorial/example_reservoir/6b57b71f.svg rename to previews/PR811/tutorial/example_reservoir/8721dae3.svg index 41fef8d85..565524371 100644 --- a/previews/PR811/tutorial/example_reservoir/6b57b71f.svg +++ b/previews/PR811/tutorial/example_reservoir/8721dae3.svg @@ -1,46 +1,46 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_reservoir/869c3d19.svg b/previews/PR811/tutorial/example_reservoir/bb3277c2.svg similarity index 84% rename from previews/PR811/tutorial/example_reservoir/869c3d19.svg rename to previews/PR811/tutorial/example_reservoir/bb3277c2.svg index ad188e550..beb9d6269 100644 --- a/previews/PR811/tutorial/example_reservoir/869c3d19.svg +++ b/previews/PR811/tutorial/example_reservoir/bb3277c2.svg @@ -1,109 +1,109 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_reservoir/e6446ea7.svg b/previews/PR811/tutorial/example_reservoir/e6446ea7.svg new file mode 100644 index 000000000..3a4450a6e --- /dev/null +++ b/previews/PR811/tutorial/example_reservoir/e6446ea7.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_reservoir/e320acda.svg b/previews/PR811/tutorial/example_reservoir/f028b18e.svg similarity index 84% rename from previews/PR811/tutorial/example_reservoir/e320acda.svg rename to previews/PR811/tutorial/example_reservoir/f028b18e.svg index 361b9d76a..6ed92e464 100644 --- a/previews/PR811/tutorial/example_reservoir/e320acda.svg +++ b/previews/PR811/tutorial/example_reservoir/f028b18e.svg @@ -1,52 +1,52 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/example_reservoir/index.html b/previews/PR811/tutorial/example_reservoir/index.html index 79db268fb..6a534cc7c 100644 --- a/previews/PR811/tutorial/example_reservoir/index.html +++ b/previews/PR811/tutorial/example_reservoir/index.html @@ -9,7 +9,7 @@ import DataFrames import HiGHS import Plots

Data

First, we need some data for the problem. For this tutorial, we'll write CSV files to a temporary directory from Julia. If you have an existing file, you could change the filename to point to that instead.

dir = mktempdir()
-filename = joinpath(dir, "example_reservoir.csv")
"/tmp/jl_xb9uFx/example_reservoir.csv"

Here is the data

csv_data = """
+filename = joinpath(dir, "example_reservoir.csv")
"/tmp/jl_Q2Qybi/example_reservoir.csv"

Here is the data

csv_data = """
 week,inflow,demand,cost
 1,3,7,10.2\n2,2,7.1,10.4\n3,3,7.2,10.6\n4,2,7.3,10.9\n5,3,7.4,11.2\n
 6,2,7.6,11.5\n7,3,7.8,11.9\n8,2,8.1,12.3\n9,3,8.3,12.7\n10,2,8.6,13.1\n
@@ -29,7 +29,7 @@
     Plots.plot(data[!, :cost]; ylabel = "Cost", xlabel = "Week");
     layout = (3, 1),
     legend = false,
-)
Example block output

The number of weeks will be useful later:

T = size(data, 1)
52

Deterministic JuMP model

To start, we construct a deterministic model in pure JuMP.

Create a JuMP model, using HiGHS as the optimizer:

model = Model(HiGHS.Optimizer)
+)
Example block output

The number of weeks will be useful later:

T = size(data, 1)
52

Deterministic JuMP model

To start, we construct a deterministic model in pure JuMP.

Create a JuMP model, using HiGHS as the optimizer:

model = Model(HiGHS.Optimizer)
 set_silent(model)

x_storage[t]: the amount of water in the reservoir at the start of stage t:

reservoir_max = 320.0
 @variable(model, 0 <= x_storage[1:T+1] <= reservoir_max)
53-element Vector{VariableRef}:
  x_storage[1]
@@ -197,13 +197,13 @@
   Dual objective value : 6.82910e+02
 
 * Work counters
-  Solve time (sec)   : 9.01222e-04
+  Solve time (sec)   : 8.63552e-04
   Simplex iterations : 53
   Barrier iterations : 0
   Node count         : -1
 

The total cost is:

objective_value(model)
682.9099999999999

Here's a plot of demand and generation:

Plots.plot(data[!, :demand]; label = "Demand", xlabel = "Week")
 Plots.plot!(value.(u_thermal); label = "Thermal")
-Plots.plot!(value.(u_flow); label = "Hydro")
Example block output

And here's the storage over time:

Plots.plot(value.(x_storage); label = "Storage", xlabel = "Week")
Example block output

Deterministic SDDP model

For the next step, we show how to decompose our JuMP model into SDDP.jl. It should obtain the same solution.

model = SDDP.LinearPolicyGraph(;
+Plots.plot!(value.(u_flow); label = "Hydro")
Example block output

And here's the storage over time:

Plots.plot(value.(x_storage); label = "Storage", xlabel = "Week")
Example block output

Deterministic SDDP model

For the next step, we show how to decompose our JuMP model into SDDP.jl. It should obtain the same solution.

model = SDDP.LinearPolicyGraph(;
     stages = T,
     sense = :Min,
     lower_bound = 0.0,
@@ -252,11 +252,11 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1   1.079600e+03  3.157700e+02  4.467511e-02       104   1
-        10   6.829100e+02  6.829100e+02  1.466031e-01      1040   1
+         1   1.079600e+03  3.157700e+02  4.390097e-02       104   1
+        10   6.829100e+02  6.829100e+02  1.390100e-01      1040   1
 -------------------------------------------------------------------
 status         : iteration_limit
-total time (s) : 1.466031e-01
+total time (s) : 1.390100e-01
 total solves   : 1040
 best bound     :  6.829100e+02
 simulation ci  :  7.289889e+02 ± 7.726064e+01
@@ -279,9 +279,9 @@
 
 Plots.plot(data[!, :demand]; label = "Demand", xlabel = "Week")
 Plots.plot!(r_sim; label = "Thermal")
-Plots.plot!(u_sim; label = "Hydro")
Example block output

Perfect. That's the same as we got before.

Now let's look at x_storage. This is a little more complicated, because we need to grab the outgoing value of the state variable in each stage:

x_sim = [sim[:x_storage].out for sim in simulations[1]]
+Plots.plot!(u_sim; label = "Hydro")
Example block output

Perfect. That's the same as we got before.

Now let's look at x_storage. This is a little more complicated, because we need to grab the outgoing value of the state variable in each stage:

x_sim = [sim[:x_storage].out for sim in simulations[1]]
 
-Plots.plot(x_sim; label = "Storage", xlabel = "Week")
Example block output

Stochastic SDDP model

Now we add some randomness to our model. In each stage, we assume that the inflow could be: 2 units lower, with 30% probability; the same as before, with 40% probability; or 5 units higher, with 30% probability.

model = SDDP.LinearPolicyGraph(;
+Plots.plot(x_sim; label = "Storage", xlabel = "Week")
Example block output

Stochastic SDDP model

Now we add some randomness to our model. In each stage, we assume that the inflow could be: 2 units lower, with 30% probability; the same as before, with 40% probability; or 5 units higher, with 30% probability.

model = SDDP.LinearPolicyGraph(;
     stages = T,
     sense = :Min,
     lower_bound = 0.0,
@@ -335,23 +335,23 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1   0.000000e+00  0.000000e+00  4.471517e-02       208   1
-        45   1.015970e+02  2.501284e+02  1.047305e+00      9360   1
-        82   8.881599e+01  2.632311e+02  2.054002e+00     17056   1
-       100   1.198882e+02  2.666197e+02  2.653225e+00     20800   1
+         1   5.619600e+02  2.548809e+01  4.797482e-02       208   1
+        47   2.794782e+02  2.493251e+02  1.068635e+00      9776   1
+        87   1.498337e+02  2.645551e+02  2.081532e+00     18096   1
+       100   1.959000e+02  2.664853e+02  2.432085e+00     20800   1
 -------------------------------------------------------------------
 status         : iteration_limit
-total time (s) : 2.653225e+00
+total time (s) : 2.432085e+00
 total solves   : 20800
-best bound     :  2.666197e+02
-simulation ci  :  2.769728e+02 ± 3.705277e+01
+best bound     :  2.664853e+02
+simulation ci  :  3.200237e+02 ± 4.569034e+01
 numeric issues : 0
 -------------------------------------------------------------------

Now simulate the policy. This time we do 100 replications because the policy is now stochastic instead of deterministic:

simulations =
     SDDP.simulate(model, 100, [:x_storage, :u_flow, :u_thermal, :ω_inflow]);

And let's plot the use of thermal generation in each replication:

plot = Plots.plot(data[!, :demand]; label = "Demand", xlabel = "Week")
 for simulation in simulations
     Plots.plot!(plot, [sim[:u_thermal] for sim in simulation]; label = "")
 end
-plot
Example block output

Viewing an interpreting static plots like this is difficult, particularly as the number of simulations grows. SDDP.jl includes an interactive SpaghettiPlot that makes things easier:

plot = SDDP.SpaghettiPlot(simulations)
+plot
Example block output

Viewing an interpreting static plots like this is difficult, particularly as the number of simulations grows. SDDP.jl includes an interactive SpaghettiPlot that makes things easier:

plot = SDDP.SpaghettiPlot(simulations)
 SDDP.add_spaghetti(plot; title = "Storage") do sim
     return sim[:x_storage].out
 end
@@ -427,40 +427,41 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1   7.522165e+04  4.709469e+04  2.835579e-01      3123   1
-         5   7.105922e+04  8.759186e+04  1.462410e+00     15407   1
-        10   2.946450e+04  9.198956e+04  2.644696e+00     26238   1
-        14   1.437630e+05  9.298395e+04  4.136594e+00     38314   1
-        17   2.713174e+05  9.318512e+04  6.652679e+00     54963   1
-        20   7.015304e+04  9.326356e+04  7.956363e+00     63084   1
-        26   9.499089e+04  9.335268e+04  1.377707e+01     95550   1
-        33   1.479632e+05  9.336211e+04  1.898816e+01    120947   1
-        38   2.005318e+04  9.337136e+04  2.399276e+01    142178   1
-        43   1.095355e+05  9.337361e+04  2.953139e+01    163617   1
-        45   4.395784e+05  9.337447e+04  3.802440e+01    189415   1
-        52   1.007213e+05  9.338021e+04  4.371206e+01    207740   1
-        57   2.110075e+05  9.338044e+04  5.113286e+01    231051   1
-        62   3.033249e+05  9.338277e+04  6.057021e+01    258730   1
-        67   1.521672e+05  9.338428e+04  6.777268e+01    278713   1
-        70   3.297146e+05  9.338575e+04  7.466152e+01    296194   1
-        74   3.027746e+04  9.338646e+04  8.015764e+01    309518   1
-        76   3.305361e+05  9.338672e+04  8.630700e+01    324292   1
-        79   4.865088e+05  9.338733e+04  9.911923e+01    354045   1
-        82   2.669285e+05  9.338975e+04  1.053440e+02    367366   1
-        85   3.459473e+05  9.339063e+04  1.146121e+02    386927   1
-       100   1.279878e+05  9.339284e+04  1.363094e+02    430860   1
+         1   1.765543e+05  7.531437e+04  6.209869e-01      7075   1
+         2   5.306559e+05  9.226252e+04  2.842379e+00     29958   1
+         5   1.299119e+05  9.294558e+04  3.900052e+00     39743   1
+         8   1.226027e+05  9.328028e+04  5.514643e+00     52648   1
+        13   1.797956e+05  9.329892e+04  7.201875e+00     64935   1
+        15   1.720022e+05  9.334951e+04  9.283951e+00     78669   1
+        21   1.395994e+05  9.336543e+04  1.497240e+01    111551   1
+        27   2.927228e+04  9.337078e+04  2.021347e+01    137569   1
+        35   1.351935e+05  9.337539e+04  2.587091e+01    163177   1
+        40   1.604219e+05  9.337752e+04  3.147526e+01    183160   1
+        45   3.820557e+05  9.337910e+04  4.066478e+01    216663   1
+        48   5.434189e+05  9.338040e+04  4.991359e+01    247040   1
+        51   1.816256e+05  9.338269e+04  5.725287e+01    269721   1
+        57   2.367720e+05  9.338618e+04  6.374079e+01    288043   1
+        61   8.216129e+04  9.338772e+04  6.904948e+01    303031   1
+        67   2.897234e+04  9.338862e+04  7.445199e+01    317817   1
+        70   2.994891e+05  9.338943e+04  8.239305e+01    338210   1
+        73   3.456753e+05  9.338961e+04  8.954896e+01    355899   1
+        77   6.458147e+04  9.339040e+04  9.533064e+01    369847   1
+        82   1.301077e+05  9.339071e+04  1.026668e+02    386918   1
+        84   4.595395e+04  9.339108e+04  1.081708e+02    399404   1
+        88   1.197247e+05  9.339259e+04  1.147888e+02    414184   1
+       100   6.965854e+04  9.339391e+04  1.385869e+02    463724   1
 -------------------------------------------------------------------
 status         : iteration_limit
-total time (s) : 1.363094e+02
-total solves   : 430860
-best bound     :  9.339284e+04
-simulation ci  :  9.681754e+04 ± 1.884197e+04
+total time (s) : 1.385869e+02
+total solves   : 463724
+best bound     :  9.339391e+04
+simulation ci  :  1.048370e+05 ± 2.107734e+04
 numeric issues : 0
 -------------------------------------------------------------------

When we simulate now, each trajectory will be a different length, because each cycle has a 95% probability of continuing and a 5% probability of stopping.

simulations = SDDP.simulate(model, 3);
 length.(simulations)
3-element Vector{Int64}:
-  364
+  416
  1040
- 2132

We can simulate a fixed number of cycles by passing a sampling_scheme:

simulations = SDDP.simulate(
+  260

We can simulate a fixed number of cycles by passing a sampling_scheme:

simulations = SDDP.simulate(
     model,
     100,
     [:x_storage, :u_flow];
@@ -497,4 +498,4 @@
         return sim[:u_flow]
     end;
     layout = (2, 1),
-)
Example block output

Next steps

Our model is very basic. There are many aspects that we could improve:

  • Can you add a second reservoir to make a river chain?

  • Can you modify the problem and data to use proper units, including a conversion between the volume of water flowing through the turbine and the electrical power output?

+)Example block output

Next steps

Our model is very basic. There are many aspects that we could improve:

  • Can you add a second reservoir to make a river chain?

  • Can you modify the problem and data to use proper units, including a conversion between the volume of water flowing through the turbine and the electrical power output?

diff --git a/previews/PR811/tutorial/first_steps/index.html b/previews/PR811/tutorial/first_steps/index.html index baea7596b..cd246723a 100644 --- a/previews/PR811/tutorial/first_steps/index.html +++ b/previews/PR811/tutorial/first_steps/index.html @@ -228,14 +228,14 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.750000e+04 2.500000e+03 3.675938e-03 12 1 - 10 7.500000e+03 8.333333e+03 1.411986e-02 120 1 + 1 2.750000e+04 3.437500e+03 3.633022e-03 12 1 + 10 2.000000e+04 8.333333e+03 1.367593e-02 120 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 1.411986e-02 +total time (s) : 1.367593e-02 total solves : 120 best bound : 8.333333e+03 -simulation ci : 1.287500e+04 ± 4.165000e+03 +simulation ci : 1.303125e+04 ± 4.925497e+03 numeric issues : 0 -------------------------------------------------------------------

There's a lot going on in this printout! Let's break it down.

The first section, "problem," gives some problem statistics. In this example there are 3 nodes, 1 state variable, and 27 scenarios ($3^3$). We haven't solved this problem before so there are no existing cuts.

The "options" section lists some options we are using to solve the problem. For more information on the numerical stability report, read the Numerical stability report section.

The "subproblem structure" section also needs explaining. This looks at all of the nodes in the policy graph and reports the minimum and maximum number of variables and each constraint type in the corresponding subproblem. In this case each subproblem has 7 variables and various numbers of different constraint types. Note that the exact numbers may not correspond to the formulation as you wrote it, because SDDP.jl adds some extra variables for the cost-to-go function.

Then comes the iteration log, which is the main part of the printout. It has the following columns:

  • iteration: the SDDP iteration
  • simulation: the cost of the single forward pass simulation for that iteration. This value is stochastic and is not guaranteed to improve over time. However, it's useful to check that the units are reasonable, and that it is not deterministic if you intended for the problem to be stochastic, etc.
  • bound: this is a lower bound (upper if maximizing) for the value of the optimal policy. This bound should be monotonically improving (increasing if minimizing, decreasing if maximizing), but in some cases it can temporarily worsen due to cut selection, especially in the early iterations of the algorithm.
  • time (s): the total number of seconds spent solving so far
  • solves: the total number of subproblem solves to date. This can be very large!
  • pid: the ID of the processor used to solve that iteration. This should be 1 unless you are using parallel computation.

In addition, if the first character of a line is , then SDDP.jl experienced numerical issues during the solve, but successfully recovered.

The printout finishes with some summary statistics:

  • status: why did the solver stop?
  • total time (s), best bound, and total solves are the values from the last iteration of the solve.
  • simulation ci: a confidence interval that estimates the quality of the policy from the Simulation column.
  • numeric issues: the number of iterations that experienced numerical issues.
Warning

The simulation ci result can be misleading if you run a small number of iterations, or if the initial simulations are very bad. On a more technical note, it is an in-sample simulation, which may not reflect the true performance of the policy. See Obtaining bounds for more details.

Obtaining the decision rule

After training a policy, we can create a decision rule using SDDP.DecisionRule:

rule = SDDP.DecisionRule(model; node = 1)
A decision rule for node 1

Then, to evaluate the decision rule, we use SDDP.evaluate:

solution = SDDP.evaluate(
     rule;
@@ -254,31 +254,31 @@
 replication = 1
 stage = 2
 simulations[replication][stage]
Dict{Symbol, Any} with 10 entries:
-  :volume             => State{Float64}(200.0, 150.0)
+  :volume             => State{Float64}(200.0, 100.0)
   :hydro_spill        => 0.0
-  :bellman_term       => 0.0
-  :noise_term         => 100.0
+  :bellman_term       => 2500.0
+  :noise_term         => 0.0
   :node_index         => 2
-  :stage_objective    => 0.0
+  :stage_objective    => 5000.0
   :objective_state    => nothing
-  :thermal_generation => 0.0
-  :hydro_generation   => 150.0
+  :thermal_generation => 50.0
+  :hydro_generation   => 100.0
   :belief             => Dict(2=>1.0)

Ignore many of the entries for now; they will be relevant later.

One element of interest is :volume.

outgoing_volume = map(simulations[1]) do node
     return node[:volume].out
 end
3-element Vector{Float64}:
  200.0
- 150.0
- 100.0

Another is :thermal_generation.

thermal_generation = map(simulations[1]) do node
+ 100.0
+  -0.0

Another is :thermal_generation.

thermal_generation = map(simulations[1]) do node
     return node[:thermal_generation]
 end
3-element Vector{Float64}:
  150.0
-   0.0
+  50.0
    0.0

Obtaining bounds

Because the optimal policy is stochastic, one common approach to quantify the quality of the policy is to construct a confidence interval for the expected cost by summing the stage objectives along each simulation.

objectives = map(simulations) do simulation
     return sum(stage[:stage_objective] for stage in simulation)
 end
 
 μ, ci = SDDP.confidence_interval(objectives)
-println("Confidence interval: ", μ, " ± ", ci)
Confidence interval: 7700.0 ± 961.7142522757489

This confidence interval is an estimate for an upper bound of the policy's quality. We can calculate the lower bound using SDDP.calculate_bound.

println("Lower bound: ", SDDP.calculate_bound(model))
Lower bound: 8333.333333333332
Tip

The upper- and lower-bounds are reversed if maximizing, i.e., SDDP.calculate_bound. returns an upper bound.

Custom recorders

In addition to simulating the primal values of variables, we can also pass custom recorder functions. Each of these functions takes one argument, the JuMP subproblem corresponding to each node. This function gets called after we have solved each node as we traverse the policy graph in the simulation.

For example, the dual of the demand constraint (which we named demand_constraint) corresponds to the price we should charge for electricity, since it represents the cost of each additional unit of demand. To calculate this, we can go:

simulations = SDDP.simulate(
+println("Confidence interval: ", μ, " ± ", ci)
Confidence interval: 9700.0 ± 992.9806980332835

This confidence interval is an estimate for an upper bound of the policy's quality. We can calculate the lower bound using SDDP.calculate_bound.

println("Lower bound: ", SDDP.calculate_bound(model))
Lower bound: 8333.333333333332
Tip

The upper- and lower-bounds are reversed if maximizing, i.e., SDDP.calculate_bound. returns an upper bound.

Custom recorders

In addition to simulating the primal values of variables, we can also pass custom recorder functions. Each of these functions takes one argument, the JuMP subproblem corresponding to each node. This function gets called after we have solved each node as we traverse the policy graph in the simulation.

For example, the dual of the demand constraint (which we named demand_constraint) corresponds to the price we should charge for electricity, since it represents the cost of each additional unit of demand. To calculate this, we can go:

simulations = SDDP.simulate(
     model,
     1;  ## Perform a single simulation
     custom_recorders = Dict{Symbol,Function}(
@@ -289,6 +289,6 @@
 prices = map(simulations[1]) do node
     return node[:price]
 end
3-element Vector{Float64}:
- 50.0
- 50.0
- -0.0

Extracting the marginal water values

Finally, we can use SDDP.ValueFunction and SDDP.evaluate to obtain and evaluate the value function at different points in the state-space.

Note

By "value function" we mean $\mathbb{E}_{j \in i^+, \varphi \in \Omega_j}[V_j(x^\prime, \varphi)]$, not the function $V_i(x, \omega)$.

First, we construct a value function from the first subproblem:

V = SDDP.ValueFunction(model; node = 1)
A value function for node 1

Then we can evaluate V at a point:

cost, price = SDDP.evaluate(V, Dict("volume" => 10))
(21499.999999999996, Dict(:volume => -99.99999999999999))

This returns the cost-to-go (cost), and the gradient of the cost-to-go function with respect to each state variable. Note that since we are minimizing, the price has a negative sign: each additional unit of water leads to a decrease in the expected long-run cost.

+ 50.0 + 100.0 + 150.0

Extracting the marginal water values

Finally, we can use SDDP.ValueFunction and SDDP.evaluate to obtain and evaluate the value function at different points in the state-space.

Note

By "value function" we mean $\mathbb{E}_{j \in i^+, \varphi \in \Omega_j}[V_j(x^\prime, \varphi)]$, not the function $V_i(x, \omega)$.

First, we construct a value function from the first subproblem:

V = SDDP.ValueFunction(model; node = 1)
A value function for node 1

Then we can evaluate V at a point:

cost, price = SDDP.evaluate(V, Dict("volume" => 10))
(21499.999999999993, Dict(:volume => -99.99999999999999))

This returns the cost-to-go (cost), and the gradient of the cost-to-go function with respect to each state variable. Note that since we are minimizing, the price has a negative sign: each additional unit of water leads to a decrease in the expected long-run cost.

diff --git a/previews/PR811/tutorial/inventory/db106b0b.svg b/previews/PR811/tutorial/inventory/8d504edc.svg similarity index 84% rename from previews/PR811/tutorial/inventory/db106b0b.svg rename to previews/PR811/tutorial/inventory/8d504edc.svg index 82b90daba..9383a8722 100644 --- a/previews/PR811/tutorial/inventory/db106b0b.svg +++ b/previews/PR811/tutorial/inventory/8d504edc.svg @@ -1,57 +1,57 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/inventory/d0826549.svg b/previews/PR811/tutorial/inventory/d4db6541.svg similarity index 84% rename from previews/PR811/tutorial/inventory/d0826549.svg rename to previews/PR811/tutorial/inventory/d4db6541.svg index a9f2da4a5..2eb571787 100644 --- a/previews/PR811/tutorial/inventory/d0826549.svg +++ b/previews/PR811/tutorial/inventory/d4db6541.svg @@ -1,51 +1,51 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/inventory/index.html b/previews/PR811/tutorial/inventory/index.html index 75ef2d9b5..4dd0514f9 100644 --- a/previews/PR811/tutorial/inventory/index.html +++ b/previews/PR811/tutorial/inventory/index.html @@ -72,24 +72,23 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 4.044053e+05 4.573582e+04 1.952600e-02 212 1 - 48 1.898816e+05 1.443368e+05 1.030853e+00 13476 1 - 102 1.572079e+05 1.443373e+05 2.031849e+00 27124 1 - 164 1.290816e+05 1.443373e+05 3.049588e+00 40268 1 - 213 1.482816e+05 1.443373e+05 4.051144e+00 51756 1 - 266 1.142605e+05 1.443373e+05 5.057745e+00 62992 1 - 287 1.179658e+05 1.443373e+05 5.513835e+00 67444 1 + 1 4.456684e+05 4.573582e+04 1.931691e-02 212 1 + 58 2.019242e+05 1.443354e+05 1.032120e+00 15596 1 + 115 1.146395e+05 1.443372e+05 2.035309e+00 29880 1 + 178 9.863947e+04 1.443374e+05 3.049769e+00 43236 1 + 234 9.085000e+04 1.443374e+05 4.052715e+00 56208 1 + 286 9.085000e+04 1.443374e+05 5.023869e+00 67232 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 5.513835e+00 -total solves : 67444 -best bound : 1.443373e+05 -simulation ci : 1.437148e+05 ± 3.669326e+03 +total time (s) : 5.023869e+00 +total solves : 67232 +best bound : 1.443374e+05 +simulation ci : 1.463885e+05 ± 3.909823e+03 numeric issues : 0 ------------------------------------------------------------------- -Confidence interval: 142233.16 ± 3526.03 -Lower bound: 144337.34

Plot the optimal inventory levels:

plt = SDDP.publication_plot(
+Confidence interval: 142268.11 ± 3853.81
+Lower bound: 144337.44

Plot the optimal inventory levels:

plt = SDDP.publication_plot(
     simulations;
     title = "x_inventory.out + u_buy.out",
     xlabel = "Stage",
@@ -97,7 +96,7 @@
     ylims = (0, 1_000),
 ) do data
     return data[:x_inventory].out + data[:u_buy].out
-end
Example block output

In the early stages, we indeed recover an order-up-to policy. However, there are end-of-horizon effects as the agent tries to optimize their decision making knowing that they have 10 realizations of demand.

Infinite horizon

We can remove the end-of-horizonn effects by considering an infinite horizon model. We assume a discount factor $\alpha=0.95$:

α = 0.95
+end
Example block output

In the early stages, we indeed recover an order-up-to policy. However, there are end-of-horizon effects as the agent tries to optimize their decision making knowing that they have 10 realizations of demand.

Infinite horizon

We can remove the end-of-horizonn effects by considering an infinite horizon model. We assume a discount factor $\alpha=0.95$:

α = 0.95
 graph = SDDP.LinearGraph(2)
 SDDP.add_edge(graph, 2 => 2, α)
 graph
Root
@@ -167,32 +166,30 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1   3.261395e+05  4.629033e+04  1.603484e-02       253   1
-        40   8.223870e+05  3.110268e+05  1.056395e+00     14467   1
-        59   1.325037e+06  3.124707e+05  2.061967e+00     25175   1
-        82   1.487445e+06  3.126509e+05  3.163571e+00     36118   1
-       101   7.947975e+05  3.126628e+05  4.216599e+00     45335   1
-       126   4.517778e+05  3.126648e+05  5.298299e+00     54075   1
-       145   3.713553e+05  3.126650e+05  6.389154e+00     61633   1
-       160   5.611658e+05  3.126650e+05  7.436390e+00     67864   1
-       177   1.160661e+06  3.126650e+05  8.623258e+00     74454   1
-       186   2.550605e+05  3.126650e+05  9.682608e+00     79356   1
-       238   7.567026e+05  3.126650e+05  1.469167e+01    100345   1
-       270   7.641132e+05  3.126650e+05  1.983227e+01    114993   1
-       299   2.758605e+05  3.126650e+05  2.497983e+01    127391   1
-       316   5.273974e+05  3.126650e+05  3.041085e+01    137593   1
-       332   4.783868e+05  3.126650e+05  3.567293e+01    147101   1
-       349   6.081553e+05  3.126650e+05  4.075312e+01    154972   1
-       358   1.381797e+06  3.126650e+05  4.595205e+01    161680   1
-       373   8.825974e+05  3.126650e+05  5.139970e+01    168688   1
-       384   5.303447e+05  3.126650e+05  5.664452e+01    174915   1
-       400   8.032368e+04  3.126650e+05  6.061250e+01    179614   1
+         1   5.925000e+04  4.040190e+04  9.183168e-03       127   1
+        31   1.404778e+06  3.013109e+05  1.167548e+00     15655   1
+        52   1.019353e+05  3.118068e+05  2.167894e+00     26386   1
+        79   3.556378e+05  3.126211e+05  3.197883e+00     37207   1
+       102   1.127161e+06  3.126629e+05  4.355690e+00     48171   1
+       123   3.268071e+05  3.126649e+05  5.394886e+00     56634   1
+       139   7.257613e+04  3.126650e+05  6.402684e+00     64651   1
+       152   6.472711e+05  3.126650e+05  7.438318e+00     72455   1
+       167   2.473132e+05  3.126650e+05  8.447790e+00     79358   1
+       177   2.345974e+05  3.126650e+05  9.471624e+00     85794   1
+       226   9.373342e+05  3.126650e+05  1.448742e+01    112912   1
+       274   9.666395e+05  3.126650e+05  1.996113e+01    134611   1
+       306   5.097553e+05  3.126650e+05  2.514281e+01    151254   1
+       333   1.631026e+05  3.126650e+05  3.018784e+01    163230   1
+       363   1.145974e+05  3.126650e+05  3.527018e+01    173802   1
+       382   1.915658e+05  3.126650e+05  4.031261e+01    183355   1
+       399   1.344745e+06  3.126650e+05  4.644930e+01    192402   1
+       400   1.908921e+05  3.126650e+05  4.663174e+01    192655   1
 -------------------------------------------------------------------
 status         : iteration_limit
-total time (s) : 6.061250e+01
-total solves   : 179614
+total time (s) : 4.663174e+01
+total solves   : 192655
 best bound     :  3.126650e+05
-simulation ci  :  3.221874e+05 ± 2.709090e+04
+simulation ci  :  3.471375e+05 ± 3.227828e+04
 numeric issues : 0
 -------------------------------------------------------------------

Plot the optimal inventory levels:

plt = SDDP.publication_plot(
     simulations;
@@ -203,4 +200,4 @@
 ) do data
     return data[:x_inventory].out + data[:u_buy].out
 end
-Plots.hline!(plt, [662]; label = "Analytic solution")
Example block output

We again recover an order-up-to policy. The analytic solution is to order-up-to 662 units. We do not precisely recover this solution because we used a sample average approximation of 20 elements. If we increased the number of samples, our solution would approach the analytic solution.

+Plots.hline!(plt, [662]; label = "Analytic solution")Example block output

We again recover an order-up-to policy. The analytic solution is to order-up-to 662 units. We do not precisely recover this solution because we used a sample average approximation of 20 elements. If we increased the number of samples, our solution would approach the analytic solution.

diff --git a/previews/PR811/tutorial/markov_uncertainty/index.html b/previews/PR811/tutorial/markov_uncertainty/index.html index e80f9eae2..cc67729e5 100644 --- a/previews/PR811/tutorial/markov_uncertainty/index.html +++ b/previews/PR811/tutorial/markov_uncertainty/index.html @@ -85,14 +85,14 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 1.562500e+04 1.991887e+03 5.845070e-03 18 1 - 40 1.312500e+04 8.072917e+03 1.328571e-01 1320 1 + 1 2.812500e+04 1.991887e+03 5.608082e-03 18 1 + 40 1.250000e+04 8.072917e+03 1.342120e-01 1320 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 1.328571e-01 +total time (s) : 1.342120e-01 total solves : 1320 best bound : 8.072917e+03 -simulation ci : 9.055480e+03 ± 2.372164e+03 +simulation ci : 7.955223e+03 ± 2.209038e+03 numeric issues : 0 -------------------------------------------------------------------

Instead of performing a Monte Carlo simulation like the previous tutorials, we may want to simulate one particular sequence of noise realizations. This historical simulation can also be conducted by passing a SDDP.Historical sampling scheme to the sampling_scheme keyword of the SDDP.simulate function.

We can confirm that the historical sequence of nodes was visited by querying the :node_index key of the simulation results.

simulations = SDDP.simulate(
     model;
@@ -106,4 +106,4 @@
 [stage[:node_index] for stage in simulations[1]]
3-element Vector{Tuple{Int64, Int64}}:
  (1, 1)
  (2, 2)
- (3, 1)
+ (3, 1) diff --git a/previews/PR811/tutorial/mdps/index.html b/previews/PR811/tutorial/mdps/index.html index c12a2b8db..285f84c4f 100644 --- a/previews/PR811/tutorial/mdps/index.html +++ b/previews/PR811/tutorial/mdps/index.html @@ -61,11 +61,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 2.499895e+01 1.562631e+00 1.605582e-02 6 1 - 40 8.333333e+00 8.333333e+00 7.100549e-01 246 1 + 1 2.499895e+01 1.562631e+00 1.610589e-02 6 1 + 40 8.333333e+00 8.333333e+00 6.816051e-01 246 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.100549e-01 +total time (s) : 6.816051e-01 total solves : 246 best bound : 8.333333e+00 simulation ci : 8.810723e+00 ± 8.167195e-01 @@ -154,14 +154,14 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 0.000000e+00 1.000000e+01 1.208591e-02 35 1 - 40 9.000000e+00 6.561000e+00 7.349939e-01 2884 1 + 1 0.000000e+00 1.000000e+01 4.554033e-03 11 1 + 43 0.000000e+00 6.561000e+00 6.500010e-01 2729 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.349939e-01 -total solves : 2884 +total time (s) : 6.500010e-01 +total solves : 2729 best bound : 6.561000e+00 -simulation ci : 5.950000e+00 ± 3.334032e+00 +simulation ci : 3.953488e+00 ± 1.863137e+00 numeric issues : 0 -------------------------------------------------------------------

Simulating a cyclic policy graph requires an explicit sampling_scheme that does not terminate early based on the cycle probability:

simulations = SDDP.simulate(
     model,
@@ -179,4 +179,4 @@
 
 print(join([join(path[i, :], ' ') for i in 1:size(path, 1)], '\n'))
1 2 3 ⋅
 ⋅ ▩ 4 †
-† ⋅ 5 *
Tip

This formulation will likely struggle as the number of cells in the maze increases. Can you think of an equivalent formulation that uses fewer state variables?

+† ⋅ 5 *
Tip

This formulation will likely struggle as the number of cells in the maze increases. Can you think of an equivalent formulation that uses fewer state variables?

diff --git a/previews/PR811/tutorial/objective_states/index.html b/previews/PR811/tutorial/objective_states/index.html index 74daa289b..0f26c977a 100644 --- a/previews/PR811/tutorial/objective_states/index.html +++ b/previews/PR811/tutorial/objective_states/index.html @@ -79,24 +79,24 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 3.515625e+03 2.307692e+03 2.280307e-02 39 1 - 69 8.122500e+03 5.092593e+03 3.268039e-01 3591 1 + 1 1.856250e+03 3.792977e+03 2.103996e-02 39 1 + 75 2.578125e+03 5.092593e+03 3.317330e-01 3825 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 3.268039e-01 -total solves : 3591 +total time (s) : 3.317330e-01 +total solves : 3825 best bound : 5.092593e+03 -simulation ci : 5.045107e+03 ± 9.521140e+02 +simulation ci : 5.035567e+03 ± 8.906509e+02 numeric issues : 0 ------------------------------------------------------------------- Finished training and simulating.

To demonstrate how the objective states are updated, consider the sequence of noise observations:

[stage[:noise_term] for stage in simulations[1]]
3-element Vector{@NamedTuple{fuel::Float64, inflow::Float64}}:
- (fuel = 1.25, inflow = 50.0)
- (fuel = 1.25, inflow = 50.0)
- (fuel = 0.75, inflow = 50.0)

This, the fuel cost in the first stage should be 0.75 * 50 = 37.5. The fuel cost in the second stage should be 1.1 * 37.5 = 41.25. The fuel cost in the third stage should be 0.75 * 41.25 = 30.9375.

To confirm this, the values of the objective state in a simulation can be queried using the :objective_state key.

[stage[:objective_state] for stage in simulations[1]]
3-element Vector{Float64}:
- 62.5
- 78.125
- 58.59375

Multi-dimensional objective states

You can construct multi-dimensional price processes using NTuples. Just replace every scalar value associated with the objective state by a tuple. For example, initial_value = 1.0 becomes initial_value = (1.0, 2.0).

Here is an example:

model = SDDP.LinearPolicyGraph(;
+ (fuel = 0.9, inflow = 50.0)
+ (fuel = 1.1, inflow = 50.0)
+ (fuel = 0.75, inflow = 0.0)

This, the fuel cost in the first stage should be 0.75 * 50 = 37.5. The fuel cost in the second stage should be 1.1 * 37.5 = 41.25. The fuel cost in the third stage should be 0.75 * 41.25 = 30.9375.

To confirm this, the values of the objective state in a simulation can be queried using the :objective_state key.

[stage[:objective_state] for stage in simulations[1]]
3-element Vector{Float64}:
+ 45.0
+ 49.50000000000001
+ 37.12500000000001

Multi-dimensional objective states

You can construct multi-dimensional price processes using NTuples. Just replace every scalar value associated with the objective state by a tuple. For example, initial_value = 1.0 becomes initial_value = (1.0, 2.0).

Here is an example:

model = SDDP.LinearPolicyGraph(;
     stages = 3,
     sense = :Min,
     lower_bound = 0.0,
@@ -170,19 +170,19 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1   8.687500e+03  2.123386e+03  2.507806e-02        39   1
-       186   2.875000e+03  5.135984e+03  1.026699e+00      8754   1
-       288   1.237500e+04  5.135984e+03  1.520157e+00     13032   1
+         1   5.250000e+03  1.944444e+03  2.288103e-02        39   1
+       197   2.437500e+03  5.135984e+03  1.026698e+00      9483   1
+       286   3.187500e+03  5.135984e+03  1.389911e+00     12954   1
 -------------------------------------------------------------------
 status         : simulation_stopping
-total time (s) : 1.520157e+00
-total solves   : 13032
+total time (s) : 1.389911e+00
+total solves   : 12954
 best bound     :  5.135984e+03
-simulation ci  :  5.093300e+03 ± 4.706043e+02
+simulation ci  :  5.047210e+03 ± 4.909091e+02
 numeric issues : 0
 -------------------------------------------------------------------
 
 Finished training and simulating.

This time, since our objective state is two-dimensional, the objective states are tuples with two elements:

[stage[:objective_state] for stage in simulations[1]]
3-element Vector{Tuple{Float64, Float64}}:
- (55.0, 50.0)
- (52.5, 55.0)
- (61.25, 52.5)

Warnings

There are number of things to be aware of when using objective states.

  • The key assumption is that price is independent of the states and actions in the model.

    That means that the price cannot appear in any @constraints. Nor can you use any @variables in the update function.

  • Choosing an appropriate Lipschitz constant is difficult.

    The points discussed in Choosing an initial bound are relevant. The Lipschitz constant should not be chosen as large as possible (since this will help with convergence and the numerical issues discussed above), but if chosen to small, it may cut of the feasible region and lead to a sub-optimal solution.

  • You need to ensure that the cost-to-go function is concave with respect to the objective state before the update.

    If the update function is linear, this is always the case. In some situations, the update function can be nonlinear (e.g., multiplicative as we have above). In general, placing constraints on the price (e.g., clamp(price, 0, 1)) will destroy concavity. Caveat emptor. It's up to you if this is a problem. If it isn't you'll get a good heuristic with no guarantee of global optimality.

+ (45.0, 50.0) + (52.5, 45.0) + (61.25, 52.5)

Warnings

There are number of things to be aware of when using objective states.

  • The key assumption is that price is independent of the states and actions in the model.

    That means that the price cannot appear in any @constraints. Nor can you use any @variables in the update function.

  • Choosing an appropriate Lipschitz constant is difficult.

    The points discussed in Choosing an initial bound are relevant. The Lipschitz constant should not be chosen as large as possible (since this will help with convergence and the numerical issues discussed above), but if chosen to small, it may cut of the feasible region and lead to a sub-optimal solution.

  • You need to ensure that the cost-to-go function is concave with respect to the objective state before the update.

    If the update function is linear, this is always the case. In some situations, the update function can be nonlinear (e.g., multiplicative as we have above). In general, placing constraints on the price (e.g., clamp(price, 0, 1)) will destroy concavity. Caveat emptor. It's up to you if this is a problem. If it isn't you'll get a good heuristic with no guarantee of global optimality.

diff --git a/previews/PR811/tutorial/objective_uncertainty/index.html b/previews/PR811/tutorial/objective_uncertainty/index.html index 8812bceb5..dd61d917e 100644 --- a/previews/PR811/tutorial/objective_uncertainty/index.html +++ b/previews/PR811/tutorial/objective_uncertainty/index.html @@ -82,16 +82,16 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 5.625000e+04 3.958333e+03 3.849983e-03 12 1 - 40 5.000000e+03 1.062500e+04 7.199407e-02 642 1 + 1 1.875000e+04 3.958333e+03 3.413916e-03 12 1 + 40 1.875000e+03 1.062500e+04 6.562400e-02 642 1 ------------------------------------------------------------------- status : simulation_stopping -total time (s) : 7.199407e-02 +total time (s) : 6.562400e-02 total solves : 642 best bound : 1.062500e+04 -simulation ci : 1.144952e+04 ± 3.560509e+03 +simulation ci : 1.192119e+04 ± 2.615892e+03 numeric issues : 0 ------------------------------------------------------------------- -Confidence interval: 10225.0 ± 719.88 -Lower bound: 10625.0 +Confidence interval: 11120.0 ± 762.77 +Lower bound: 10625.0 diff --git a/previews/PR811/tutorial/pglib_opf/index.html b/previews/PR811/tutorial/pglib_opf/index.html index 9141132b2..f65364303 100644 --- a/previews/PR811/tutorial/pglib_opf/index.html +++ b/previews/PR811/tutorial/pglib_opf/index.html @@ -61,24 +61,24 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 8.739943e+04 8.392522e+04 1.107059e-01 23 1 - 4 8.366643e+05 1.610511e+05 1.459596e+00 244 1 - 6 5.727988e+05 3.666291e+05 2.661353e+00 446 1 - 10 5.935476e+05 3.934937e+05 3.845967e+00 630 1 + 1 1.060565e+07 4.875069e+04 6.346560e-01 187 1 + 4 4.933798e+05 3.565300e+05 1.900154e+00 420 1 + 7 1.614108e+06 3.925867e+05 3.791182e+00 729 1 + 10 6.561330e+05 4.110306e+05 4.558589e+00 842 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 3.845967e+00 -total solves : 630 -best bound : 3.934937e+05 -simulation ci : 5.365945e+05 ± 2.532734e+05 +total time (s) : 4.558589e+00 +total solves : 842 +best bound : 4.110306e+05 +simulation ci : 1.610035e+06 ± 1.988407e+06 numeric issues : 0 -------------------------------------------------------------------

To more accurately simulate the dynamics of the problem, a common approach is to write the cuts representing the policy to a file, and then read them into a non-convex model:

SDDP.write_cuts_to_file(convex, "convex.cuts.json")
 non_convex = build_model(PowerModels.ACPPowerModel)
 SDDP.read_cuts_from_file(non_convex, "convex.cuts.json")

Now we can simulate non_convex to evaluate the policy.

result = SDDP.simulate(non_convex, 1)
1-element Vector{Vector{Dict{Symbol, Any}}}:
- [Dict(:bellman_term => 371699.15494089026, :noise_term => 5, :node_index => 1, :stage_objective => 17580.118673456385, :objective_state => nothing, :belief => Dict(1 => 1.0))]

A problem with reading and writing the cuts to file is that the cuts have been generated from trial points of the convex model. Therefore, the policy may be arbitrarily bad at points visited by the non-convex model.

Training a non-convex model

We can also build and train a non-convex formulation of the optimal power flow problem.

The problem with the non-convex model is that because it is non-convex, SDDP.jl may find a sub-optimal policy. Therefore, it may over-estimate the true cost of operation.

non_convex = build_model(PowerModels.ACPPowerModel)
+ [Dict(:bellman_term => 397348.8632319851, :noise_term => 0, :node_index => 1, :stage_objective => 17579.697029811745, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 396830.06813583785, :noise_term => 5, :node_index => 1, :stage_objective => 17579.69702963712, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.75727644213, :noise_term => 0, :node_index => 1, :stage_objective => 20433.585286405298, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 401533.9621711968, :noise_term => 5, :node_index => 1, :stage_objective => 17579.697038463684, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.75735986745, :noise_term => 2, :node_index => 1, :stage_objective => 22628.221454460712, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 427786.8126528796, :noise_term => 0, :node_index => 1, :stage_objective => 27420.55350180487, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.7573600904, :noise_term => 2, :node_index => 1, :stage_objective => 25694.765161760122, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 427786.81265798234, :noise_term => 0, :node_index => 1, :stage_objective => 27420.55350180487, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.75727231696, :noise_term => 5, :node_index => 1, :stage_objective => 18341.12085144961, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.75735993707, :noise_term => 2, :node_index => 1, :stage_objective => 23580.69729536841, :objective_state => nothing, :belief => Dict(1 => 1.0))  …  Dict(:bellman_term => 427786.81265447376, :noise_term => 0, :node_index => 1, :stage_objective => 27420.55350180487, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.75727231696, :noise_term => 5, :node_index => 1, :stage_objective => 18341.12085127002, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.75735993707, :noise_term => 2, :node_index => 1, :stage_objective => 23580.69729536841, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 401533.96225390973, :noise_term => 5, :node_index => 1, :stage_objective => 17579.69703846368, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 401015.16715311626, :noise_term => 5, :node_index => 1, :stage_objective => 17579.697034283643, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 404487.48182884674, :noise_term => 0, :node_index => 1, :stage_objective => 27420.553501466715, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 430444.8576045284, :noise_term => 0, :node_index => 1, :stage_objective => 27420.553501811708, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402052.7573601053, :noise_term => 2, :node_index => 1, :stage_objective => 25901.01525014339, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 401533.96225407196, :noise_term => 5, :node_index => 1, :stage_objective => 17579.697038463666, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 415763.5481330753, :noise_term => 0, :node_index => 1, :stage_objective => 27420.553501474962, :objective_state => nothing, :belief => Dict(1 => 1.0))]

A problem with reading and writing the cuts to file is that the cuts have been generated from trial points of the convex model. Therefore, the policy may be arbitrarily bad at points visited by the non-convex model.

Training a non-convex model

We can also build and train a non-convex formulation of the optimal power flow problem.

The problem with the non-convex model is that because it is non-convex, SDDP.jl may find a sub-optimal policy. Therefore, it may over-estimate the true cost of operation.

non_convex = build_model(PowerModels.ACPPowerModel)
 SDDP.train(non_convex; iteration_limit = 10)
 result = SDDP.simulate(non_convex, 1)
1-element Vector{Vector{Dict{Symbol, Any}}}:
- [Dict(:bellman_term => 389924.15247613343, :noise_term => 2, :node_index => 1, :stage_objective => 21433.37404767218, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 395415.31976751, :noise_term => 0, :node_index => 1, :stage_objective => 21433.374047672358, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 400906.4870588859, :noise_term => 0, :node_index => 1, :stage_objective => 21433.374047673216, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 405874.3773738785, :noise_term => 0, :node_index => 1, :stage_objective => 22203.182996831845, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 405874.37737412285, :noise_term => 2, :node_index => 1, :stage_objective => 23580.697454502428, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 401284.0376122276, :noise_term => 5, :node_index => 1, :stage_objective => 21433.374047673333, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 405874.3773739774, :noise_term => 0, :node_index => 1, :stage_objective => 22759.004411022546, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 405874.3773741229, :noise_term => 2, :node_index => 1, :stage_objective => 23580.697454647583, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 401284.0376122276, :noise_term => 5, :node_index => 1, :stage_objective => 21433.374047673333, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 396693.69785056135, :noise_term => 5, :node_index => 1, :stage_objective => 21433.374047672543, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402184.86514193675, :noise_term => 0, :node_index => 1, :stage_objective => 21433.374047673653, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 397594.5253802702, :noise_term => 5, :node_index => 1, :stage_objective => 21433.37404767258, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 403085.6926716453, :noise_term => 0, :node_index => 1, :stage_objective => 21433.374047674173, :objective_state => nothing, :belief => Dict(1 => 1.0))]

Combining convex and non-convex models

To summarize, training with the convex model constructs cuts at points that may never be visited by the non-convex model, and training with the non-convex model may construct arbitrarily poor cuts because a key assumption of SDDP is convexity.

As a compromise, we can train a policy using a combination of the convex and non-convex models; we'll use the non-convex model to generate trial points on the forward pass, and we'll use the convex model to build cuts on the backward pass.

convex = build_model(PowerModels.DCPPowerModel)
A policy graph with 1 nodes.
+ [Dict(:bellman_term => 402971.566820766, :noise_term => 0, :node_index => 1, :stage_objective => 21433.375017898394, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 398256.41456800274, :noise_term => 5, :node_index => 1, :stage_objective => 21433.375017898343, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 403896.8858505682, :noise_term => 0, :node_index => 1, :stage_objective => 21433.37501789844, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 405395.10771900206, :noise_term => 2, :node_index => 1, :stage_objective => 21433.375017898452, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 400679.9554662386, :noise_term => 5, :node_index => 1, :stage_objective => 21433.375017898285, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402178.1773346726, :noise_term => 2, :node_index => 1, :stage_objective => 21433.375017898386, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 403676.3992031065, :noise_term => 2, :node_index => 1, :stage_objective => 21433.37501789845, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 398961.2469503432, :noise_term => 5, :node_index => 1, :stage_objective => 21433.37501789835, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 400459.46881877724, :noise_term => 2, :node_index => 1, :stage_objective => 21433.375017898365, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 401957.6906872111, :noise_term => 2, :node_index => 1, :stage_objective => 21433.37501789838, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 407598.1619697765, :noise_term => 0, :node_index => 1, :stage_objective => 21433.375017898517, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 402883.00971701316, :noise_term => 5, :node_index => 1, :stage_objective => 21433.3750178984, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 398167.8574642498, :noise_term => 5, :node_index => 1, :stage_objective => 21433.37501789835, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 393452.70521148655, :noise_term => 5, :node_index => 1, :stage_objective => 21433.375017898317, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 388737.5529587234, :noise_term => 5, :node_index => 1, :stage_objective => 21433.375017898292, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 390235.77482715726, :noise_term => 2, :node_index => 1, :stage_objective => 21433.37501789827, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 395876.24610972276, :noise_term => 0, :node_index => 1, :stage_objective => 21433.3750178983, :objective_state => nothing, :belief => Dict(1 => 1.0)), Dict(:bellman_term => 397374.46797815664, :noise_term => 2, :node_index => 1, :stage_objective => 21433.375017898314, :objective_state => nothing, :belief => Dict(1 => 1.0))]

Combining convex and non-convex models

To summarize, training with the convex model constructs cuts at points that may never be visited by the non-convex model, and training with the non-convex model may construct arbitrarily poor cuts because a key assumption of SDDP is convexity.

As a compromise, we can train a policy using a combination of the convex and non-convex models; we'll use the non-convex model to generate trial points on the forward pass, and we'll use the convex model to build cuts on the backward pass.

convex = build_model(PowerModels.DCPPowerModel)
A policy graph with 1 nodes.
  Node indices: 1
 
non_convex = build_model(PowerModels.ACPPowerModel)
A policy graph with 1 nodes.
  Node indices: 1
@@ -113,16 +113,16 @@
 -------------------------------------------------------------------
  iteration    simulation      bound        time (s)     solves  pid
 -------------------------------------------------------------------
-         1   1.051620e+06  1.018342e+05  2.495060e-01        36   1
-         3   2.811369e+05  2.192570e+05  1.461578e+00       156   1
-         5   1.148674e+05  2.465873e+05  2.556314e+00       270   1
-         6   7.866119e+05  3.728553e+05  3.877495e+00       375   1
-        10   1.761483e+04  3.911610e+05  4.789682e+00       465   1
+         1   3.510376e+04  4.945735e+04  5.675817e-02         9   1
+         3   7.173198e+05  1.184728e+05  1.626347e+00       183   1
+         6   1.089690e+05  3.415483e+05  2.661640e+00       285   1
+         7   3.504677e+06  3.623161e+05  4.114105e+00       435   1
+        10   7.135552e+05  3.966804e+05  5.825555e+00       609   1
 -------------------------------------------------------------------
 status         : iteration_limit
-total time (s) : 4.789682e+00
-total solves   : 465
-best bound     :  3.911610e+05
-simulation ci  :  4.427065e+05 ± 2.573449e+05
+total time (s) : 5.825555e+00
+total solves   : 609
+best bound     :  3.966804e+05
+simulation ci  :  1.157820e+06 ± 1.092722e+06
 numeric issues : 0
--------------------------------------------------------------------

In practice, if we were to simulate non_convex now, we should obtain a better policy than either of the two previous approaches.

+-------------------------------------------------------------------

In practice, if we were to simulate non_convex now, we should obtain a better policy than either of the two previous approaches.

diff --git a/previews/PR811/tutorial/plotting/eafa3194.svg b/previews/PR811/tutorial/plotting/ebe920f6.svg similarity index 84% rename from previews/PR811/tutorial/plotting/eafa3194.svg rename to previews/PR811/tutorial/plotting/ebe920f6.svg index 248c0228c..8f71a7a99 100644 --- a/previews/PR811/tutorial/plotting/eafa3194.svg +++ b/previews/PR811/tutorial/plotting/ebe920f6.svg @@ -1,84 +1,84 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR811/tutorial/plotting/index.html b/previews/PR811/tutorial/plotting/index.html index 3b44c8cac..53f697982 100644 --- a/previews/PR811/tutorial/plotting/index.html +++ b/previews/PR811/tutorial/plotting/index.html @@ -76,14 +76,14 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 4.375000e+04 1.991887e+03 1.675916e-02 18 1 - 20 1.875000e+03 8.072917e+03 5.456901e-02 360 1 + 1 1.875000e+04 1.991887e+03 1.411796e-02 18 1 + 20 1.875000e+03 8.072917e+03 4.841495e-02 360 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 5.456901e-02 +total time (s) : 4.841495e-02 total solves : 360 best bound : 8.072917e+03 -simulation ci : 9.822043e+03 ± 4.952850e+03 +simulation ci : 7.710737e+03 ± 3.157375e+03 numeric issues : 0 ------------------------------------------------------------------- @@ -106,4 +106,4 @@ xlabel = "Stage", ylims = (0, 200), layout = (1, 2), -)Example block output

You can save this plot as a PDF using the Plots.jl function savefig:

Plots.savefig("my_picture.pdf")

Plotting the value function

You can obtain an object representing the value function of a node using SDDP.ValueFunction.

V = SDDP.ValueFunction(model[(1, 1)])
A value function for node (1, 1)

The value function can be evaluated using SDDP.evaluate.

SDDP.evaluate(V; volume = 1)
(23019.270833333332, Dict(:volume => -157.8125))

evaluate returns the height of the value function, and a subgradient with respect to the convex state variables.

You can also plot the value function using SDDP.plot

SDDP.plot(V, volume = 0:200, filename = "value_function.html")

This should open a webpage that looks like this one.

Convergence dashboard

If the text-based logging isn't to your liking, you can open a visualization of the training by passing dashboard = true to SDDP.train.

SDDP.train(model; dashboard = true)

By default, dashboard = false because there is an initial overhead associated with opening and preparing the plot.

Warning

The dashboard is experimental. There are known bugs associated with it, e.g., SDDP.jl#226.

+)Example block output

You can save this plot as a PDF using the Plots.jl function savefig:

Plots.savefig("my_picture.pdf")

Plotting the value function

You can obtain an object representing the value function of a node using SDDP.ValueFunction.

V = SDDP.ValueFunction(model[(1, 1)])
A value function for node (1, 1)

The value function can be evaluated using SDDP.evaluate.

SDDP.evaluate(V; volume = 1)
(23019.270833333332, Dict(:volume => -157.8125))

evaluate returns the height of the value function, and a subgradient with respect to the convex state variables.

You can also plot the value function using SDDP.plot

SDDP.plot(V, volume = 0:200, filename = "value_function.html")

This should open a webpage that looks like this one.

Convergence dashboard

If the text-based logging isn't to your liking, you can open a visualization of the training by passing dashboard = true to SDDP.train.

SDDP.train(model; dashboard = true)

By default, dashboard = false because there is an initial overhead associated with opening and preparing the plot.

Warning

The dashboard is experimental. There are known bugs associated with it, e.g., SDDP.jl#226.

diff --git a/previews/PR811/tutorial/spaghetti_plot.html b/previews/PR811/tutorial/spaghetti_plot.html index ee6029af2..e5d7f64fe 100644 --- a/previews/PR811/tutorial/spaghetti_plot.html +++ b/previews/PR811/tutorial/spaghetti_plot.html @@ -230,7 +230,7 @@
diff --git a/previews/PR811/tutorial/warnings/index.html b/previews/PR811/tutorial/warnings/index.html index c25cdf9fc..f23811c5c 100644 --- a/previews/PR811/tutorial/warnings/index.html +++ b/previews/PR811/tutorial/warnings/index.html @@ -89,11 +89,11 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 6.500000e+00 3.000000e+00 3.309965e-03 6 1 - 5 3.500000e+00 3.500000e+00 6.183863e-03 30 1 + 1 6.500000e+00 3.000000e+00 3.022909e-03 6 1 + 5 3.500000e+00 3.500000e+00 5.645990e-03 30 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 6.183863e-03 +total time (s) : 5.645990e-03 total solves : 30 best bound : 3.500000e+00 simulation ci : 4.100000e+00 ± 1.176000e+00 @@ -134,13 +134,13 @@ ------------------------------------------------------------------- iteration simulation bound time (s) solves pid ------------------------------------------------------------------- - 1 6.500000e+00 1.100000e+01 3.236055e-03 6 1 - 5 5.500000e+00 1.100000e+01 5.764008e-03 30 1 + 1 6.500000e+00 1.100000e+01 3.062963e-03 6 1 + 5 5.500000e+00 1.100000e+01 5.445957e-03 30 1 ------------------------------------------------------------------- status : iteration_limit -total time (s) : 5.764008e-03 +total time (s) : 5.445957e-03 total solves : 30 best bound : 1.100000e+01 simulation ci : 5.700000e+00 ± 3.920000e-01 numeric issues : 0 --------------------------------------------------------------------

How do we tell which is more appropriate? There are a few clues that you should look out for.

  • The bound converges to a value above (if minimizing) the simulated cost of the policy. In this case, the problem is deterministic, so it is easy to tell. But you can also check by performing a Monte Carlo simulation like we did in An introduction to SDDP.jl.

  • The bound converges to different values when we change the bound. This is another clear give-away. The bound provided by the user is only used in the initial iterations. It should not change the value of the converged policy. Thus, if you don't know an appropriate value for the bound, choose an initial value, and then increase (or decrease) the value of the bound to confirm that the value of the policy doesn't change.

  • The bound converges to a value close to the bound provided by the user. This varies between models, but notice that 11.0 is quite close to 10.0 compared with 3.5 and 0.0.

+-------------------------------------------------------------------

How do we tell which is more appropriate? There are a few clues that you should look out for.

  • The bound converges to a value above (if minimizing) the simulated cost of the policy. In this case, the problem is deterministic, so it is easy to tell. But you can also check by performing a Monte Carlo simulation like we did in An introduction to SDDP.jl.

  • The bound converges to different values when we change the bound. This is another clear give-away. The bound provided by the user is only used in the initial iterations. It should not change the value of the converged policy. Thus, if you don't know an appropriate value for the bound, choose an initial value, and then increase (or decrease) the value of the bound to confirm that the value of the policy doesn't change.

  • The bound converges to a value close to the bound provided by the user. This varies between models, but notice that 11.0 is quite close to 10.0 compared with 3.5 and 0.0.