Skip to content

Commit

Permalink
Added Pareto set drawing (#200)
Browse files Browse the repository at this point in the history
  • Loading branch information
LebedevIlyaG authored Dec 7, 2024
1 parent de97b58 commit bc7abd9
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 30 deletions.
4 changes: 4 additions & 0 deletions examples/MCO_Grishagin_example.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from iOpt.output_system.listeners.static_painters import StaticPainterParetoListener
from problems.grishagin_mco import Grishagin_mco
from iOpt.solver import Solver
from iOpt.solver_parametrs import SolverParameters
Expand All @@ -18,6 +19,9 @@
cfol = ConsoleOutputListener(mode='full')
solver.add_listener(cfol)

sppl = StaticPainterParetoListener("Grishagin_mco_pareto.png")
solver.add_listener(sppl)

sol = solver.solve()

# output of the Pareto set (coordinates - function values)
Expand Down
19 changes: 5 additions & 14 deletions examples/MCO_Test1_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from iOpt.solver_parametrs import SolverParameters

from iOpt.output_system.listeners.console_outputers import ConsoleOutputListener
from iOpt.output_system.listeners.static_painters import StaticPainterParetoListener
import matplotlib.pyplot as plt

if __name__ == "__main__":
Expand All @@ -24,6 +25,10 @@
cfol = ConsoleOutputListener(mode='full')
solver.add_listener(cfol)

# Добавляем построение графика множества Парето y[0]-y[1]
sppl = StaticPainterParetoListener("mco_test1_pareto.png")
solver.add_listener(sppl)

# Решаем задачу
sol = solver.solve()

Expand All @@ -33,17 +38,3 @@
print("size pareto set: ", len(var))
for fvar, fval in zip(var, val):
print(fvar, fval)

# Точки для построения
# x1 = [trial.point.float_variables[0] for trial in sol.best_trials]
# x2 = [trial.point.float_variables[1] for trial in sol.best_trials]

# plt.plot(x1, x2, 'ro')
# plt.show()

# Точки для построения графика множества Парето y[0]-y[1]
fv1 = [trial.function_values[0].value for trial in sol.best_trials]
fv2 = [trial.function_values[1].value for trial in sol.best_trials]

plt.plot(fv1, fv2, 'ro')
plt.show()
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from iOpt.output_system.listeners.static_painters import StaticPainterNDListener
from iOpt.output_system.listeners.static_painters import StaticPainterParetoListener
from iOpt.output_system.listeners.console_outputers import ConsoleOutputListener

from iOpt.solver import Solver
Expand All @@ -12,7 +12,7 @@
# Для построения HV индекса
# from pymoo.util.misc import stack
# from pymoo.indicators.hv import HV
import numpy as np
# import numpy as np

def factory_dataset():
x = []
Expand All @@ -34,13 +34,16 @@ def factory_dataset():
kernel_coefficient_bound = {'low': -3, 'up': 1}
problem = MCO_SVC_2D_Transformators_State.MCO_SVC_2D_Transformators_State(X, Y, regularization_value_bound,
kernel_coefficient_bound)
method_params = SolverParameters(r=np.double(2.0), iters_limit=50, number_of_parallel_points=1,
method_params = SolverParameters(r=np.double(2.0), iters_limit=500, number_of_parallel_points=1,
evolvent_density=12, number_of_lambdas=5)
solver = Solver(problem=problem, parameters=method_params)
# Добавляем вывод результатов в консоль
cfol = ConsoleOutputListener(mode='full')
solver.add_listener(cfol)

sppl = StaticPainterParetoListener("MCO_SVC_2D_Transformators_pareto.png")
solver.add_listener(sppl)

# Решаем задачу
sol = solver.solve()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ def __init__(self, x_dataset: np.ndarray, y_dataset: np.ndarray,
self.upper_bound_of_float_variables = np.array([regularization_bound['up'], kernel_coefficient_bound['up']],
dtype=np.double)

#self.cv = StratifiedKFold(shuffle=True, random_state=42)




def calculateAllFunction(self, point: Point, function_values: np.ndarray(shape=(1), dtype=FunctionValue)) -> \
np.ndarray(shape=(1), dtype=FunctionValue):
"""
Expand Down
35 changes: 31 additions & 4 deletions iOpt/output_system/listeners/static_painters.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from iOpt.method.listener import Listener
from iOpt.method.method import Method
from iOpt.method.search_data import SearchData
from iOpt.output_system.painters.static_painters import StaticPainter, StaticPainterND, DiscretePainter
from iOpt.output_system.painters.static_painters import StaticPainter, StaticPainterND, DiscretePainter, StaticPainterPareto
from iOpt.solution import Solution


Expand Down Expand Up @@ -89,7 +89,7 @@ def __init__(self, file_name: str, path_for_saves="", indx=0, is_points_at_botto
"""
Constructor of the StaticPainterListener class
:param file_name: File name specifying the format for saving the image.
:param file_name: File name specifying the format for saving the image.
:param path_for_saves: The directory to save the image. If this parameter is not specified, the image is saved in the current working directory.
is saved in the current working directory.
:param indx: Index of the variable of the optimization problem. It is used in multivariate optimization.
Expand Down Expand Up @@ -133,9 +133,9 @@ class StaticPainterNDListener(Listener):
def __init__(self, file_name: str, path_for_saves="", vars_indxs=[0, 1], mode='lines layers',
calc='objective function'):
"""
Конструктор класса StaticPainterNDListener
Constructor of the StaticPainterNDListener class
:param file_name: File name specifying the format for saving the image.
:param file_name: File name specifying the format for saving the image.
:param path_for_saves: The directory to save the image. If this parameter is not specified, the image is saved in the current working directory.
is saved in the current working directory.
:param vars_indxs: A pair of indices of the variables of the optimization problem for which the figure will be plotted.
Expand Down Expand Up @@ -167,3 +167,30 @@ def on_method_stop(self, search_data: SearchData,
painter.paint_points()
painter.paint_optimum()
painter.save_image()


class StaticPainterParetoListener(Listener):
"""
The StaticPainterParetoListener class is an event listener. It contains a method handler that produces an image as a
image as a reaction to the method completion.
It is used for multicriteria optimization
"""

def __init__(self, file_name: str, path_for_saves="", criteria_indxs=[0, 1]):
"""
Constructor of the StaticPainterParetoListener class
:param file_name: File name specifying the format for saving the image.
:param path_for_saves: The directory to save the image. If this parameter is not specified, the image is saved in the current working directory.
is saved in the current working directory.
:param criteria_indxs: A pair of indices of the criteria of the optimization problem for which the figure will be plotted.
"""
self.file_name = file_name
self.path_for_saves = path_for_saves
self.criteria_indxs = criteria_indxs

def on_method_stop(self, search_data: SearchData,
solution: Solution, status: bool, ):
painter = StaticPainterPareto(solution, self.criteria_indxs, self.path_for_saves, self.file_name)
painter.paint_pareto()
painter.save_image()
13 changes: 11 additions & 2 deletions iOpt/output_system/painters/plotters/plotters.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ def __init__(self, parameter_in_nd_problem, left_bound, right_bound):

self.fig, self.ax = plt.subplots(1, 1)
self.ax.tick_params(axis='both', labelsize=8)
self.ax.set_xlim([self.leftBound, self.rightBound])
if self.leftBound != None and self.rightBound != None:
self.ax.set_xlim([self.leftBound, self.rightBound])

def plot_by_grid(self, calculate, section, points_count=100):
x = np.arange(self.leftBound, self.rightBound, (self.rightBound - self.leftBound) / points_count)
Expand Down Expand Up @@ -433,4 +434,12 @@ def plot_points(self, points, values, clr='blue', mrkr='o', mrkrs=4):
self.ax.relim()
self.ax.autoscale_view()
self.fig.canvas.draw()
self.fig.canvas.flush_events()
self.fig.canvas.flush_events()


class PlotterPareto(Plotter2D):
def __init__(self):
super().__init__(None, None, None)

def plot_pareto(self, first_criteria_values, second_criteria_values, clr='blue', mrkr='o', mrkrs=8):
self.plot_points(first_criteria_values, second_criteria_values, clr, mrkr, mrkrs)
36 changes: 34 additions & 2 deletions iOpt/output_system/painters/static_painters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from iOpt.method.search_data import SearchData, SearchDataItem
from iOpt.trial import Point, FunctionValue
from iOpt.solution import Solution
from iOpt.output_system.painters.plotters.plotters import Plotter2D, Plotter3D, DisretePlotter
from iOpt.output_system.painters.plotters.plotters import Plotter2D, Plotter3D, DisretePlotter, PlotterPareto
from iOpt.output_system.painters.painter import Painter

import matplotlib.pyplot as plt
Expand Down Expand Up @@ -282,4 +282,36 @@ def calculate_func(self, x):
point = Point(x, [])
fv = FunctionValue()
fv = self.objFunc(point, fv)
return fv.value
return fv.value


class StaticPainterPareto:
def __init__(self,
solution: Solution,
criteria_indxs,
path_for_saves,
file_name
):
self.path_for_saves = path_for_saves
self.file_name = file_name

# values of Pareto-efficient criteria with input indices
self.first_criteria_values = [trial.function_values[criteria_indxs[0]].value for trial in solution.best_trials]
self.second_criteria_values = [trial.function_values[criteria_indxs[1]].value for trial in solution.best_trials]

# definition of plotter
self.plotter = PlotterPareto()

def paint_pareto(self):
self.plotter.plot_pareto(self.first_criteria_values, self.second_criteria_values)

def save_image(self):
if not os.path.isdir(self.path_for_saves):
if self.path_for_saves == "":
plt.savefig(self.file_name)
else:
os.mkdir(self.path_for_saves)
plt.savefig(self.path_for_saves + "/" + self.file_name)
else:
plt.savefig(self.path_for_saves + "/" + self.file_name)
plt.show()

0 comments on commit bc7abd9

Please sign in to comment.