


\chapter{The Coopr Optimization Package}

\section{The Coopr Optimization Package}
\label{sec:opt}

Much of Pyomo's flexibility and extensibility is due to the fact that
Pyomo is integrated into Coopr, a COmmon Optimization Python Repository.
Coopr utilizes a component architecture to provide plugins that modularize
many aspects of the optimization process.  This includes components
that manage the execution of optimizers, which enables transparent
parallelization of independent optimization tasks.  This component
architecture also supports a generic optimization process.  Finally,
Coopr provides a simple installation mechanism that leverage's Python's
online package index.


\subsection{Optimization Plugins}

Coopr uses plugin components to modularize the steps needed to perform
optimization.  A component is a software package, module, or object
that provides a particular functionality.  Plugin components augment
the execution flow by implementing functionality that is exercised
``on demand.''  Component-based software with plugins is a best
practice for extend and evolve complex software systems in a reliable
manner~\citep{DDJ}.  Component-based software frameworks manage the
interaction between components to promote adaptability, scalability and
maintainability in large software systems~\citep{Szy98}.  For example,
with component-based software there is much less need for major release
changes because software changes can be encapsulated within individual
components.  Component architectures also encourage third-party developers
to add value to software systems without risk of destabilizing the core
functionality.

Coopr uses the PyUtilib plugin framework~\citep{PyUtilib} to define interfaces for the following plugin components:
\begin{itemize}
\item solvers, which perform optimization
\item solver managers, which manage the execution of solver plugins
\item converters, which translate between different optimization problem file formats
\item solution readers, which load optimization solutions from files
\item problem writers, which create files that contain optimization problems
\end{itemize}
Coopr also contains Pyomo-specific components for preprocessing Pyomo models
before they are solved.  

Coopr includes a variety of plugins that implement these component
interfaces, many of which rely on third-party software packages to
implement key functionality.  For example, solver plugins are available
for the CPLEX, CBC, PICO and GLPK mixed-integer linear programming
solvers.  These plugins naturally rely on the availability of binary
executables for these solvers, which need to be installed separately.
Similarly, Coopr includes plugins that convert between different
optimization problem file formats, which rely on binary executables
built by the GLPK~\citep{GLPK} and Acro~\citep{ACRO} software libraries.

Taken together, plugins provide the following capabilities that simplify optimization within Pyomo:
\begin{itemize}

\item {\bf Dynamic Registration of Optimizers}: Optimizers are registered
as plugins, which provides an extensible architecture for developers
of third-party optimizers.  Coopr uses a dynamic registration process
that disables plugins whose executables are not available at runtime.
This minimizes the effort needed to integrate new optimizers into Pyomo.

\item {\bf Problem Transformation}: A key challenge for optimization
packages is the need to support a diverse set of problem formats.
This is an issue even for LP and MILP solver packages, where MPS is the
least common denominator for users.  Coopr includes plugins that can
write problems in NL and CPXLP formats.  Additionally, Coopr includes an
automatic problem transformation mechanism that enables the application
of optimizers to problems with a wide range of formats.  This mechanism
employs plugins, which simplifies the process for adding new conversion
capabilities.

\item {\bf Solver Managers}: Some optimization techniques involve the
execution of multiple, independent optimization subproblems.  In this
context, Pyomo's solver manager plugin components provide a high-level
abstraction of the execution of these subproblems.  This abstraction
enables the parallel execution of optimizers for these subproblems in
a transparent manner.

\end{itemize}


\subsection{Generic Optimization Process}

Pyomo strongly leverages Coopr's ability to 
execute optimizers in a generic manner.  For example, the following script illustrates the 
how an optimizer is setup and executed with Coopr:
\begin{lstlisting}
opt = SolverFactory( name )
opt.reset()
results = opt.solve( problem )
results.write()
\end{lstlisting}
Note that this relies on Coopr's explicit segregation of problems and solvers into separate objects.  This promotes the development of tools like Pyomo that support flexible definition of optimization applications, and it enables automatic transformation of problem instances.

Coopr borrows and extends the representation used by the COIN-OR OS project~\citep{OS} to support a general representation of optimizer results.  The {\em results} object returned by a Coopr optimizer includes information about the problem, the solver execution, and one or more solutions generated during optimization.

For example, if the problem in Appendix~\ref{sec:simple} is being solved, the simple Coopr optimization script would print the following information that is contained in the {\tt results} object:
\begin{lstlisting}
=====================================================
---  Solver Results                               ---
=====================================================
-----------------------------------------------------
------  Problem Information                    ------
-----------------------------------------------------
  name: None
  num_constraints: 5
  num_nonzeros: 6
  num_objectives: 1
  num_variables: 2
  sense: maximize
  upper_bound: 192000
-----------------------------------------------------
------  Solver Information                     ------
-----------------------------------------------------
  error_rc: 0
  nbounded: None
  ncreated: None
  status: ok
  systime: None
  usrtime: None
-----------------------------------------------------
------  Solution 0
-----------------------------------------------------
  gap: 0.0
  status: optimal
  value: 192000
  Primal Variables
        X_bands_        6000
        X_coils_        1400
  Dual Variables
        c_u_Limit_1     4
        c_u_Time_0      4200
-----------------------------------------------------
\end{lstlisting}



