Solving the Extensive Form
When we refer to “solving the EF” we mean passing the extensive form in its entirety directly to a general-purpose solver (as opposed to decomposition).
The simplest way to solve the EF is via generic_cylinders.py with the
--EF flag:
python -m mpisppy.generic_cylinders --module-name farmer --num-scens 3 \
--EF --EF-solver-name gurobi
See generic_cylinders.py for full details on EF-related command-line options.
mpisppy.opt.ef.ExtensiveForm Class
For developers who need programmatic access, there is a class for the EF that roughly matches the “look and feel” of a hub class, but does not function as a hub.
- class mpisppy.opt.ef.ExtensiveForm(options, all_scenario_names, scenario_creator, scenario_creator_kwargs=None, all_nodenames=None, model_name=None, suppress_warnings=False, extensions=None, extension_kwargs=None)[source]
Bases:
SPBaseCreate and solve an extensive form.
- ef
Pyomo model of the extensive form.
- Type:
pyomo.environ.ConcreteModel
- solver
Solver produced by the Pyomo solver factory.
- Parameters:
options (dict) – Dictionary of options. May include a solver key to specify which solver name to use on the EF.
all_scenario_names (list) – List of the names of each scenario in the EF (strings).
scenario_creator (callable) – Scenario creator function, which takes as input a scenario name, and returns a Pyomo model of that scenario.
scenario_creator_kwargs (dict, optional) – Keyword arguments passed to scenario_creator.
all_nodenames (list, optional) – List of all node names, incl. leaves. Can be None for two-stage problem.
model_name (str, optional) – Name of the resulting EF model object.
suppress_warnings (bool, optional) – Boolean to suppress warnings when building the EF. Default is False.
Note: allowing use of the “solver” option key is for backward compatibility
- get_objective_value()[source]
Retrieve the objective value.
- Returns:
Objective value.
- Return type:
float
- Raises:
ValueError – If optimal objective value could not be retrieved.
- get_root_solution()[source]
Get the value of the variables at the root node.
- Returns:
Dictionary mapping variable name (str) to variable value (float) for all variables at the root node.
- Return type:
dict
- nonants()[source]
An iterator to give representative Vars subject to non-anticipitivity Args: None
- Yields:
tree node name, full EF Var name, Var value
- nonants_to_csv(filename)[source]
Dump the nonant vars from an ef to a csv file; truly a dump… :param filename: the full name of the csv output file :type filename: str
- scenarios()[source]
An iterator to give the scenario sub-models in an ef Args: None
- Yields:
scenario name, scenario instance (str, ConcreteModel)
- solve_extensive_form(solver_options=None, tee=False)[source]
Solve the extensive form.
- Parameters:
solver_options (dict, optional) – Dictionary of solver-specific options (e.g. Gurobi options, CPLEX options, etc.).
tee (bool, optional) – If True, displays solver output. Default False.
- Returns:
Result returned by the Pyomo solve method.
- Return type:
pyomo.opt.results.results_.SolverResults
EF Extensions
The ExtensiveForm class supports extensions via the extensions and
extension_kwargs constructor arguments. EF extensions inherit from
mpisppy.extensions.extension.EFExtension and can override two hooks:
pre_solve(): called after EF creation, before passing the model to the solver.post_solve(results): called after the solver returns; must return results.
When using generic_cylinders.py, extensions are injected by defining an
ef_dict_callback(ef_dict, cfg) function in the model module. This callback
can modify ef_dict to add extensions before the EF is solved. Use
cfg_vanilla.ef_extension_adder(ef_dict, ext_class) to add extension classes
(multiple extensions are handled automatically via EFMultiExtension).
See examples/farmer/farmer_ef_ext.py for a complete example that adds
a minimum expected wheat production constraint to the EF.
Other method: mpisppy.utils.sputils.create_EF
The use of this function does not require the installation of mpi4py. Its use
is illustrated in examples.farmer.CI.farmer_ef.py. Here are the
arguments to the function:
- mpisppy.utils.sputils.create_EF(scenario_names, scenario_creator, scenario_creator_kwargs=None, EF_name=None, suppress_warnings=False, nonant_for_fixed_vars=True, total_number_of_scenarios=None)[source]
Create a ConcreteModel of the extensive form.
- Parameters:
scenario_names (list of str) – Names for each scenario to be passed to the scenario_creator function.
scenario_creator (callable) – Function which takes a scenario name as its first argument and returns a concrete model corresponding to that scenario.
scenario_creator_kwargs (dict, optional) – Options to pass to scenario_creator.
EF_name (str, optional) – Name of the ConcreteModel of the EF.
suppress_warnings (boolean, optional) – If true, do not display warnings. Default False.
nonant_for_fixed_vars (bool--optional) – If True, enforces non-anticipativity constraints for all variables, including those which have been fixed. Default is True.
total_number_of_scenarios (int, optional) – For calculating uniform probabilities, the total number of scenarios.
- Returns:
ConcreteModel of extensive form with explicit non-anticipativity constraints.
- Return type:
EF_instance (ConcreteModel)
Note
If any of the scenarios produced by scenario_creator do not have a ._mpisppy_probability attribute, this function displays a warning, and assumes that all scenarios are equally likely.