# The River Pollution Problem

:

from desdeo_emo.EAs.RVEA import RVEA
from desdeo_problem import variable_builder, ScalarObjective, VectorObjective, MOProblem

import numpy as np
import pandas as pd
from desdeo_emo.utilities.plotlyanimate import animate_init_, animate_next_

:

# create the problem
def f_1(x):
return 4.07 + 2.27 * x[:, 0]

def f_2(x):
return 2.60 + 0.03*x[:, 0] + 0.02*x[:, 1] + 0.01 / (1.39 - x[:, 0]**2) + 0.30 / (1.39 - x[:, 1]**2)

def f_3(x):
return 8.21 - 0.71 / (1.09 - x[:, 0]**2)

def f_4(x):
return 0.96 - 0.96 / (1.09 - x[:, 1]**2)

# def f_5(x):
# return -0.96 + 0.96 / (1.09 - x[:, 1]**2)

def f_5(x):
return np.max([np.abs(x[:, 0] - 0.65), np.abs(x[:, 1] - 0.65)], axis=0)

:

f1 = ScalarObjective(name="f1", evaluator=f_1, maximize=True)
f2 = ScalarObjective(name="f2", evaluator=f_2, maximize=True)
f3 = ScalarObjective(name="f3", evaluator=f_3, maximize=True)
f4 = ScalarObjective(name="f4", evaluator=f_4, maximize=True)
f5 = ScalarObjective(name="f5", evaluator=f_5, maximize=False)

:

varsl = variable_builder(["x_1", "x_2"],
initial_values=[0.5, 0.5],
lower_bounds=[0.3, 0.3],
upper_bounds=[1.0, 1.0]
)

:

problem = MOProblem(variables=varsl, objectives=[f1, f2, f3, f4, f5])

:

evolver = RVEA(problem, interact=True, n_iterations=5, n_gen_per_iter=100)
figure = animate_init_(evolver.population.objectives, filename="river.html")

Plot saved as:  river.html
View the plot by opening the file in browser.
To view the plot in Jupyter Notebook, use the IFrame command.

:

pref, plot = evolver.start()

:

print(plot.content["dimensions_data"])

               f1       f2       f3          f4        f5
minimize       -1       -1       -1          -1         1
ideal     6.33643  3.40833  7.49815 -0.00301699  0.013136
nadir        -inf     -inf     -inf        -inf       inf

:

print(pref.content['message'])

Please provide preferences. There is four ways to do this. You can either:

1: Select preferred solution(s)
2: Select non-preferred solution(s)
3: Specify a reference point worse than or equal to the ideal point
4: Specify desired ranges for objectives.

In case you choose

1, please specify index/indices of preferred solutions in a numpy array (indexing starts from 0).
For example:
numpy.array(), for choosing the solutions with index 1.
numpy.array([2, 4, 5, 16]), for choosing the solutions with indices 2, 4, 5, and 16.

2, please specify index/indices of non-preferred solutions in a numpy array (indexing starts from 0).
For example:
numpy.array(), for choosing the solutions with index 3.
numpy.array([1, 2]), for choosing the solutions with indices 1 and 2.

3, please provide a reference point worse than or equal to the ideal point:

f1       6.33643
f2       3.40833
f3       7.49815
f4   -0.00301699
f5      0.013136
Name: ideal, dtype: object
The reference point will be used to focus the reference vectors towards the preferred region.
If a reference point is not provided, the previous state of the reference vectors is used.
If the reference point is the same as the ideal point, the reference vectors are spread uniformly in the objective space.

4, please specify desired lower and upper bound for each objective, starting from
the first objective and ending with the last one. Please specify the bounds as a numpy array containing
lists, so that the first item of list is the lower bound and the second the upper bound, for each
objective.
For example: numpy.array([[1, 2], [2, 5], [0, 3.5]]), for problem with three objectives.
Ideal vector:
f1       6.33643
f2       3.40833
f3       7.49815
f4   -0.00301699
f5      0.013136
Name: ideal, dtype: object
f1   -inf
f2   -inf
f3   -inf
f4   -inf
f5    inf

:

pref.response = pd.DataFrame([[6.3,3.3,7,-2,0.3]],
columns=pref.content['dimensions_data'].columns)

:

pref, plot = evolver.iterate(pref)
figure = animate_next_(
plot.content['data'].values,
figure,
filename="river.html",
generation=evolver._iteration_counter,
)

message = (f"Current generation number:{evolver._current_gen_count}. "
f"Is looping back recommended: {'Yes' if evolver.continue_evolution() else 'No'}")
print(message)

Current generation number:400. Is looping back recommended: Yes

[ ]: