How to get your multi-objective optimization problem working with DESDEO¶
This section describes the different ways you can get your data, model or simulation corresponding to a multi-objective optimization problem working with DESDEO. Currently, there are three approaches to adding a new problem: creating the model in Python, importing a list of solutions as data from a CSV, or interfacing to another language via Thrift.
Creating the model in Python¶
This approach is based around the classes in
desdeo.problem.porcelain
. This section walks through the process of defining the cylinder problem:
desdeo.problem.toy.CylinderProblem
. You can work through
the cylinder problem notebook to gain
familiarity with the cylinder problem.
from desdeo.problem.porcelain import Objective, PorcelainProblem, Variable
class CylinderProblem(PorcelainProblem):
"""
A description of the problem goes here.
"""
The first step is to import the classes we need and create a new class which
inherits from desdeo.problem.porcelain.PorcelainProblem
. You should
always add a docstring describing the problem so it can be displayed in the
notebook interface.
r = Variable(low=5, high=15, start=10, name="Radius")
h = Variable(low=5, high=25, start=10, name="Height")
Next, we can define variables using the
desdeo.problem.porcelain.Variable
class. Here, two variables r
and h are defined as the radius and height and given a range of acceptable
values, a starting value and a display name.
@Objective("Volume", maximized=True)
def volume(r, h):
return math.pi * r ** 2 * h
Now we define one of the objectives: maximizing the volume of the cylinder.
First we define a function that takes all variables r and h in the form we
have just named them. The body of the function is the formula for the volume of
a cylinder \(\pi r^2 h\), translated to Python code. The function is then
decorated with the desdeo.problem.porcelain.Objective
class where
it is given a display name and the direction (maximized versus minimized) is
chosen.
@Objective("Surface Area", maximized=False)
def surface_area(r, h):
return 2 * math.pi * r ** 2 + 2 * math.pi * r * h
@Objective("Height Difference", maximized=False)
def height_diff(r, h):
return abs(h - 15.0)
We now define the other objectives, setting maximized=False to define them as minimization problems.
class Meta:
name = "Cylinder Problem"
Lastly, we define the inner class Meta which is where extra settings are stored. Here, we just define the display name for the problem.
Importing a list of solutions as data¶
In this approach, you start by generating a list of solutions and write out their corresponding objective values to a CSV file <https://en.wikipedia.org/wiki/Comma-separated_values>. DESDEO can then by used to find the row corresponding to the best solution according to some preferences.
The main class involved here is
desdeo.problem.PreGeneratedProblem
. Usage is simple, just pass in
a filename parameter:
PreGeneratedProblem(
filename="/path/to/my/file.csv")
)
PreGeneratedProblem only works with the
desdeo.optimization.PointSearch
(single-objective) optimization
method. So a full example using ENAUTILUS would look like:
ENAUTILUS(
PreGeneratedProblem(
filename="/path/to/my/file.csv"
),
PointSearch,
)
Interfacing to another language via Thrift¶
In some cases, your multi-objective optimization problem may be defined in terms of simulation software you already have available. In order to transfer information from the simulation to DESDEO, a Thrift interface is provided.
(Coming soon)