Demonstration of rapper Capabilities¶
In this section we provide a series of examples intended to show different things that can be done with rapper.
Imports:
>>> import pyomo.pysp.util.rapper as rapper
>>> import pyomo.pysp.plugins.csvsolutionwriter as csvw
>>> from pyomo.pysp.scenariotree.tree_structure_model import CreateAbstractScenarioTreeModel
>>> import pyomo.environ as pyo
The next line establishes the solver to be used.
>>> solvername = "cplex"
The next two lines show one way to create a concrete scenario tree. There are
others that can be found in `pyomo.pysp.scenariotree.tree_structure_model`.
>>> abstract_tree = CreateAbstractScenarioTreeModel()
>>> concrete_tree = \
... abstract_tree.create_instance("ScenarioStructure.dat")
Emulate some aspects of runef¶
Create a rapper solver object assuming there is a file named ReferenceModel.py that has an appropriate pysp_instance_creation_callback function.
>>> stsolver = rapper.StochSolver("ReferenceModel.py", ... tree_model = concrete_tree)This object has a solve_ef method (as well as a solve_ph method)
>>> ef_sol = stsolver.solve_ef(solvername)The return status from the solver can be tested.
>>> if ef_sol.solver.termination_condition != \ ... pyo.TerminationCondition.optimal: ... print ("oops! not optimal:",ef_sol.solver.termination_condition)There is an iterator to loop over the root node solution:
>>> for varname, varval in stsolver.root_Var_solution(): ... print (varname, str(varval))There is also a function to compute compute the objective function value.
>>> obj = stsolver.root_E_obj() >>> print ("Expecatation take over scenarios=", obj)Also, stsolver.scenario_tree has the solution. The package csvw is imported from PySP as shown above.
>>> csvw.write_csv_soln(stsolver.scenario_tree, "testcref")It is also possible to add arguments for chance constraints and CVaR; see rapper API for details.
Again, but with mip gap reported¶
Now we will solve the same problem again, but we cannot re-use the same rapper.StochSolver object in the same program so we must construct a new one; however, we can re-used the scenario tree.
>>> stsolver = rapper.StochSolver("ReferenceModel.py", ... tree_model = concrete_tree)We add a solver option to get the mip gap
>>> sopts = {"mipgap": 1} # I want a gapand we add the option to solve_ef to return the gap and the tee option to see the solver output as well.
>>> res, gap = stsolver.solve_ef(solvername, sopts = sopts, tee=True, need_gap = True) >>> print ("ef gap=",gap)
PH¶
We will now do the same problem, but with PH and we will re-use the scenario tree in tree_model from the code above. We put sub-solver options in sopts and PH options (i.e., those that would provided to runph) Note that if options are passed to the constructor (and the solver); they are passed as a dictionary where options that do not have an argument have the data value None. The constructor really only needs to some options, such as those related to bundling.
>>> sopts = {} >>> sopts['threads'] = 2 >>> phopts = {} >>> phopts['--output-solver-log'] = None >>> phopts['--max-iterations'] = '3'>>> stsolver = rapper.StochSolver("ReferenceModel.py", ... tree_model = concrete_tree, ... phopts = phopts)The solve_ph method is similar to solve_ef, but requires a default_rho and accepts PH options:
>>> ph = stsolver.solve_ph(subsolver = solvername, default_rho = 1, ... phopts=phopts)With PH, it is important to be careful to distinguish x-bar from x-hat.
>>> obj = stsolver.root_E_obj()We can compute and x-hat (using the current PH options):
>>> obj, xhat = rapper.xhat_from_ph(ph)There is a utility for obtaining the x-hat values:
>>> for nodename, varname, varvalue in rapper.xhat_walker(xhat): ... print (nodename, varname, varvalue)