Остановка по повтореням лучшего значения
This commit is contained in:
20
lab2/gen.py
20
lab2/gen.py
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
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 $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{Исследование реализации}
|
||||
|
||||
Reference in New Issue
Block a user