Files
genetic-algorithms/lab1/report/report.tex
2025-09-11 22:37:22 +03:00

576 lines
36 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

\documentclass[a4paper, final]{article}
%\usepackage{literat} % Нормальные шрифты
\usepackage[14pt]{extsizes} % для того чтобы задать нестандартный 14-ый размер шрифта
\usepackage{tabularx}
\usepackage{booktabs}
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
\usepackage{amsmath}
\usepackage[left=25mm, top=20mm, right=20mm, bottom=20mm, footskip=10mm]{geometry}
\usepackage{ragged2e} %для растягивания по ширине
\usepackage{setspace} %для межстрочно го интервала
\usepackage{moreverb} %для работы с листингами
\usepackage{indentfirst} % для абзацного отступа
\usepackage{moreverb} %для печати в листинге исходного кода программ
\usepackage{pdfpages} %для вставки других pdf файлов
\usepackage{tikz}
\usepackage{graphicx}
\usepackage{afterpage}
\usepackage{longtable}
\usepackage{float}
% \usepackage[paper=A4,DIV=12]{typearea}
\usepackage{pdflscape}
% \usepackage{lscape}
\usepackage{array}
\usepackage{multirow}
\renewcommand\verbatimtabsize{4\relax}
\renewcommand\listingoffset{0.2em} %отступ от номеров строк в листинге
\renewcommand{\arraystretch}{1.4} % изменяю высоту строки в таблице
\usepackage[font=small, singlelinecheck=false, justification=centering, format=plain, labelsep=period]{caption} %для настройки заголовка таблицы
\usepackage{listings} %листинги
\usepackage{xcolor} % цвета
\usepackage{hyperref}% для гиперссылок
\usepackage{enumitem} %для перечислений
\newcommand{\specialcell}[2][l]{\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}
\setlist[enumerate,itemize]{leftmargin=1.2cm} %отступ в перечислениях
\hypersetup{colorlinks,
allcolors=[RGB]{010 090 200}} %красивые гиперссылки (не красные)
% подгружаемые языки — подробнее в документации listings (это всё для листингов)
\lstloadlanguages{ SQL}
% включаем кириллицу и добавляем кое−какие опции
\lstset{tabsize=2,
breaklines,
basicstyle=\footnotesize,
columns=fullflexible,
flexiblecolumns,
numbers=left,
numberstyle={\footnotesize},
keywordstyle=\color{blue},
inputencoding=cp1251,
extendedchars=true
}
\lstdefinelanguage{MyC}{
language=SQL,
% ndkeywordstyle=\color{darkgray}\bfseries,
% identifierstyle=\color{black},
% morecomment=[n]{/**}{*/},
% commentstyle=\color{blue}\ttfamily,
% stringstyle=\color{red}\ttfamily,
% morestring=[b]",
% showstringspaces=false,
% morecomment=[l][\color{gray}]{//},
keepspaces=true,
escapechar=\%,
texcl=true
}
\textheight=24cm % высота текста
\textwidth=16cm % ширина текста
\oddsidemargin=0pt % отступ от левого края
\topmargin=-1.5cm % отступ от верхнего края
\parindent=24pt % абзацный отступ
\parskip=5pt % интервал между абзацами
\tolerance=2000 % терпимость к "жидким" строкам
\flushbottom % выравнивание высоты страниц
% Настройка листингов
\lstset{
language=python,
extendedchars=\true,
inputencoding=utf8,
keepspaces=true,
% captionpos=b, % подписи листингов снизу
}
\begin{document} % начало документа
% НАЧАЛО ТИТУЛЬНОГО ЛИСТА
\begin{center}
\hfill \break
\hfill \break
\normalsize{МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ\\
федеральное государственное автономное образовательное учреждение высшего образования «Санкт-Петербургский политехнический университет Петра Великого»\\[10pt]}
\normalsize{Институт компьютерных наук и кибербезопасности}\\[10pt]
\normalsize{Высшая школа технологий искусственного интеллекта}\\[10pt]
\normalsize{Направление: 02.03.01 <<Математика и компьютерные науки>>}\\
\hfill \break
\hfill \break
\hfill \break
\hfill \break
\large{Лабораторная работа №1}\\
\large{по дисциплине}\\
\large{<<Генетические алгоритмы>>}\\
\large{Вариант 18}\\
% \hfill \break
\hfill \break
\end{center}
\small{
\begin{tabular}{lrrl}
\!\!\!Студент, & \hspace{2cm} & & \\
\!\!\!группы 5130201/20101 & \hspace{2cm} & \underline{\hspace{3cm}} &Тищенко А. А. \\\\
\!\!\!Преподаватель & \hspace{2cm} & \underline{\hspace{3cm}} & Большаков А. А. \\\\
&&\hspace{4cm}
\end{tabular}
\begin{flushright}
<<\underline{\hspace{1cm}}>>\underline{\hspace{2.5cm}} 2025г.
\end{flushright}
}
\hfill \break
% \hfill \break
\begin{center} \small{Санкт-Петербург, 2025} \end{center}
\thispagestyle{empty} % выключаем отображение номера для этой страницы
% КОНЕЦ ТИТУЛЬНОГО ЛИСТА
\newpage
\tableofcontents
\newpage
\section {Постановка задачи}
В данной работе были поставлены следующие задачи:
\begin{itemize}
\item Изучить теоретический материал;
\item Ознакомиться с вариантами кодирования хромосомы;
\item Рассмотреть способы выполнения операторов репродукции,
кроссинговера и мутации;
\item Выполнить индивидуальное задание на любом языке высокого
уровня с необходимыми комментариями и выводами
\end{itemize}
\textbf{Индивидуальное задание вариант 18:}
\textbf{Дано:} Функция одной переменной $f(x) = \frac{\sin(x)}{x^2}$; промежуток нахождения решения $x \in [3.1, 20.0]$.
\vspace{0.3cm}
\textbf{Требуется:}
\begin{enumerate}
\item Разработать простой генетический алгоритм для нахождения минимума данной функции в заданном промежутке;
\item Исследовать зависимость времени поиска, числа поколений (генераций) и точности нахождения решения от числа особей в популяции и вероятности кроссинговера и мутации;
\item Вывести на экран график функции с указанием найденного экстремума для каждого поколения;
\item Сравнить найденное решение с действительным.
\end{enumerate}
\textbf{Ограничения:}
\begin{enumerate}
\item $ \min f(x) = \frac{\sin(x)}{x^2} \approx -0.04957 $
\item Точность решения составляет 3 знака после запятой.
\end{enumerate}
\newpage
\section{Теоретические сведения}
Генетиче ские алгоритмы (ГА) используют принципы и терминологию, заимствованные у биологической науки генетики. В ГА каждая особь представляет потенциальное решение некоторой
проблемы. В классическом ГА особь кодируется строкой двоичных символов хромосомой, каждый
бит которой называется геном. Множество особей потенциальных решений составляет популяцию. Поиск (суб)оптимального решения проблемы выполняется в процессе эволюции популяции
- последовательного преобразования одного конечного множества решений в другое с помощью
генетических операторов репродукции, кроссинговера и мутации.
Предварительно простой ГА случайным образом генерирует начальную популяцию стрингов
(хромосом). Затем алгоритм генерирует следующее поколение (популяцию), с помощью трех основных генетических операторов:
\begin{enumerate}
\item Оператор репродукции (ОР);
\item Оператор скрещивания (кроссинговера, ОК);
\item Оператор мутации (ОМ).
\end{enumerate}
ГА работает до тех пор, пока не будет выполнено заданное количество поколений (итераций)
процесса эволюции или на некоторой генерации будет получено заданное качество или вследствие
преждевременной сходимости при попадании в некоторый локальный оптимум. На Рис.~\ref{fig:alg} представлен простой генетический алгоритм.
\begin{figure}[h!]
\centering
\includegraphics[width=0.9\linewidth]{img/alg.png}
\caption{Простой генетический алгоритм}
\label{fig:alg}
\end{figure}
\newpage
\subsection{Основная терминология в генетических алгоритмах}
\textbf{Ген} -- элементарный код в хромосоме $s_i$, называемый также знаком или детектором
(в классическом ГА $s_i = 0, 1$).
\textbf{Хромосома} -- упорядоченная последовательность генов в виде закодированной структуры
данных $S = (s_1, s_2, \ldots, s_n)$, определяющая решение (в простейшем случае двоичная
последовательность -- стринг, где $s_i = 0, 1$).
\textbf{Локус} -- местоположение (позиция, номер бита) данного гена в хромосоме.
\textbf{Аллель} -- значение, которое принимает данный ген (например, 0 или 1).
\textbf{Особь} -- одно потенциальное решение задачи (представляемое хромосомой).
\textbf{Популяция} -- множество особей (хромосом), представляющих потенциальные решения.
\textbf{Поколение} -- текущая популяция ГА на данной итерации алгоритма.
\textbf{Генотип} -- набор хромосом данной особи. В популяции могут использоваться как отдельные
хромосомы, так и целые генотипы.
\textbf{Генофонд} -- множество всех возможных генотипов.
\textbf{Фенотип} -- набор значений, соответствующий данному генотипу. Это декодированное множество
параметров задачи (например, десятичное значение $x$, соответствующее двоичному коду).
\textbf{Размер популяции $N$} -- число особей в популяции.
\textbf{Число поколений} -- количество итераций, в течение которых производится поиск.
\textbf{Селекция} -- совокупность правил, определяющих выживание особей на основе значений целевой функции.
\textbf{Эволюция популяции} -- чередование поколений, в которых хромосомы изменяют свои признаки,
чтобы каждая новая популяция лучше приспосабливалась к среде.
\textbf{Фитнесс-функция} -- функция полезности, определяющая меру приспособленности особи.
В задачах оптимизации она совпадает с целевой функцией или описывает близость к оптимальному решению.
\subsection{Генетические операторы}
\subsubsection{Оператор репродукции}
Репродукция -- процесс копирования хромосом в промежуточную популяцию для дальнейшего
``размножения'' в соответствии со значениями фитнесс-функции. В данной работе рассматривается метод колеса рулетки. Каждой хромосоме соответствует сектор, пропорциональный значению фитнесс-функции.
Хромосомы с большим значением имеют больше шансов попасть в следующее поколение.
\subsubsection{Оператор скрещивания (кроссинговера)}
Одноточечный кроссинговер выполняется следующим образом:
\begin{enumerate}
\item Из промежуточной популяции выбираются две хромосомы (родители).
\item Определяется случайная точка скрещивания $k \in [1, n-1]$, где $n$ -- длина хромосомы.
\begin{figure}[h!]
\centering
\includegraphics[width=0.5\linewidth]{img/cross1.png}
\label{fig:cross1}
\end{figure}
\item Две новые хромосомы (потомки) формируются путём обмена подстрок после точки $k$.
\begin{figure}[h!]
\centering
\includegraphics[width=0.35\linewidth]{img/cross2.png}
\label{fig:cross2}
\end{figure}
\end{enumerate}
\subsubsection{Оператор мутации}
Мутация применяется с малой вероятностью $P_M \approx 0.001$:
\begin{enumerate}
\item В хромосоме $A = a_1a_2 \ldots a_n$ выбирается случайная позиция $k$.
\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}
Результаты измерений представлены в таблицах \ref{tab:pc_pm_results}--\ref{tab:pc_pm_results4}. В ячейках указано усредненное время в миллисекундах нахождения минимума функции. В скобках указано усредненное количество поколений, за которое было найдено решение. Каждый эксперимент запускался 30 раз. Если в ячейке стоит прочерк, то это означает, что решение не было найдено за 200 поколений. Лучшее значение по времени выполнения для каждого размера популяции выделено жирным шрифтом.
\newcolumntype{Y}{>{\centering\arraybackslash}X}
\begin{table}[h!]
\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} & 11.5 (167) & 8.4 (123) & 5.4 (78) & 4.9 (71) & 3.3 (48) \\
\textbf{0.4} & 10.1 (144) & 7.1 (104) & 6.3 (92) & 4.7 (67) & 4.7 (67) \\
\textbf{0.5} & 11.4 (168) & 7.7 (112) & 5.4 (79) & 6.1 (83) & \textbf{3.1 (44)} \\
\textbf{0.6} & 11.0 (160) & 6.7 (97) & 4.9 (70) & 4.7 (67) & 5.3 (74) \\
\textbf{0.7} & 12.1 (174) & 9.3 (135) & 3.7 (52) & 4.7 (67) & 6.5 (92) \\
\textbf{0.8} & 8.7 (126) & 8.3 (119) & 3.9 (57) & 7.9 (113)& 4.4 (61) \\
\bottomrule
\end{tabularx}
\caption{Результаты для $N = 10$}
\label{tab:pc_pm_results}
\end{table}
\begin{table}[h!]
\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} & 14.7 (111) & 8.2 (62) & 4.9 (37) & 4.7 (35) & 8.7 (63) \\
\textbf{0.4} & 12.8 (95) & 7.3 (54) & 4.7 (35) & 4.3 (32) & 8.2 (61) \\
\textbf{0.5} & 10.5 (78) & 5.4 (40) & \textbf{2.2 (16)} & 5.5 (40) & 12.1 (89) \\
\textbf{0.6} & 14.0 (103) & 6.5 (48) & 3.4 (25) & 4.0 (30) & 14.0 (87) \\
\textbf{0.7} & 11.5 (84) & 6.2 (46) & 3.0 (22) & 3.2 (24) & 11.6 (83) \\
\textbf{0.8} & 9.2 (64) & 5.8 (41) & 2.5 (18) & 3.0 (22) & 11.2 (78) \\
\bottomrule
\end{tabularx}
\caption{Результаты для $N = 25$}
\label{tab:pc_pm_results2}
\end{table}
\begin{table}[h!]
\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.1 (26) & 5.2 (22) & 6.3 (26) & 11.6 (48) & 40.2 (147) \\
\textbf{0.4} & 6.1 (26) & 4.5 (19) & 5.2 (22) & 9.8 (40) & 37.2 (149) \\
\textbf{0.5} & 10.5 (44) & 4.9 (20) & 7.6 (28) & 17.1 (65) & 36.2 (144) \\
\textbf{0.6} & 7.5 (31) & \textbf{4.6 (19)} & 5.6 (23) & 18.8 (76) & 42.0 (158) \\
\textbf{0.7} & 7.6 (31) & 4.7 (20) & 7.6 (31) & 13.9 (55) & 34.3 (136) \\
\textbf{0.8} & 10.8 (44) & 5.0 (21) & 6.1 (24) & 13.9 (56) & 36.5 (145) \\
\bottomrule
\end{tabularx}
\caption{Результаты для $N = 50$}
\label{tab:pc_pm_results3}
\end{table}
\begin{table}[h!]
\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} & \textbf{7.6 (16)} & 9.5 (21) & 29.0 (60) & 62.9 (128) & -- \\
\textbf{0.4} & 8.0 (17) & 9.6 (21) & 31.5 (68) & 56.6 (120) & -- \\
\textbf{0.5} & 9.1 (20) & 9.2 (20) & 22.6 (48) & 59.4 (124) & -- \\
\textbf{0.6} & 17.8 (38) & 12.3 (26) & 30.0 (64) & 61.1 (128) & 95.3 (196) \\
\textbf{0.7} & 10.0 (22) & 14.3 (31) & 30.3 (64) & 49.1 (103) & -- \\
\textbf{0.8} & 16.4 (34) & 12.1 (25) & 31.4 (64) & 54.9 (114) & -- \\
\bottomrule
\end{tabularx}
\caption{Результаты для $N = 100$}
\label{tab:pc_pm_results4}
\end{table}
\newpage
\phantom{text}
\newpage
\phantom{text}
\subsection{Анализ результатов}
Ключевые наблюдения:
\begin{itemize}
\item При небольших популяциях ($N=10$) повышение $p_m$ ускоряет поиск; наилучшее время при $p_c=0.5$, $p_m=0.2$ (3.1 мс, 44 пок.).
\item Для $N=25$ оптимум при умеренной мутации $p_m\in[0.05,0.10]$; минимум времени при $p_c=0.5$, $p_m=0.05$ (2.2 мс, 16 пок.) — лучшее среди всех экспериментов.
\item Для $N=50$ лучшее время при $p_c=0.6$, $p_m=0.01$ (4.6 мс, 19 пок.). Слишком большая мутация ($p_m=0.2$) резко ухудшает результаты.
\item Для $N=100$ оптимальны низкие $p_m$; лучший результат при $p_c=0.3$, $p_m=0.001$ (7.6 мс, 16 пок.). При $p_m=0.2$ решение часто не находится за 200 поколений.
\item Рост $N$ не гарантирует ускорения: число поколений может уменьшаться, но суммарное время часто растёт из-за большей стоимости одной итерации.
\end{itemize}
Практические выводы:
\begin{itemize}
\item Для умеренных затрат времени и стабильной сходимости разумно выбирать $N\approx25\text{--}50$, $p_c\approx0.5\text{--}0.6$, $p_m\approx0.01\text{--}0.05$.
\item Оптимальное $p_m$ снижается с ростом $N$: при малых популяциях полезна более агрессивная мутация, при больших — слабая.
\item Слишком большие значения $p_m$ и $p_c$ могут разрушать хорошие решения и ухудшать сходимость; стоит избегать $p_m\ge 0.2$ и высоких $p_c$ при больших $N$.
\end{itemize}
\newpage
\section{Ответ на контрольный вопрос}
\textbf{Вопрос}: Какую роль в ГА играет оператор репродукции (ОР)?
\textbf{Ответ}: Оператор репродукции (ОР) в ГА играет роль селекции. Он выбирает наиболее приспособленных особей для дальнейшего участия в скрещивании и мутации. Это позволяет сохранить наиболее приспособленные особи и постепенно улучшить популяцию.
\newpage
\section*{Заключение}
\addcontentsline{toc}{section}{Заключение}
В ходе первой лабораторной работы:
\begin{enumerate}
\item Был изучен теоретический материал, основная терминология ГА, генетические операторы,
использующиеся в простых ГА;
\item Реализована программа на языке Python для нахождения минимума заданной функции;
\item Проведено исследование зависимости времени выполнения программы и поколения от мощности популяции и коэффициентов кроссинговера и мутации.
\end{enumerate}
\newpage
\section*{Список литературы}
\addcontentsline{toc}{section}{Список литературы}
\vspace{-1.5cm}
\begin{thebibliography}{0}
\bibitem{vostrov}
Методические указания по выполнению лабораторных работ к курсу «Генетические алгоритмы», 119 стр.
\end{thebibliography}
\end{document}