21 September 2022 (1,571 words)
In this article we continue the Python Production mix series, using the Pyomo library. Specifically, we build Model 6, which changes Model 5 to:
- Declare the model as a Pyomo
pyo.AbstractModel, rather than as a
- Read the data from a
datfile rather than a
These changes show that, contrary to how abstract and concrete models are portrayed in most blogs, there is actually little difference between abstract and concrete Pyomo models.
Articles in this series
Articles in the Python Production mix series:
- Python optimization Rosetta Stone
- Production mix - Model 1, Pyomo concrete
- Production mix - Model 2, Pyomo separate data
- Production mix - Model 3, Pyomo external data
- Production mix - Model 4, Pyomo json file
- Production mix - Model 5, Pyomo using def
- Production mix - Model 6, Pyomo abstract
- Production mix - Model 7, PuLP
- Production mix - Model 8, OR-Tools
- Production mix - Model 9, Gekko
- Production mix - Model 10, CVXPY
- Production mix - Model 11, SciPy
- Production mix - Conclusions
Download the model
The Python code and data for this model are available in the following files:
- Jupyter notebook: production-model-6.ipynb
- Python code: production-model-6.py
- Data: productiondata6.dat
The "Jupyter notebook" file contains a formatted combination of Python code and markdown code – this file should be opened and run in Jupyter Lab. We describe setting up our Python environment, including Jupyter Lab and various Python libraries, in the article Set up a Python modelling environment.
The "Python code" file is a plain text file containing only the Python code of this model. Download this file if you have a non-Jupyter environment for running Python programs.
The "Data" file is a plain text file containing the model's data, in Pyomo dat format.
The model files are also available on GitHub.
Formulation for Model 6
For this model, we're using the same general formulation that we used for Model 5, as shown in Figure 1.
Model 6 Python code
The first task is to import the libraries that are needed for our program. As shown in Figure 2, we aren't using a json file, so we don't need the
json libraries that we imported in Model 5.
The data for Model 6 is shown in Figure 3. Unlike Model 5, where we read json format data and assign it to Pyomo
Param data structures, here we define the data directly in
param data structures. Note the different capitalization of the two structures – uppercase for parameters defined in the model, and lowercase for parameters defined in a
dat file. The same convention applies to sets.
Note that, unlike concrete models, we don't load the data at this stage. This is the essential difference between the two types of Pyomo model. That is:
pyo.ConcreteModel. Data is loaded before the constraints and objective function are defined.
pyo.AbstractModel. The constraints are objective function are defined first, with the data loaded only when we solve the model.
We declare an
pyo.AbstractModel, rather than a
pyo.ConcreteModel. Because we have not loaded the data, the declarations are empty sets and parameters, as shown in Figure 4. Though we can declare the domains, such as
Define the model
The model definition, as shown in Figure 5, is the same as for Model 5.
In a more complex model, the concrete and abstract model definitions may not be the same. Specifically, in a concrete mode, we may use the data to make decisions within the constraint and objective function rules. That is not possible in a pure abstract model – though we could read some data, to inform decision making, but there is typically little advantage in adopting a hybrid approach.
As shown in Figure 6, we create an instance of an abstract model by loading the data just before we solve the model. Having created an instance, we need to refer to our
Instance object rather than our
Model object. In abstract models, a common error is to refer to the model definition rather than its instance.
The code for processing the solver result, as shown in Figure 7, is the same as for Model 5 except that we refer to
Instance rather than
The code for writing the output, as shown in Figure 8, is almost the same as for Model 5, except that, again, we refer to
Instance rather than
When we find an optimal solution, the output is shown in Figure 9. This output is the same as for Model 5.
Evaluation of this model
Model 6 is our final Pyomo model in this series of articles. This model translates the concrete Model 5 into an abstract model.
Most blog articles about Pyomo models suggest that there is a substantial difference between concrete and abstract models. A model like our Model 1 is often used as a typical concrete model, while a model like our Model 6 is used as a typical abstract model. When presented that way, there is indeed a substantial difference between the two types of model.
However, a fairer comparison is between our Model 5 and Model 6. When presented this way, there is actually little difference between the two model types. As the Pyomo documentation says:
Python programmers will probably prefer to write concrete models, while users of some other algebraic modeling languages may tend to prefer to write abstract models. The choice is largely a matter of taste; some applications may be a little more straightforward using one or the other.Abstract versus Concrete models
So far in this series, we've explored the Pyomo library quite extensively. Next, we'll continue our Production mix series by implementing the model using other Python modelling libraries. Specifically, we'll use the PuLP, OR Tools, Gekko, CVXPY, and SciPy libraries to implement the same model. By using different libraries, we'll get some insight into their similarities and differences, along with their relative strengths and weaknesses.
This article completes the Pyomo part of this series. Compared with models 1 to 5, which use Pyomo's concrete model type, here we use Pyomo's abstract model type. It turns out that there isn't much difference between the two model types, with the choice between them being largely a matter of taste.
In the next article, we'll start using different libraries to build the same Production mix model.
If you would like to know more about this model, or you want help with your own models, then please contact us.