Остановка по повтореням лучшего значения
This commit is contained in:
20
lab2/gen.py
20
lab2/gen.py
@@ -30,6 +30,9 @@ class GARunConfig:
|
|||||||
pc: float # вероятность кроссинговера
|
pc: float # вероятность кроссинговера
|
||||||
pm: float # вероятность мутации
|
pm: float # вероятность мутации
|
||||||
max_generations: int # максимальное количество поколений
|
max_generations: int # максимальное количество поколений
|
||||||
|
max_best_repetitions: int | None = (
|
||||||
|
None # остановка при повторении лучшего результата
|
||||||
|
)
|
||||||
seed: int | None = None # seed для генератора случайных чисел
|
seed: int | None = None # seed для генератора случайных чисел
|
||||||
minimize: bool = False # если True, ищем минимум вместо максимума
|
minimize: bool = False # если True, ищем минимум вместо максимума
|
||||||
save_generations: list[int] | None = (
|
save_generations: list[int] | None = (
|
||||||
@@ -39,6 +42,7 @@ class GARunConfig:
|
|||||||
fitness_avg_threshold: float | None = (
|
fitness_avg_threshold: float | None = (
|
||||||
None # порог среднего значения фитнес функции для остановки
|
None # порог среднего значения фитнес функции для остановки
|
||||||
)
|
)
|
||||||
|
log_every_generation: bool = False # логировать каждое поколение
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
@@ -337,6 +341,7 @@ def genetic_algorithm(config: GARunConfig) -> GARunResult:
|
|||||||
best: Generation | None = None
|
best: Generation | None = None
|
||||||
|
|
||||||
generation_number = 1
|
generation_number = 1
|
||||||
|
best_repetitions = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Вычисляем фитнес для всех особей в популяции
|
# Вычисляем фитнес для всех особей в популяции
|
||||||
@@ -357,6 +362,12 @@ def genetic_algorithm(config: GARunConfig) -> GARunResult:
|
|||||||
)
|
)
|
||||||
history.append(current)
|
history.append(current)
|
||||||
|
|
||||||
|
if config.log_every_generation:
|
||||||
|
print(
|
||||||
|
f"Generation #{generation_number} best: {current.best_fitness},"
|
||||||
|
f" avg: {np.mean(current.fitnesses)}"
|
||||||
|
)
|
||||||
|
|
||||||
# Обновляем лучшую эпоху
|
# Обновляем лучшую эпоху
|
||||||
if (
|
if (
|
||||||
best is None
|
best is None
|
||||||
@@ -371,6 +382,15 @@ def genetic_algorithm(config: GARunConfig) -> GARunResult:
|
|||||||
if generation_number >= config.max_generations:
|
if generation_number >= config.max_generations:
|
||||||
stop_algorithm = True
|
stop_algorithm = True
|
||||||
|
|
||||||
|
if config.max_best_repetitions is not None and generation_number > 1:
|
||||||
|
if history[-2].best_fitness == current.best_fitness:
|
||||||
|
best_repetitions += 1
|
||||||
|
|
||||||
|
if best_repetitions == config.max_best_repetitions:
|
||||||
|
stop_algorithm = True
|
||||||
|
else:
|
||||||
|
best_repetitions = 0
|
||||||
|
|
||||||
# if config.variance_threshold is not None:
|
# if config.variance_threshold is not None:
|
||||||
# fitness_variance = np.var(fitnesses)
|
# fitness_variance = np.var(fitnesses)
|
||||||
# if fitness_variance < config.variance_threshold:
|
# if fitness_variance < config.variance_threshold:
|
||||||
|
|||||||
@@ -11,14 +11,15 @@ config = GARunConfig(
|
|||||||
x_min=np.array([-5.12, -5.12]),
|
x_min=np.array([-5.12, -5.12]),
|
||||||
x_max=np.array([5.12, 5.12]),
|
x_max=np.array([5.12, 5.12]),
|
||||||
fitness_func=fitness_function,
|
fitness_func=fitness_function,
|
||||||
max_generations=200,
|
|
||||||
pop_size=25,
|
pop_size=25,
|
||||||
pc=0.5,
|
pc=0.5,
|
||||||
pm=0.01,
|
pm=0.01,
|
||||||
|
max_generations=200,
|
||||||
|
max_best_repetitions=10,
|
||||||
minimize=True,
|
minimize=True,
|
||||||
seed=17,
|
seed=17,
|
||||||
fitness_avg_threshold=0.05,
|
save_generations=[1, 2, 3, 5, 7, 9, 10, 15, 19],
|
||||||
save_generations=[1, 2, 3, 5, 7, 10, 15],
|
log_every_generation=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
result = genetic_algorithm(config)
|
result = genetic_algorithm(config)
|
||||||
|
|||||||
BIN
lab2/report/img/results/generation_009.png
Normal file
BIN
lab2/report/img/results/generation_009.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 545 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 543 KiB |
BIN
lab2/report/img/results/generation_015.png
Normal file
BIN
lab2/report/img/results/generation_015.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 542 KiB |
BIN
lab2/report/img/results/generation_019.png
Normal file
BIN
lab2/report/img/results/generation_019.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 542 KiB |
@@ -393,11 +393,11 @@
|
|||||||
\item $N = 25$ -- размер популяции.
|
\item $N = 25$ -- размер популяции.
|
||||||
\item $p_c = 0.5$ -- вероятность кроссинговера.
|
\item $p_c = 0.5$ -- вероятность кроссинговера.
|
||||||
\item $p_m = 0.01$ -- вероятность мутации.
|
\item $p_m = 0.01$ -- вероятность мутации.
|
||||||
\item $0.05$ -- минимальное среднее значение фитнесс функции по популяции для остановки алгоритма. Глобальный минимум функции равен $f(0, 0) = 0$.
|
\item Алгоритм останавливался, если лучшее значение фитнеса не изменялось $10$ поколений подряд.
|
||||||
\item Использован арифметический кроссовер для real-coded хромосом.
|
\item Использован арифметический кроссовер для real-coded хромосом.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
С каждым поколением точность найденного минимума становится выше. Популяция постепенно сходится к глобальному минимуму в точке $(0, 0)$. На графиках показаны 2D-контурный график (a) и 3D-поверхность целевой функции с точками популяции текущего поколения (b) и (c).
|
Популяция постепенно консолидируется вокруг глобального минимума в точке $(0, 0)$. Лучшая особь была найдена на поколнении №9 (см. Рис.~\ref{fig:gen9}), но судя по всему она подверглась мутации или кроссинговеру, поэтому алгоритм не остановился. На поколении №19 (см. Рис.~\ref{fig:lastgen}) было получено значение фитнеса $0.0201$, которое затем повторялось в следующих 10 поколениях. Алгоритм остановился на поколлении №29. На графиках показаны 2D-контурный график (a) и 3D-поверхность целевой функции с точками популяции текущего поколения (b) и (c).
|
||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[h!]
|
||||||
\centering
|
\centering
|
||||||
@@ -435,6 +435,13 @@
|
|||||||
\label{fig:gen7}
|
\label{fig:gen7}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[h!]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=1\linewidth]{img/results/generation_009.png}
|
||||||
|
\caption{График целевой функции и популяции поколения №9}
|
||||||
|
\label{fig:gen9}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[h!]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=1\linewidth]{img/results/generation_010.png}
|
\includegraphics[width=1\linewidth]{img/results/generation_010.png}
|
||||||
@@ -444,8 +451,15 @@
|
|||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[h!]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=1\linewidth]{img/results/generation_013.png}
|
\includegraphics[width=1\linewidth]{img/results/generation_015.png}
|
||||||
\caption{График целевой функции и популяции поколения №13}
|
\caption{График целевой функции и популяции поколения №15}
|
||||||
|
\label{fig:gen15}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[h!]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=1\linewidth]{img/results/generation_019.png}
|
||||||
|
\caption{График целевой функции и популяции поколения №19}
|
||||||
\label{fig:lastgen}
|
\label{fig:lastgen}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
@@ -454,6 +468,8 @@
|
|||||||
\phantom{text}
|
\phantom{text}
|
||||||
\newpage
|
\newpage
|
||||||
\phantom{text}
|
\phantom{text}
|
||||||
|
\newpage
|
||||||
|
\phantom{text}
|
||||||
|
|
||||||
\newpage
|
\newpage
|
||||||
\section{Исследование реализации}
|
\section{Исследование реализации}
|
||||||
|
|||||||
Reference in New Issue
Block a user