14. Import and Export of Optimization Problems
This notebook demonstrates how an optimization problem setup in MASSpy can be exported for use with other optimization solvers. This notebook is based on the Optlang API documentation and the COBRApy FAQ How do I generate an LP file from a COBRA model?
Variables, constraints, objectives, and a name (if provided) are imported/exported through this method; however, solver configuration options are not.
[1]:
try:
import simplejson as json
except ImportError:
import json
import cobra
from optlang import Model as OptModel
import mass.example_data
# Print list of available solvers
print(list(cobra.util.solver.solvers))
['glpk_exact', 'glpk', 'gurobi', 'scipy']
14.1. Using Optlang
To facilitate the formation of the mathematical optimization problem, MASSpy utilizes the Optlang python package [JCS17]. As stated in the documentation:
Optlang provides a common interface to a series of optimization tools, so different solver backends can be changed in a transparent way.
Optlang takes advantage of the symbolic math library SymPy to allow objective functions and constraints to be easily formulated from symbolic expressions of variables.
Optlang interfaces with all solvers through importable python modules (read more here).
The following optimization solvers are supported:
However, there are times where it would be preferrable to utilize other solvers and/or change programming environments in the process of setting up and performing optimizations. Fortunately, Optlang provides class methods for importing and exporting the optimization problem in both LP and JSON-compatible formats. The examples below demonstrate how the JSON format is utilized with MASSpy objects to facilitate the transference of optimization problems.
It is generally NOT recommended to import optimization problems directly into the solvers, as the corresponding MASSpy objects are bypassed and therefore do not have any values updated to match the new state of the solver.
14.1.1. Importing and Exporting with LP files
LP formulations of models can be used in conjunction with Optlang facilitate the exchange of optimization problems. Note the following:
Importing and exporting using LP formulations can change variable and constraint identifiers
LP formulations do not work with the
scipy
solver interface.
[2]:
# Start with a fresh model
model = mass.example_data.create_example_model("textbook")
# Change the bounds for demonstration purposes
model.variables.HEX1.lb, model.variables.HEX1.ub = (-123, 456)
print(model.variables["HEX1"])
Set parameter Username
-123 <= HEX1 <= 456
14.1.2. Exporting an LP file
For all solver interfaces in Optlang, the str
representation of an optlang.interface.Model
is the LP formulation of the problem.
To export the optimization problem into a file:
[3]:
with open("problem.lp", "w") as file:
file.write(str(model.solver))
Alternatively, the optlang.interface.Model.to_lp()
method can be used, but note that variable and constraint identifiers may be changed.
14.1.3. Importing an LP file
The optlang.interface.Model.from_lp()
method can be used to import an LP formulation of an optimization problem.
[4]:
# Use new model to demonstrate how bounds change
model = mass.example_data.create_example_model("textbook")
print("Before: " + str(model.variables["HEX1"]))
# Load problem from JSON file
with open("problem.lp") as file:
model._solver = OptModel.from_lp(file.read())
print("After: " + str(model.variables["HEX1"]))
Before: 0 <= HEX1 <= 1000.0
After: -123.0 <= HEX1 <= 456.0
14.1.4. Importing and Exporting with JSON files
[5]:
# Start with a fresh model
model = mass.example_data.create_example_model("textbook")
# Change the bounds for demonstration purposes
model.variables.HEX1.lb, model.variables.HEX1.ub = (-654, 321)
print(model.variables.HEX1)
-654 <= HEX1 <= 321
14.1.4.1. Exporting using JSON
Problems formulated in Optlang can be exported using the optlang.interface.Model.to_json class method. First, the to_json
class method exports a JSON compatible dict
containing the variables, constraints, objectives, and an optional name from the optlang.interface.Model
. The dict
is then passed to json.dump to save the
optimization problem as a JSON file.
To export the optimization problem into a file:
[6]:
with open("problem.json", "w") as file:
json.dump(model.solver.to_json(), file)
14.1.4.2. Importing using JSON
Problems can be imported into Optlang using the optlang.interface.Model.from_json class method. First, a JSON compatible dict
is loaded from a file using the json.load. The dict
is then passed to the from_json
class method to load the variables, constraints, objectives, and an optional name into the optlang.interface.Model
(imported as “OptModel” in this example”).
To import the optimization problem from a file:
[7]:
# Use new model to demonstrate how bounds change
model = mass.example_data.create_example_model("textbook")
print("Before: " + str(model.variables.HEX1))
# Load problem from JSON file
with open("problem.json") as file:
model._solver = OptModel.from_json(json.load(file))
print("After: " + str(model.variables.HEX1))
Before: 0 <= HEX1 <= 1000.0
After: -654 <= HEX1 <= 321
14.1.5. Adding a solver interface
For an optimization solver that does not currently have an interface, consider adding a solver interface.