Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Pareto set drawing #200

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
Loading