# Start optimizing

To start with the optimization make sure to first install the paretos package.

```
pip install paretos
```

## Initialize

With the paretos package installed the initialization can start.
By parsing the customer token and the path where the database should be created
to the pre-build `Config`

class
everything is set automatically in the background for the user. If the database
already exists the data are written in it. Make sure the key is parsed as a normal string or read in
via. environment variables!

```
from paretos import Config
config = Config(customer_token='put here your customer token')
```

## Define the optimization problem

Before starting the optimization itself, the optimization problem needs to be described with the provided helper functions from the paretos package. Here is an example for an optimization problem having three input design variables and two KPIs to be optimized:

```
from paretos import DesignParameter, KpiParameter
from paretos import OptimizationProblem
from paretos import KpiGoalMinimum, KpiGoalMaximum
# Design parameter to be varied between minimum and maximum for a certain type of parameter
# By default the continuity is always set to continuous and is an optional parameter
design_1 = DesignParameter(name="design_1", minimum=0, maximum=1, continuity="continuous")
design_2 = DesignParameter(name="design_2", minimum=0, maximum=17, continuity="discrete")
design_3 = DesignParameter(name="design_3", minimum=-1.2, maximum=1.4)
design_space = [design_1, design_2, design_3]
kpi_1 = KpiParameter("kpi_1", KpiGoalMinimum) # To minimize
kpi_2 = KpiParameter("kpi_2", KpiGoalMaximum) # To maximize
kpi_space = [kpi_1, kpi_2]
optimization_problem = OptimizationProblem(design_space, kpi_space)
```

## Initialize the model environment

With the optimization problem set it is time to make the connection to the customer model. For further details how to wrap the customer model environment visit here. In the example here a simplified example is taken which just adds up the different design parameters above in two different ways to receive the two KPIs.

```
from paretos import EnvironmentInterface
class CustomerEnvironment(EnvironmentInterface):
def evaluate(self, design_values: Dict[str, float]) -> Dict[str, float]:
# Here the KPIs are calculated directly or by calling the wrapped model
kpi_1_value = design_values['design_1'] - design_values['design_2']
kpi_2_value = design_values['design_3'] * design_values['design_2']
return {
"kpi_1": kpi_1_value,
"kpi_2": kpi_2_value
}
```

## Setup the stop criterion for the optimization

The last things to do is to define stop criterion for the optimization to return the results. If you don't specify at
least one `Terminator`

the default terminator is set which stops the optimization after 100 runs.
If you prefer custom criterion just specify the list of custom terminators like here:

```
from paretos import RunTerminator
termination_criterion_1 = RunTerminator(number_of_runs=300)
custom_terminators = [termination_criterion_1]
```

## Start the optimization

With all the above defined variables the optimization can now be started.

```
from paretos import Paretos
project_name = "my_first_optimization_project"
paretos = Paretos(config)
paretos.optimize(name=project_name,
optimization_problem=optimization_problem,
environment=CustomerEnvironment(),
terminators=custom_terminators)
```

## Get optimization results from the database

Paretos package enables the user to get the results for all possibilities fast to go ahead processing them.

```
result = paretos.obtain(name="my_first_optimization_project")
# Transform results in pandas dataframe
import pandas as pd
result_df = pd.DataFrame(result)
# Save Data to .csv
result.to_csv(path="example.csv")
```

## Resume optimization run

## Complete Code Example

```
import math
from typing import Dict
from paretos import Config, DesignParameter, KpiParameter, \
KpiGoalMinimum, KpiGoalMaximum, OptimizationProblem, \
EnvironmentInterface, Paretos, RunTerminator
class SecretModel():
"""
Random Model predicting the Costs and CO2 which is emitted
for a system based on five secret inputs ;)
"""
@staticmethod
def predict(x_sim: list) -> list:
"""
Function has a convex pareto optimal front.
"""
costs = x_sim[0]
g = 1 + 9 / 29 * sum(x_sim[1:])
h = 1 - math.sqrt(costs / g)
co2_emission = g * h
return [costs, co2_emission]
class SecretModelEnvironment(EnvironmentInterface):
def evaluate(self, design_values: Dict[str, float]) -> Dict[str, float]:
customer_model = SecretModel()
# Here we bring design parameter in the shape customer model needs them
# Dicts are not ordered thats why we need to guarantee design parameter order
design_params_order = ["design_1", "design_2", "design_3", "design_4"]
design_list = [design_values[design_name] for design_name in design_params_order]
cost_val, co2_emission_val = customer_model.predict(design_list)
return {
"System cost": cost_val,
"CO2 emission": co2_emission_val
}
secret_env = SecretModelEnvironment()
config = Config(customer_token="customer token here")
design_1 = DesignParameter("design_1", minimum=0, maximum=1, continuity="continuous")
design_2 = DesignParameter("design_2", minimum=0, maximum=1)
design_3 = DesignParameter("design_3", minimum=0, maximum=1)
design_4 = DesignParameter("design_4", minimum=0, maximum=1)
design_space = [design_1, design_2, design_3, design_4]
kpi_1 = KpiParameter("System cost", KpiGoalMinimum)
kpi_2 = KpiParameter("CO2 emission", KpiGoalMinimum)
kpi_space = [kpi_1, kpi_2]
optimization_problem = OptimizationProblem(design_space, kpi_space)
# Stop after 50 runs
terminator_creator = RunTerminator(number_of_runs=50)
customer_terminators = [terminator_creator]
# Initialize Paretos class and run optimization
paretos = Paretos(config)
paretos.optimize(
name="secret_system_design",
optimization_problem=optimization_problem,
environment=secret_env,
terminators=customer_terminators
)
# Get the results in dict form from the database
result_data = paretos.obtain("secret_system_design")
# Save results to csv file
result_data.to_csv("secret_system_design.csv")
```