Остановка по повтореням лучшего значения

This commit is contained in:
2025-10-09 12:25:23 +03:00
parent b7f2234bff
commit 745cfea282
7 changed files with 44 additions and 7 deletions

View File

@@ -30,6 +30,9 @@ class GARunConfig:
pc: float # вероятность кроссинговера
pm: float # вероятность мутации
max_generations: int # максимальное количество поколений
max_best_repetitions: int | None = (
None # остановка при повторении лучшего результата
)
seed: int | None = None # seed для генератора случайных чисел
minimize: bool = False # если True, ищем минимум вместо максимума
save_generations: list[int] | None = (
@@ -39,6 +42,7 @@ class GARunConfig:
fitness_avg_threshold: float | None = (
None # порог среднего значения фитнес функции для остановки
)
log_every_generation: bool = False # логировать каждое поколение
@dataclass(frozen=True)
@@ -337,6 +341,7 @@ def genetic_algorithm(config: GARunConfig) -> GARunResult:
best: Generation | None = None
generation_number = 1
best_repetitions = 0
while True:
# Вычисляем фитнес для всех особей в популяции
@@ -357,6 +362,12 @@ def genetic_algorithm(config: GARunConfig) -> GARunResult:
)
history.append(current)
if config.log_every_generation:
print(
f"Generation #{generation_number} best: {current.best_fitness},"
f" avg: {np.mean(current.fitnesses)}"
)
# Обновляем лучшую эпоху
if (
best is None
@@ -371,6 +382,15 @@ def genetic_algorithm(config: GARunConfig) -> GARunResult:
if generation_number >= config.max_generations:
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:
# fitness_variance = np.var(fitnesses)
# if fitness_variance < config.variance_threshold:

View File

@@ -11,14 +11,15 @@ config = GARunConfig(
x_min=np.array([-5.12, -5.12]),
x_max=np.array([5.12, 5.12]),
fitness_func=fitness_function,
max_generations=200,
pop_size=25,
pc=0.5,
pm=0.01,
max_generations=200,
max_best_repetitions=10,
minimize=True,
seed=17,
fitness_avg_threshold=0.05,
save_generations=[1, 2, 3, 5, 7, 10, 15],
save_generations=[1, 2, 3, 5, 7, 9, 10, 15, 19],
log_every_generation=True,
)
result = genetic_algorithm(config)

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

View File

@@ -393,11 +393,11 @@
\item $N = 25$ -- размер популяции.
\item $p_c = 0.5$ -- вероятность кроссинговера.
\item $p_m = 0.01$ -- вероятность мутации.
\item $0.05$ -- минимальное среднее значение фитнесс функции по популяции для остановки алгоритма. Глобальный минимум функции равен $f(0, 0) = 0$.
\item Алгоритм останавливался, если лучшее значение фитнеса не изменялось $10$ поколений подряд.
\item Использован арифметический кроссовер для real-coded хромосом.
\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!]
\centering
@@ -435,6 +435,13 @@
\label{fig:gen7}
\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!]
\centering
\includegraphics[width=1\linewidth]{img/results/generation_010.png}
@@ -444,8 +451,15 @@
\begin{figure}[h!]
\centering
\includegraphics[width=1\linewidth]{img/results/generation_013.png}
\caption{График целевой функции и популяции поколения №13}
\includegraphics[width=1\linewidth]{img/results/generation_015.png}
\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}
\end{figure}
@@ -454,6 +468,8 @@
\phantom{text}
\newpage
\phantom{text}
\newpage
\phantom{text}
\newpage
\section{Исследование реализации}