diff --git a/doc/source/conf.py b/doc/source/conf.py index f4a901dc9..e2482f1b1 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -15,7 +15,9 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ["breathe", "sphinx.ext.mathjax", "sphinx.ext.graphviz"] +extensions = ["breathe", + "sphinx.ext.mathjax", "sphinx.ext.graphviz", + "sphinx_tabs.tabs"] # Configure Breathe. # When building with CMake, the path to doxyxml is passed via the command line. diff --git a/doc/source/images/ref_explore.png b/doc/source/images/ref_explore.png new file mode 100644 index 000000000..df4201ad7 Binary files /dev/null and b/doc/source/images/ref_explore.png differ diff --git a/doc/source/index.rst b/doc/source/index.rst index 112b66b4b..6527f6a0a 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -3,10 +3,14 @@ MP library ============ MP library is a set of solver drivers and tools recommended to create +and use with new AMPL solver drivers. It provides type-safe and flexible interfaces suitable for linear and mixed-integer, non-linear, and Constraint Programming solvers. +MP provides supporting tools, such as a +:ref:`Model reformulation explorer `. + Moreover, MP library provides a :ref:`lightweight NL writer `. diff --git a/doc/source/modeling-tools.rst b/doc/source/modeling-tools.rst index ab8a3b417..ad65eef58 100644 --- a/doc/source/modeling-tools.rst +++ b/doc/source/modeling-tools.rst @@ -59,7 +59,7 @@ the following ways. .. _explore-final-model: -Explore the final model +Export the solver model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To explore the model received by the solver, @@ -81,16 +81,151 @@ Some solvers can export their presolved model: .. _reformulation-graph: -Reformulation graph +Reformulation explorer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The flattening and reformulation graph can be exported -by the ``cvt:writegraph`` option (WIP). +MP provides a tool to explore and compare the model +provided to an MP solver driver in the NL file, and the final model +sent to the underlying solver. -At the moment only arcs are exported. Terminal nodes (variables, constraints, -objectives) can be seen in the NL model (ampl: ``expand``) and the -final flat model (gurobi: option ``tech:writeprob``). +.. image:: images/ref_explore.png + :width: 400 + :align: center + :alt: Reformulation explorer interface +Tool invocation +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the reformulation explorer online, go to http://ampl.com/streamlit. + +To run locally, download the `MP repository `_. +In subfolder `support/modelexplore`, run the command:: + + streamlit run modelexplore.py + + +Using the explorer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To produce the input data for the tool, containing the reformulations, +run an MP solver with the `writegraph` option, as follows. + +.. tabs:: + + .. tab:: AMPL + + .. code-block:: ampl + + ampl: option solver gurobi; # select solver + ampl: option gurobi_auxfiles rc; # write var/con names + ampl: option gurobi_options 'writegraph=model.jsonl lim:time=0'; + ampl: solve; # solve the problem + + .. tab:: Python + + How to install using `amplpy `_: + + .. code-block:: bash + + # Install Python API for AMPL: + $ python -m pip install amplpy --upgrade + + # Install AMPL & solver modules: + $ python -m amplpy.modules install gurobi # install Gurobi + + # Activate your license (e.g., free ampl.com/ce or ampl.com/courses licenses): + $ python -m amplpy.modules activate + + How to use: + + .. code-block:: python + + from amplpy import AMPL + ampl = AMPL() + ... + ampl.set_option("gurobi_auxfiles", "rc") + ampl.solve(solver="gurobi", gurobi_options="writegraph=graph.jsonl") + + Learn more about what we have to offer to implement and deploy `Optimization in Python `_. + + .. tab:: Other APIs + + `AMPL APIs `_ are interfaces + that allow developers to access the features of the AMPL interpreter + from within a programming language. We have APIs available for: + + - `Python `_ + - `R `_ + - `C++ `_ + - `C#/.NET `_ + - `Java `_ + - `MATLAB `_ + + .. tab:: Command line + + .. code-block:: bash + + auxfiles=rc ampl -obmodel model.mod data.dat + gurobi model.nl writegraph=reformulations.jsonl lim:time=0 + + +In the Explorer, upload the JSONL file. The NL (source) and solver's +(destination) models are displayed. + +.. note:: + The NL model displayed in most cases coincides + with the output of AMPL's `solexpand` command. + + The solver model is equivalent to the solver's exported model + via the `tech:writeprob` option. + +The following operations are possible: + +- *Search for a text pattern*. To display the subsets of the models + containing a certain name, enter that in the 'Search pattern' field. + +- *Download (subsets of) the models*. To download currently + displayed (sub)models, use the download buttons. + + +Example +~~~~~~~~~~~~~~~~~~~~~ + +Consider the following AMPL model. + +.. code-block:: ampl + + var x binary; + var y binary; + var z binary; + minimize TotalSum: z + 1; + subj to C1: x+y >= 1; + subj to C2: x^2+y^2+(z-0.7)^2 <= 1.83; + subj to C3: z==1 ==> x-y <= 2; + +To see the reformulations applied to constraint `C3`, +download the corresponding JSONL file in the Explorer +and enter `C3` in the 'Search pattern' field. For Gurobi, +the resulting subset of the Solver model can be as follows: + +.. code-block:: ampl + + ## Variables (3) + var C3 binary; + var C3_3_ binary; + var C3_5_ = 1; + + ## Constraints '_indle' (1) + C3_4_: C3_3_==1 ==> (1*x - 1*y <= 2); + + ## Constraints '_lineq' (1) + C3_2_: 1*z - 1*C3 == -1; + + ## Constraints '_or' (1) + C3_6_: C3_5_ == OrConstraint([C3, C3_3_], []); + +The constraint types (`_indle`, `_or`, etc.) are as explained +in :ref:`supported-constraints`. .. _solution-check: diff --git a/doc/source/requirements.txt b/doc/source/requirements.txt index 188f51e62..5a43efe0f 100644 --- a/doc/source/requirements.txt +++ b/doc/source/requirements.txt @@ -1 +1,2 @@ -breathe \ No newline at end of file +breathe +sphinx-tabs diff --git a/support/modelexplore/scripts/python/modelreader.py b/support/modelexplore/scripts/python/modelreader.py index 6cb86da44..985b1c352 100644 --- a/support/modelexplore/scripts/python/modelreader.py +++ b/support/modelexplore/scripts/python/modelreader.py @@ -3,8 +3,6 @@ # if __name__ == "__main__": # pass -import streamlit as st - import json from scripts.python.model import Model