Результаты в отчёте
This commit is contained in:
@@ -15,8 +15,8 @@ def target_function(x: float) -> float:
|
||||
BASE_DIR = "experiments"
|
||||
|
||||
# Параметры для экспериментов
|
||||
POPULATION_SIZES = [10, 50, 100]
|
||||
PC_VALUES = [0.5, 0.6, 0.7, 0.8, 0.9] # вероятности кроссинговера
|
||||
POPULATION_SIZES = [10, 25, 50, 100]
|
||||
PC_VALUES = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8] # вероятности кроссинговера
|
||||
PM_VALUES = [0.001, 0.01, 0.05, 0.1, 0.2] # вероятности мутации
|
||||
|
||||
# Базовые параметры (как в main.py)
|
||||
@@ -110,7 +110,7 @@ def main():
|
||||
os.makedirs(pop_exp_dir, exist_ok=True)
|
||||
with open(os.path.join(pop_exp_dir, "results.csv"), "w", encoding="utf-8") as f:
|
||||
f.write(table.get_csv_string())
|
||||
print(f"Результаты сохранены в папке: {pop_exp_dir}/")
|
||||
print(f"Результаты сохранены в папке: {pop_exp_dir}")
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print("ВСЕ ЭКСПЕРИМЕНТЫ ЗАВЕРШЕНЫ!")
|
||||
|
||||
11
lab1/main.py
11
lab1/main.py
@@ -15,8 +15,8 @@ config = GARunConfig(
|
||||
x_max=20.0,
|
||||
fitness_func=target_function,
|
||||
precision_digits=3,
|
||||
pop_size=15,
|
||||
pc=0.7,
|
||||
pop_size=25,
|
||||
pc=0.5,
|
||||
pm=0.01,
|
||||
max_generations=200,
|
||||
seed=17,
|
||||
@@ -26,12 +26,9 @@ config = GARunConfig(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
10,
|
||||
25,
|
||||
49,
|
||||
99,
|
||||
150,
|
||||
199,
|
||||
], # поколения для сохранения графиков
|
||||
results_dir="results",
|
||||
# variance_threshold=1e-6, # порог дисперсии для остановки
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
%\usepackage{literat} % Нормальные шрифты
|
||||
\usepackage[14pt]{extsizes} % для того чтобы задать нестандартный 14-ый размер шрифта
|
||||
\usepackage{tabularx}
|
||||
\usepackage{booktabs}
|
||||
\usepackage[T2A]{fontenc}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[russian]{babel}
|
||||
@@ -280,7 +281,247 @@
|
||||
\item Ген $a_k$ инвертируется: $a_k' = \lnot a_k$.
|
||||
\end{enumerate}
|
||||
|
||||
\newpage
|
||||
\section{Особенности реализации}
|
||||
В рамках работы создана мини-библиотека \texttt{gen.py} для экспериментов с простым
|
||||
генетическим алгоритмом (ГА) на одной переменной. Второй модуль
|
||||
\texttt{expirements.py} организует серийные эксперименты (перебор параметров,
|
||||
форматирование и сохранение результатов).
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Кодирование особей}: каждая хромосома — список битов фиксированной длины \(L\).
|
||||
Длина \(L\) подбирается автоматически так, чтобы шаг дискретизации по \(x\)
|
||||
был не хуже заданной точности (например, \(10^{-3}\)). Декодирование — линейное в
|
||||
\([x_{\min}, x_{\max}]\). За это отвечают:
|
||||
\begin{itemize}
|
||||
\item \texttt{bits\_for\_precision(x\_min: float, x\_max: float, } \\ \texttt{ digits\_after\_decimal: int) -> int}
|
||||
\item \texttt{decode\_bits\_to\_x(bits: list[int], x\_min: float, x\_max: float)} \\ \texttt{ -> float}
|
||||
\item \texttt{random\_bits(L: int) -> list[int]}
|
||||
\end{itemize}
|
||||
\item \textbf{Фитнесс и минимум/максимум}: целевая функция передаётся параметром. Для
|
||||
режима \emph{минимизации} используется внутреннее преобразование при селекции (инвертирование
|
||||
знака/сдвиг), что позволяет единообразно применять рулетку при отрицательных значениях. За это отвечают:
|
||||
\begin{itemize}
|
||||
\item \texttt{eval\_population(population: list[list[int]], x\_min: float, x\_max: float, fitness\_func(x: float) -> float)} \\ \texttt{ -> (list[float], list[float])}
|
||||
\item Логика режима минимизации в \texttt{genetic\_algorithm(config: GARunConfig) -> GARunResult}
|
||||
\end{itemize}
|
||||
\item \textbf{Селекция (рулетка)}: вероятности нормируются после сдвига на минимальное
|
||||
значение в поколении (устойчиво к отрицательным фитнессам). Функция:
|
||||
\texttt{reproduction(population: list[list[int]], fitnesses: list[float])} \\ \texttt{ -> list[list[int]]}.
|
||||
\item \textbf{Кроссинговер}: одноточечный, попарно по перемешанной популяции. При нечётном
|
||||
размере последняя особь скрещивается со случайной другой особью (возможно повторное участие в кроссинговере одной из особей). Пары скрещиваются с вероятностью \(p_c\), иначе родители добавляются в новую популяцию без изменений. Функции:
|
||||
\begin{itemize}
|
||||
\item \texttt{crossover\_pair(p1: list[int], p2: list[int], pc: float) -> (list[int], list[int])}
|
||||
\item \texttt{crossover(population: list[list[int]], pc: float) -> list[list[int]]}
|
||||
\end{itemize}
|
||||
\item \textbf{Мутация}: с вероятностью \(p_m\) \emph{на хромосому} инвертируется ровно один
|
||||
случайный бит. Функция:
|
||||
\texttt{mutation(chrom: list[int], pm: float) -> None}.
|
||||
|
||||
\item \textbf{Критерий остановки}: поддержаны критерии по дисперсии значений фитнесс функции в популяции и по среднему значению (настраиваемые пороги), но для экспериментов в данной лабораторной работе используется только критерий по среднему значению. Хранится история лучших особей и всех
|
||||
популяций по поколениям. Проверка выполняется внутри функции:
|
||||
|
||||
\texttt{genetic\_algorithm(config: GARunConfig) -> GARunResult}
|
||||
(используются поля \texttt{variance\_threshold}, \texttt{fitness\_avg\_threshold} из \texttt{GARunConfig}).
|
||||
\item \textbf{Визуализация}: снимок поколения включает график целевой функции, точки всей
|
||||
текущей популяции, лучшую особь (выделена красным цветом), а также историю лучших по предыдущим
|
||||
поколениям (выделены оранжевым цветом). Функция:
|
||||
\texttt{plot\_generation\_snapshot(... ) -> str}.
|
||||
\item \textbf{Измерение времени}: длительность вычислений возвращается в миллисекундах; для
|
||||
сравнения параметров в серии экспериментов введён единый формат вывода. Значение доступно как
|
||||
\texttt{GARunResult.time\_ms} из \\ \texttt{genetic\_algorithm(config: GARunConfig) -> GARunResult}.
|
||||
\item \textbf{Файловая организация}: по желанию сохраняются изображения поколений в
|
||||
\texttt{results/}. Серии экспериментов пишут результаты иерархически: \texttt{experiments/\textit{N}/pc\_\textit{p}/pm\_\textit{m}/} с
|
||||
агрегированной таблицей в \texttt{CSV} на уровне популяции. Задействованные функции:
|
||||
\begin{itemize}
|
||||
\item \texttt{clear\_results\_directory(results\_dir: str) -> None}
|
||||
\item \texttt{run\_single\_experiment(pop\_size: int, pc: float, pm: float) -> (float, int)}
|
||||
\item \texttt{run\_experiments\_for\_population(pop\_size: int) -> PrettyTable}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
В модуле \texttt{expirements.py} задаётся целевая функция (\texttt{target\_function(x: float) -> float} (\(\sin(x)/x^2\)) ) и другие параметры для экспериментов.
|
||||
Серийные запуски и сохранение результатов реализованы в функциях:
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{run\_single\_experiment(pop\_size: int, pc: float, pm: float) -> (float, int)},
|
||||
\item \texttt{run\_experiments\_for\_population(pop\_size: int) -> PrettyTable},
|
||||
\item \texttt{main()}.
|
||||
\end{itemize}
|
||||
|
||||
\newpage
|
||||
\section{Результаты работы}
|
||||
На Рис.~\ref{fig:gen1}--~\ref{fig:lastgen} представлены результаты работы генетического алгоритма со следующими параметрами:
|
||||
\begin{itemize}
|
||||
\item $N = 15$ -- размер популяции.
|
||||
\item $p_c = 0.5$ -- вероятность кроссинговера.
|
||||
\item $p_m = 0.01$ -- вероятность мутации.
|
||||
\item $-0.049$ -- минимальное среднее значение фитнесс функции по популяции для остановки алгоритма. Настоящий минимум функции равен примерно $-0.04957$.
|
||||
\end{itemize}
|
||||
|
||||
С каждым поколением точность найденного максимума становится выше. На втором поколении популяция еще распределена по всей области поиска решения. На поколении 8 особи
|
||||
«конденсируются» вблизи нужного нам экстремума, а на поколении 14 достигается заданная точность нахождения минимума функции.
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_000.png}
|
||||
\caption{График целевой функции и популяции поколения \#1.}
|
||||
\label{fig:gen1}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_001.png}
|
||||
\caption{График целевой функции и популяции поколения \#2.}
|
||||
\label{fig:gen2}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_002.png}
|
||||
\caption{График целевой функции и популяции поколения \#3.}
|
||||
\label{fig:gen3}
|
||||
\end{figure}
|
||||
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_003.png}
|
||||
\caption{График целевой функции и популяции поколения \#4.}
|
||||
\label{fig:gen4}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_005.png}
|
||||
\caption{График целевой функции и популяции поколения \#6.}
|
||||
\label{fig:gen6}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_007.png}
|
||||
\caption{График целевой функции и популяции поколения \#8.}
|
||||
\label{fig:gen8}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_010.png}
|
||||
\caption{График целевой функции и популяции поколения \#11.}
|
||||
\label{fig:gen11}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=1\linewidth]{img/results/generation_014.png}
|
||||
\caption{График целевой функции и популяции поколения \#15.}
|
||||
\label{fig:lastgen}
|
||||
\end{figure}
|
||||
|
||||
|
||||
\newpage
|
||||
\phantom{text}
|
||||
\newpage
|
||||
\phantom{text}
|
||||
\newpage
|
||||
\phantom{text}
|
||||
\newpage
|
||||
\phantom{text}
|
||||
|
||||
\newpage
|
||||
\section{Исследование реализации}
|
||||
\subsection{Проведение измерений}
|
||||
В рамках лабораторной работы необходимо было исследовать зависимость времени выполнения задачи и количества поколений от популяции и вероятностей кроссинговера и мутации хромосомы
|
||||
|
||||
Для исследования были выбраны следующие значения параметров:
|
||||
\begin{itemize}
|
||||
\item $N = 10, 25, 50, 100$ -- размер популяции.
|
||||
\item $p_c = 0.3, 0.4, 0.5, 0.6, 0.7, 0.8$ -- вероятность кроссинговера.
|
||||
\item $p_m = 0.001, 0.01, 0.05, 0.1, 0.2$ -- вероятность мутации.
|
||||
\end{itemize}
|
||||
\newcolumntype{Y}{>{\centering\arraybackslash}X}
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabularx}{\linewidth}{l *{5}{Y}}
|
||||
\toprule
|
||||
$\mathbf{P_c \;\backslash\; P_m}$ & \textbf{0.001} & \textbf{0.010} & \textbf{0.050} & \textbf{0.100} & \textbf{0.200} \\
|
||||
\midrule
|
||||
\textbf{0.3} & -- & 6.8 (83) & 4.7 (57) & 3.4 (37) & 2.3 (29) \\
|
||||
\textbf{0.4} & -- & 3.7 (48) & 3.6 (24) & 5.2 (64) & 2.3 (17) \\
|
||||
\textbf{0.5} & -- & -- & 6.2 (86) & 2.5 (27) & 2.8 (34) \\
|
||||
\textbf{0.6} & -- & 12.6 (163)& 5.7 (56) & 2.7 (34) & 2.1 (25) \\
|
||||
\textbf{0.7} & -- & -- & 7.9 (103) & 2.4 (23) & 2.3 (25) \\
|
||||
\textbf{0.8} & -- & 11.8 (159)& 2.9 (23) & 2.0 (23) & 1.3 (13) \\
|
||||
\bottomrule
|
||||
\end{tabularx}
|
||||
\caption{Результаты для $N = 10$}
|
||||
\label{tab:pc_pm_results}
|
||||
\end{table}
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabularx}{\linewidth}{l *{5}{Y}}
|
||||
\toprule
|
||||
$\mathbf{P_c \;\backslash\; P_m}$ & \textbf{0.001} & \textbf{0.010} & \textbf{0.050} & \textbf{0.100} & \textbf{0.200} \\
|
||||
\midrule
|
||||
\textbf{0.3} & 20.6 (146) & 13.5 (90) & 6.5 (43) & 5.3 (29) & 7.1 (48) \\
|
||||
\textbf{0.4} & 2.7 (13) & 6.7 (38) & 3.4 (20) & 3.0 (20) & 19.2 (122) \\
|
||||
\textbf{0.5} & -- & 3.0 (15) & 2.5 (16) & 3.7 (20) & -- \\
|
||||
\textbf{0.6} & 1.8 (11) & 14.3 (102)& 2.3 (13) & 2.4 (14) & -- \\
|
||||
\textbf{0.7} & 2.1 (12) & 3.3 (17) & 6.4 (36) & 2.5 (15) & 9.1 (60) \\
|
||||
\textbf{0.8} & -- & 2.6 (12) & 3.8 (22) & 3.7 (24) & 6.8 (47) \\
|
||||
\bottomrule
|
||||
\end{tabularx}
|
||||
\caption{Результаты для $N = 25$}
|
||||
\label{tab:pc_pm_results2}
|
||||
\end{table}
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabularx}{\linewidth}{l *{5}{Y}}
|
||||
\toprule
|
||||
$\mathbf{P_c \;\backslash\; P_m}$ & \textbf{0.001} & \textbf{0.010} & \textbf{0.050} & \textbf{0.100} & \textbf{0.200} \\
|
||||
\midrule
|
||||
\textbf{0.3} & 25.8 (101) & 6.3 (24) & 9.5 (30) & 7.2 (27) & -- \\
|
||||
\textbf{0.4} & 4.8 (18) & 4.6 (16) & 21.4 (86) & 42.5 (167)& 43.2 (175) \\
|
||||
\textbf{0.5} & 23.6 (95) & 21.3 (82) & 8.5 (34) & 6.4 (23) & 20.0 (76) \\
|
||||
\textbf{0.6} & 5.5 (20) & 10.9 (41) & 12.8 (43) & -- & 28.6 (113) \\
|
||||
\textbf{0.7} & -- & 7.4 (28) & 8.8 (35) & -- & -- \\
|
||||
\textbf{0.8} & -- & 11.7 (47) & 9.1 (36) & -- & -- \\
|
||||
\bottomrule
|
||||
\end{tabularx}
|
||||
\caption{Результаты для $N = 50$}
|
||||
\label{tab:pc_pm_results3}
|
||||
\end{table}
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabularx}{\linewidth}{l *{5}{Y}}
|
||||
\toprule
|
||||
$\mathbf{P_c \;\backslash\; P_m}$ & \textbf{0.001} & \textbf{0.010} & \textbf{0.050} & \textbf{0.100} & \textbf{0.200} \\
|
||||
\midrule
|
||||
\textbf{0.3} & 7.6 (16) & 9.5 (16) & 10.6 (23) & 18.0 (38) & -- \\
|
||||
\textbf{0.4} & 6.1 (13) & 10.0 (21) & 12.5 (25) & 67.1 (143) & -- \\
|
||||
\textbf{0.5} & 7.4 (15) & 7.9 (16) & 9.5 (20) & 79.7 (166) & -- \\
|
||||
\textbf{0.6} & 7.5 (16) & 10.1 (21) & -- & 51.1 (107) & -- \\
|
||||
\textbf{0.7} & 7.6 (16) & 28.6 (56) & 22.7 (48) & 43.7 (91) & -- \\
|
||||
\textbf{0.8} & 6.7 (14) & 10.4 (22) & 13.4 (25) & 23.0 (47) & -- \\
|
||||
\bottomrule
|
||||
\end{tabularx}
|
||||
\caption{Результаты для $N = 100$}
|
||||
\label{tab:pc_pm_results4}
|
||||
\end{table}
|
||||
|
||||
\newpage
|
||||
\phantom{text}
|
||||
|
||||
|
||||
|
||||
\newpage
|
||||
\section*{Заключение}
|
||||
|
||||
Reference in New Issue
Block a user