\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{xcolor}




% \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{Лабораторная работа №2}\\
        \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{Дано:} Функция Axis parallel hyper-ellipsoid function.

    Общая формула для n-мерного случая:
    $$f(\mathbf{x}) = \sum_{i=1}^{n} i \cdot x_i^2$$
    где $\mathbf{x} = (x_1, x_2, \ldots, x_n)$, область определения $x_i \in [-5.12, 5.12]$ для всех $i = 1, \ldots, n$.

    Для двумерного случая (n=2):
    $$f(x, y) = 1 \cdot x^2 + 2 \cdot y^2 = x^2 + 2y^2$$
    область нахождения решения $x \in [-5.12, 5.12], y \in [-5.12, 5.12]$.

    Глобальный минимум: $f(\mathbf{x}) = 0$ в точке $x_i = 0$ для всех $i = 1, \ldots, n$. Для двумерного случая: $\min f(x, y) = f(0, 0) = 0$.

    \vspace{0.3cm}
    \textbf{Требуется:}

    \begin{enumerate}
        \item Создать программу, использующую генетический алгоритм для нахождения минимума данной функции;
        \item Для n=2 вывести на экран график функции с указанием найденного экстремума и точек популяции. Предусмотреть возможность пошагового просмотра процесса поиска решения;
        \item Исследовать зависимость времени поиска, числа поколений (генераций), точности нахождения решения от основных параметров генетического алгоритма: числа особей в популяции, вероятности кроссинговера и мутации;
        \item Повторить процесс поиска решения для n=3, сравнить результаты и скорость работы программы.
    \end{enumerate}


    \newpage
    \section{Теоретические сведения}

    Генетические алгоритмы (ГА) используют принципы и терминологию, заимствованные у биологической науки – генетики. В ГА каждая особь представляет потенциальное решение некоторой
    проблемы. В классическом ГА особь кодируется строкой двоичных символов – хромосомой. Однако при работе с оптимизационными задачами в непрерывных пространствах вполне естественно представлять гены напрямую вещественными числами. В этом случае хромосома есть вектор вещественных чисел (real-coded алгоритмы). Их точность определяется исключительно разрядной сеткой ЭВМ. Длина хромосомы совпадает с длиной вектора-решения оптимизационной задачи, каждый ген отвечает за одну переменную. Генотип объекта становится идентичным его фенотипу.

    Множество особей – потенциальных решений составляет популяцию. Поиск (суб)оптимального решения проблемы выполняется в процессе эволюции популяции - последовательного преобразования одного конечного множества решений в другое с помощью генетических операторов репродукции, кроссинговера и мутации.

    Предварительно простой ГА случайным образом генерирует начальную популяцию стрингов
    (хромосом). Затем алгоритм генерирует следующее поколение (популяцию), с помощью трех основных генетических операторов:

    \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$) или как вектор вещественных чисел (real-coded представление).

    \textbf{Локус} -- местоположение (позиция, номер бита) данного гена в хромосоме.

    \textbf{Аллель} -- значение, которое принимает данный ген (например, 0 или 1).

    \textbf{Особь} -- одно потенциальное решение задачи (представляемое хромосомой).

    \textbf{Популяция} -- множество особей (хромосом), представляющих потенциальные решения.

    \textbf{Поколение} -- текущая популяция ГА на данной итерации алгоритма.

    \textbf{Генотип} -- набор хромосом данной особи. В популяции могут использоваться как отдельные 
    хромосомы, так и целые генотипы.

    \textbf{Генофонд} -- множество всех возможных генотипов.

    \textbf{Фенотип} -- набор значений, соответствующий данному генотипу. Это декодированное множество 
    параметров задачи (например, десятичное значение $x$, соответствующее двоичному коду).

    \textbf{Размер популяции $N$} -- число особей в популяции.

    \textbf{Число поколений} -- количество итераций, в течение которых производится поиск.

    \textbf{Селекция} -- совокупность правил, определяющих выживание особей на основе значений целевой функции.

    \textbf{Эволюция популяции} -- чередование поколений, в которых хромосомы изменяют свои признаки, 
    чтобы каждая новая популяция лучше приспосабливалась к среде.

    \textbf{Фитнесс-функция} -- функция полезности, определяющая меру приспособленности особи. 
    В задачах оптимизации она совпадает с целевой функцией или описывает близость к оптимальному решению.

    \subsection{Генетические операторы}

    \subsubsection{Оператор репродукции}

    Репродукция -- процесс копирования хромосом в промежуточную популяцию для дальнейшего 
    ``размножения'' в соответствии со значениями фитнесс-функции. В данной работе рассматривается метод колеса рулетки. Каждой хромосоме соответствует сектор, пропорциональный значению фитнесс-функции. 
    Хромосомы с большим значением имеют больше шансов попасть в следующее поколение.

    \subsubsection{Операторы кроссинговера для real-coded алгоритмов}

    Оператор скрещивания непрерывного ГА (кроссовер) порождает одного или нескольких потомков от двух хромосом. Требуется из двух векторов вещественных чисел получить новые векторы по определённым законам. Большинство real-coded алгоритмов генерируют новые векторы в окрестности родительских пар.

    Пусть $C_1=(c_{11},c_{21},\ldots,c_{n1})$ и $C_2=(c_{12},c_{22},\ldots,c_{n2})$ -- две хромосомы, выбранные оператором селекции для скрещивания.

    \textbf{Арифметический кроссовер (arithmetical crossover):} создаются два потомка $H_1=(h_{11},\ldots,h_{n1})$, $H_2=(h_{12},\ldots,h_{n2})$, где:
    $$h_{k1}=w \cdot c_{k1}+(1-w) \cdot c_{k2}$$
    $$h_{k2}=w \cdot c_{k2}+(1-w) \cdot c_{k1}$$
    где $k=1,\ldots,n$, $w$ -- весовой коэффициент из интервала $[0;1]$.

    \begin{figure}[h!]
       \centering
       \includegraphics[width=0.5\linewidth]{img/arithmetic_crossover.png}
       \caption{Арифметический кроссовер}
       \label{fig:arithmetic_crossover}
    \end{figure}

    \textbf{Геометрический кроссовер (geometrical crossover):} создаются два потомка $H_1=(h_{11},\ldots,h_{n1})$, $H_2=(h_{12},\ldots,h_{n2})$, где:
    $$h_{k1}=(c_{k1})^w \cdot (c_{k2})^{(1-w)}$$
    $$h_{k2}=(c_{k2})^w \cdot (c_{k1})^{(1-w)}$$
    где $w$ -- случайное число из интервала $[0;1]$.

    \begin{figure}[h!]
       \centering
       \includegraphics[width=0.5\linewidth]{img/geometric_crossover.png}
       \caption{Геометрический кроссовер}
       \label{fig:geometric_crossover}
    \end{figure}

    \textbf{Смешанный кроссовер (BLX-alpha crossover):} генерируется один потомок $H=(h_1,\ldots,h_k,\ldots,h_n)$, где $h_k$ -- случайное число из интервала $[c_{min}-I \cdot \alpha, c_{max}+I \cdot \alpha]$, $c_{min}=\min(c_{k1},c_{k2})$, $c_{max}=\max(c_{k1},c_{k2})$, $I=c_{max}-c_{min}$.

    \begin{figure}[h!]
       \centering
       \includegraphics[width=0.5\linewidth]{img/blx_crossover.png}
       \caption{Смешанный кроссовер}
       \label{fig:blx_crossover}
    \end{figure}

    \textbf{SBX кроссовер (Simulated Binary Crossover):} кроссовер, имитирующий двоичный, разработанный в 1995 году исследовательской группой под руководством K. Deb'а. Моделирует принципы работы двоичного оператора скрещивания, сохраняя важное свойство -- среднее значение функции приспособленности остаётся неизменным у родителей и их потомков.

    Создаются два потомка $H_k=(h_{1k}, \ldots, h_{jk}, \ldots, h_{nk})$, $k=1,2$, где:
    $$h_{j1} = 0.5[(1+\beta_k)c_{j1} + (1-\beta_k)c_{j2}]$$
    $$h_{j2} = 0.5[(1-\beta_k)c_{j1} + (1+\beta_k)c_{j2}]$$

    где $\beta_k \geq 0$ -- число, полученное по формуле:
    $$\beta_k = \begin{cases}
    (2u)^{\frac{1}{n+1}}, & \text{при } u \leq 0.5 \\
    \left(\frac{1}{2(1-u)}\right)^{\frac{1}{n+1}}, & \text{при } u > 0.5
    \end{cases}$$

    где $u \in (0,1)$ -- случайное число, распределённое по равномерному закону, $n \in [2,5]$ -- параметр кроссовера. Увеличение $n$ повышает вероятность появления потомка в окрестности родителей.

    \begin{figure}[h!]
       \centering
       \includegraphics[width=0.7\linewidth]{img/sbx_crossover.png}
       \caption{SBX кроссовер}
       \label{fig:sbx_crossover}
    \end{figure}

    \subsubsection{Операторы мутации для real-coded алгоритмов}

    В качестве оператора мутации наибольшее распространение получили: случайная и неравномерная мутация.

    \textbf{Случайная мутация (random mutation):} ген, подлежащий изменению, принимает случайное значение из интервала своего изменения.

    \textbf{Неравномерная мутация (non-uniform mutation):} из особи случайно выбирается точка $c_k$ с разрешёнными пределами изменения $[c_{kl}, c_{kr}]$. Точка меняется на:
    $$c_k' = \begin{cases}
    c_k + \Delta(t, c_{kr} - c_k), & \text{при } a = 1 \\
    c_k - \Delta(t, c_k - c_{kl}), & \text{при } a = 0
    \end{cases}$$

    где $a$ -- случайно выбранное направление изменения, $\Delta(t, y)$ -- функция, возвращающая случайную величину в пределах $[0, y]$ таким образом, что при увеличении $t$ среднее возвращаемое значение уменьшается:
    $$\Delta(t, y) = y \cdot r \cdot \left(1 - \frac{t}{T}\right)^b$$

    где $r$ -- случайная величина на интервале $[0, 1]$, $t$ -- текущая эпоха работы генетического алгоритма, $T$ -- общее разрешённое число эпох алгоритма, $b$ -- задаваемый пользователем параметр, определяющий степень зависимости от числа эпох.

    \newpage
    \section{Особенности реализации}
    В рамках работы создана мини-библиотека \texttt{gen.py} для экспериментов с real-coded
    генетическим алгоритмом для многомерных функций. Второй модуль
    \texttt{expirements.py} организует серийные эксперименты (перебор параметров,
    форматирование и сохранение результатов).

    \begin{itemize}
        \item \textbf{Кодирование особей}: каждая хромосома представлена как \texttt{np.ndarray} вещественных чисел (\texttt{Chromosome = NDArray[np.float64]}). Длина хромосомы соответствует размерности задачи оптимизации. Популяция -- список хромосом (\texttt{Population = list[Chromosome]}). Инициализация случайными векторами в заданном диапазоне:
        \begin{itemize}
            \item \texttt{initialize\_population(pop\_size: int, x\_min: Chromosome, x\_max:}\\ \texttt{Chromosome) -> Population}
        \end{itemize}
        \item \textbf{Фитнесс и минимум/максимум}: целевая функция принимает хромосому (вектор) и возвращает скалярное значение фитнесса. Для режима минимизации используется внутреннее преобразование при селекции (сдвиг на минимальное значение), что позволяет применять рулетку при отрицательных значениях:
        \begin{itemize}
            \item \texttt{eval\_population(population: Population, fitness\_func: FitnessFn) -> Fitnesses}
            \item Логика режима минимизации в \texttt{genetic\_algorithm(config: GARunConfig) -> GARunResult}
        \end{itemize}
        \item \textbf{Селекция (рулетка)}: вероятности нормируются после сдвига на минимальное значение в поколении (устойчиво к отрицательным фитнессам). Функция:
        \texttt{reproduction(population: Population, fitnesses: Fitnesses) -> Population}.
        \item \textbf{Кроссинговер}: реализованы арифметический и геометрический кроссоверы для real-coded алгоритмов. Кроссинговер выполняется попарно по перемешанной популяции с вероятностью $p_c$. Функции:
        \begin{itemize}
            \item \texttt{arithmetical\_crossover\_fn(p1: Chromosome, p2: Chromosome, w: float) -> tuple[Chromosome, Chromosome]}
            \item \texttt{geometrical\_crossover\_fn(p1: Chromosome, p2: Chromosome, w: float) -> tuple[Chromosome, Chromosome]}
            \item \texttt{crossover(population: Population, pc: float, crossover\_fn: CrossoverFn) -> Population}
        \end{itemize}
        \item \textbf{Мутация}: случайная мутация -- с вероятностью $p_m$ на хромосому изменяется один случайно выбранный ген на случайное значение из допустимого диапазона. Функции:
        \begin{itemize}
            \item \texttt{build\_random\_mutation\_fn(x\_min: Chromosome, x\_max: Chromosome) -> MutationFn}
            \item \texttt{mutation(population: Population, pm: float, mutation\_fn: MutationFn) -> Population}
        \end{itemize}

        \item \textbf{Критерий остановки}: поддерживается критерий по среднему значению фитнесс-функции в популяции и максимальному количеству поколений. Хранится история всех поколений. Проверка выполняется в функции:
        
        \texttt{genetic\_algorithm(config: GARunConfig) -> GARunResult}.
        \item \textbf{Визуализация}: для двумерных функций реализованы 3D-графики поверхности и 2D-контурные графики с отображением популяций. Функции:
        \begin{itemize}
            \item \texttt{plot\_fitness\_surface(fitness\_func: FitnessFn, x\_min: Chromosome, x\_max: Chromosome, ax: Axes3D)}
            \item \texttt{plot\_fitness\_contour(fitness\_func: FitnessFn, x\_min: Chromosome, x\_max: Chromosome, ax: Axes)}
            \item \texttt{save\_generation(generation: Generation, history: list[Generation], config: GARunConfig)}
        \end{itemize}
        \item \textbf{Измерение времени}: длительность вычислений возвращается в миллисекундах как часть \texttt{GARunResult.time\_ms}.
        \item \textbf{Файловая организация}: результаты экспериментов сохраняются иерархически в структуре \texttt{experiments/N/} с таблицами результатов в формате CSV. Задействованные функции:
        \begin{itemize}
            \item \texttt{clear\_results\_directory(results\_dir: str) -> None}
            \item \texttt{run\_single\_experiment(pop\_size: int, pc: float, pm: float) -> tuple[float, float, float, float]}
            \item \texttt{run\_experiments\_for\_population(pop\_size: int) -> PrettyTable}
        \end{itemize}
    \end{itemize}

    В модуле \texttt{expirements.py} задаётся целевая функция axis parallel hyper-ellipsoid: $f(x, y) = x^2 + 2y^2$ и параметры экспериментов.
    Серийные запуски и сохранение результатов реализованы в функциях \texttt{run\_single\_experiment}, \texttt{run\_experiments\_for\_population} и \texttt{main}.

    \newpage
    \section{Результаты работы}
    На Рис.~\ref{fig:gen1}--\ref{fig:lastgen} представлены результаты работы генетического алгоритма со следующими параметрами:
    \begin{itemize}
        \item $N = 25$ -- размер популяции.
        \item $p_c = 0.5$ -- вероятность кроссинговера.
        \item $p_m = 0.01$ -- вероятность мутации.
        \item Алгоритм останавливался, если лучшее значение фитнеса не изменялось $10$ поколений подряд.
        \item Использован арифметический кроссовер для real-coded хромосом.
    \end{itemize}

    Популяция постепенно консолидируется вокруг глобального минимума в точке $(0, 0)$. Лучшая особь была найдена на поколнении №9 (см. Рис.~\ref{fig:gen9}), но судя по всему она подверглась мутации или кроссинговеру, поэтому алгоритм не остановился. На поколении №19 (см. Рис.~\ref{fig:lastgen}) было получено значение фитнеса $0.0201$, которое затем повторялось в следующих 10 поколениях. Алгоритм остановился на поколлении №29. На графиках показаны 2D-контурный график (a) и 3D-поверхность целевой функции с точками популяции текущего поколения (b) и (c).

    \begin{figure}[h!]
       \centering
       \includegraphics[width=1\linewidth]{img/results/generation_001.png}
       \caption{График целевой функции и популяции поколения №1}
       \label{fig:gen1}
    \end{figure}

    \begin{figure}[h!]
       \centering
       \includegraphics[width=1\linewidth]{img/results/generation_002.png}
       \caption{График целевой функции и популяции поколения №2}
       \label{fig:gen2}
    \end{figure}

    \begin{figure}[h!]
       \centering
       \includegraphics[width=1\linewidth]{img/results/generation_003.png}
       \caption{График целевой функции и популяции поколения №3}
       \label{fig:gen3}
    \end{figure}


    \begin{figure}[h!]
       \centering
       \includegraphics[width=1\linewidth]{img/results/generation_005.png}
       \caption{График целевой функции и популяции поколения №5}
       \label{fig:gen5}
    \end{figure}

    \begin{figure}[h!]
       \centering
       \includegraphics[width=1\linewidth]{img/results/generation_007.png}
       \caption{График целевой функции и популяции поколения №7}
       \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}
       \caption{График целевой функции и популяции поколения №10}
       \label{fig:gen10}
    \end{figure}

    \begin{figure}[h!]
       \centering
       \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}


    \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}

    Измерения были проведены для двух критериев остановки:
    \begin{itemize}
        \item Лучшее значение фитнеса не изменялось 10 поколений.
        \item Лучшее значение фитнеса достигло заданного значения $0.005$.
    \end{itemize}

    \subsubsection*{Результаты для первого критерия остановки}

    Результаты измерений представлены в таблицах \ref{tab:pc_pm_results_10}--\ref{tab:pc_pm_results_100}. В ячейках указано время в миллисекундах нахождения минимума функции. В скобках указано количество поколений, за которое было найдено решение. Во второй строке указано усреднённое по всем запускам лучшее значение фитнеса. Если в ячейке стоит прочерк, то это означает, что решение не было найдено за 200 поколений. Лучшее значение по времени выполнения и по значению фитнеса для каждого размера популяции выделено цветом и жирным шрифтом.

    \newcolumntype{Y}{>{\centering\arraybackslash}X}
    % Автоматически сгенерированные LaTeX таблицы
% Лучший результат по времени и по фитнесу выделены жирным отдельно
% Убедитесь, что подключен \usepackage{tabularx}
% ВНИМАНИЕ: Убедитесь, что подключен \usepackage{xcolor} для цветового выделения
% Используйте \newcolumntype{Y}{>{\centering\arraybackslash}X} перед таблицами

\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 10$}
    \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} & 1.3 (13) 0.36281 & 1.7 (18) 7.55685 & 1.2 (13) 1.55537 & \textcolor{magenta}{\textbf{1.0 (11)}} 1.78411 & 9.4 (87) 0.04271 \\
    \textbf{0.4} & 1.3 (14) 0.03913 & 1.6 (17) 0.02868 & 1.3 (13) 0.36232 & 2.1 (20) 0.10641 & — \\
    \textbf{0.5} & 1.4 (15) 0.87081 & 1.7 (18) 1.71634 & 2.3 (21) 0.10401 & 3.4 (25) 0.00461 & — \\
    \textbf{0.6} & 2.8 (19) 0.06375 & 1.8 (13) 0.72202 & 2.9 (22) 0.01473 & 3.4 (25) 0.01162 & 29.4 (184) \textcolor{magenta}{\textbf{0.00033}} \\
    \textbf{0.7} & 1.5 (15) 1.25409 & 2.3 (22) 8.67464 & 1.9 (18) 0.13319 & 8.6 (66) 0.00078 & 8.9 (48) 0.11136 \\
    \textbf{0.8} & 1.9 (15) 3.10415 & 1.4 (13) 1.09275 & 2.1 (19) 0.43094 & 6.4 (54) 0.00191 & — \\
    \bottomrule
    \end{tabularx}
    \label{tab:pc_pm_results_10}
\end{table}


\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 25$}
    \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} & 3.0 (18) 0.16836 & \textcolor{magenta}{\textbf{2.2 (13)}} 0.04190 & 4.7 (27) 0.00544 & — & — \\
    \textbf{0.4} & 4.1 (24) 0.00808 & 4.6 (26) 0.01101 & 5.8 (31) 0.02330 & 3.8 (19) 0.05414 & — \\
    \textbf{0.5} & 3.1 (17) 0.05259 & 5.0 (26) 0.47018 & 27.8 (138) \textcolor{magenta}{\textbf{0.00024}} & 14.5 (67) 0.00312 & — \\
    \textbf{0.6} & 6.1 (31) 0.01033 & 6.8 (34) 0.00148 & — & — & — \\
    \textbf{0.7} & 4.1 (21) 0.00107 & 3.2 (16) 0.32522 & — & — & — \\
    \textbf{0.8} & 23.9 (109) 0.00352 & 15.8 (72) 0.11662 & 28.3 (123) 0.00038 & — & — \\
    \bottomrule
    \end{tabularx}
    \label{tab:pc_pm_results_25}
\end{table}


\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 50$}
    \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.9 (51) 0.05874 & 19.3 (59) \textcolor{magenta}{\textbf{0.00003}} & 36.7 (113) 0.00190 & — & — \\
    \textbf{0.4} & 12.5 (40) 0.01955 & \textcolor{magenta}{\textbf{5.6 (18)}} 0.00022 & — & — & — \\
    \textbf{0.5} & 65.0 (195) 0.04790 & 26.4 (78) 0.01673 & — & — & — \\
    \textbf{0.6} & 16.4 (47) 0.00329 & 18.5 (50) 0.00065 & — & — & — \\
    \textbf{0.7} & 51.0 (137) 0.00120 & 59.3 (158) 0.00010 & — & — & — \\
    \textbf{0.8} & 48.8 (126) 0.01393 & 67.6 (172) 0.00650 & — & — & — \\
    \bottomrule
    \end{tabularx}
    \label{tab:pc_pm_results_50}
\end{table}


\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 100$}
    \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} & 24.2 (44) 0.00110 & 17.9 (32) 0.00113 & \textcolor{magenta}{\textbf{17.6 (29)}} 0.00193 & — & — \\
    \textbf{0.4} & 30.7 (51) 0.00173 & — & — & — & — \\
    \textbf{0.5} & 27.4 (43) 0.00016 & — & — & — & — \\
    \textbf{0.6} & 20.4 (31) 0.00115 & 129.8 (186) 0.00025 & — & — & — \\
    \textbf{0.7} & 115.4 (162) 0.00002 & — & — & — & — \\
    \textbf{0.8} & 106.5 (143) \textcolor{magenta}{\textbf{0.00001}} & — & — & — & — \\
    \bottomrule
    \end{tabularx}
    \label{tab:pc_pm_results_100}
\end{table}

    \newpage
    \subsubsection*{Результаты для второго критерия остановки}

Результаты измерений представлены в таблицах \ref{tab:1_pc_pm_results_10}--\ref{tab:1_pc_pm_results_100}.


% Автоматически сгенерированные LaTeX таблицы
% Лучший результат по времени и по фитнесу выделены жирным отдельно
% Убедитесь, что подключен \usepackage{tabularx}
% ВНИМАНИЕ: Убедитесь, что подключен \usepackage{xcolor} для цветового выделения
% Используйте \newcolumntype{Y}{>{\centering\arraybackslash}X} перед таблицами

\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 10$}
    \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} & — & — & — & 15.6 (155) 0.00063 & 7.8 (69) 0.00409 \\
    \textbf{0.4} & — & — & — & 8.9 (81) \textcolor{magenta}{\textbf{0.00038}} & \textcolor{magenta}{\textbf{4.6 (40)}} 0.00317 \\
    \textbf{0.5} & — & — & 8.7 (85) 0.00199 & — & 16.5 (140) 0.00453 \\
    \textbf{0.6} & — & — & — & 8.9 (77) 0.00310 & 14.3 (117) 0.00082 \\
    \textbf{0.7} & — & — & 8.2 (70) 0.00089 & 5.6 (49) 0.00431 & 7.1 (58) 0.00047 \\
    \textbf{0.8} & — & 19.7 (180) 0.00397 & — & 5.0 (42) 0.00494 & 5.5 (44) 0.00357 \\
    \bottomrule
    \end{tabularx}
    \label{tab:1_pc_pm_results_10}
\end{table}


\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 25$}
    \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} & 1.1 (7) 0.00277 & 30.0 (173) \textcolor{magenta}{\textbf{0.00059}} & — & 2.2 (12) 0.00191 & 30.2 (139) 0.00200 \\
    \textbf{0.4} & 1.8 (10) 0.00384 & — & 12.2 (63) 0.00164 & 6.6 (33) 0.00354 & 18.5 (82) 0.00224 \\
    \textbf{0.5} & — & — & 12.5 (58) 0.00233 & 2.3 (11) 0.00196 & 17.1 (73) 0.00116 \\
    \textbf{0.6} & — & 30.9 (151) 0.00265 & 36.7 (175) 0.00146 & 10.0 (46) 0.00449 & 5.7 (23) 0.00281 \\
    \textbf{0.7} & 1.1 (6) 0.00472 & — & 0.8 (4) 0.00233 & 3.9 (17) 0.00112 & \textcolor{magenta}{\textbf{0.3 (2)}} 0.00371 \\
    \textbf{0.8} & — & — & 10.3 (43) 0.00137 & 7.7 (32) 0.00379 & 10.5 (41) 0.00155 \\
    \bottomrule
    \end{tabularx}
    \label{tab:1_pc_pm_results_25}
\end{table}


\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 50$}
    \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} & 3.7 (12) 0.00354 & 3.4 (9) 0.00075 & 23.7 (73) 0.00467 & 4.9 (14) 0.00043 & 2.1 (6) 0.00029 \\
    \textbf{0.4} & 3.6 (12) 0.00270 & 4.2 (13) 0.00061 & 9.2 (25) 0.00251 & 18.2 (51) 0.00490 & 6.6 (16) 0.00063 \\
    \textbf{0.5} & 4.0 (10) 0.00099 & 48.8 (141) 0.00324 & 3.8 (11) 0.00087 & 14.7 (39) \textcolor{magenta}{\textbf{0.00017}} & 1.2 (3) 0.00115 \\
    \textbf{0.6} & 1.6 (5) 0.00070 & 51.6 (139) 0.00217 & 4.7 (13) 0.00294 & 2.6 (7) 0.00397 & 11.5 (27) 0.00053 \\
    \textbf{0.7} & — & — & 2.6 (7) 0.00144 & 3.5 (9) 0.00182 & \textcolor{magenta}{\textbf{1.1 (3)}} 0.00072 \\
    \textbf{0.8} & 4.1 (11) 0.00240 & 3.5 (8) 0.00380 & 2.5 (6) 0.00422 & 2.7 (7) 0.00126 & 4.3 (10) 0.00060 \\
    \bottomrule
    \end{tabularx}
    \label{tab:1_pc_pm_results_50}
\end{table}


\begin{table}[h!]
    \centering
    \small
    \caption{Результаты для $N = 100$}
    \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} & 9.3 (17) 0.00451 & 6.0 (11) 0.00344 & 10.0 (17) 0.00343 & 5.3 (8) 0.00046 & 9.8 (14) 0.00412 \\
    \textbf{0.4} & 5.7 (9) \textcolor{magenta}{\textbf{0.00005}} & 8.4 (14) 0.00108 & 3.5 (6) 0.00254 & 4.0 (6) 0.00186 & 6.5 (9) 0.00283 \\
    \textbf{0.5} & 3.8 (6) 0.00019 & 4.9 (8) 0.00103 & 3.6 (6) 0.00260 & 11.1 (16) 0.00204 & 7.5 (10) 0.00374 \\
    \textbf{0.6} & — & 6.5 (10) 0.00107 & 3.6 (5) 0.00079 & \textcolor{magenta}{\textbf{0.9 (2)}} 0.00324 & 10.1 (13) 0.00044 \\
    \textbf{0.7} & 1.7 (3) 0.00106 & 6.6 (10) 0.00489 & 4.1 (6) 0.00031 & 12.4 (16) 0.00240 & 4.8 (6) 0.00276 \\
    \textbf{0.8} & 5.0 (7) 0.00387 & 58.4 (77) 0.00453 & 7.8 (10) 0.00259 & 11.2 (13) 0.00210 & 6.1 (7) 0.00493 \\
    \bottomrule
    \end{tabularx}
    \label{tab:1_pc_pm_results_100}
\end{table}

        
    \newpage
    \phantom{text}
    \newpage
    \phantom{text}
    \newpage
    \phantom{text}
    \subsection{Анализ результатов}
    
    \subsubsection*{Обоснование применения двух критериев остановки}
    
    В исследовании использовались два различных критерия остановки алгоритма, поскольку критерий по количеству поколений (отсутствие улучшения в течение 10 поколений) не всегда обеспечивал достижение достаточно хороших значений фитнеса, особенно для малых популяций. Это делало некорректным сравнение эффективности различных комбинаций параметров только по времени выполнения. Введение второго критерия (достижение фитнеса 0.005) позволило получить более объективную оценку скорости нахождении качественных решений.

    \subsubsection*{Первый критерий остановки (отсутствие улучшения в течение 10 поколений)}

    При использовании первого критерия остановки наблюдаются следующие закономерности:

    \begin{itemize}
        \item \textbf{Малые популяции ($N=10$):} Оптимальный баланс достигается при умеренных значениях параметров. Лучший результат по времени показывает комбинация $p_c=0.3$, $p_m=0.1$ (1.0 мс, 11 поколений), однако лучшее значение фитнеса достигается при $p_c=0.6$, $p_m=0.2$ (0.00033). Качество решений существенно варьируется.
        
        \item \textbf{Средние популяции ($N=25$):} Демонстрируют высокую эффективность при низких значениях мутации. Минимальное время выполнения достигается при $p_c=0.3$, $p_m=0.01$ (2.2 мс, 13 поколений), а наилучший фитнес — при $p_c=0.5$, $p_m=0.05$ (0.00024).
        
        \item \textbf{Большие популяции ($N=50, 100$):} Характеризуются критической чувствительностью к высоким значениям мутации и демонстрируют заметное улучшение качества фитнеса. Для $N=50$ лучшие результаты при $p_c=0.4$, $p_m=0.01$ (5.6 мс по времени) и $p_c=0.3$, $p_m=0.01$ (фитнес 0.00003). Для $N=100$ работают только комбинации с очень низкой мутацией, но обеспечивают отличное качество (фитнес до 0.00001).
        
        \item \textbf{Проблема сходимости:} С увеличением размера популяции значительно возрастает количество комбинаций параметров, не обеспечивающих сходимость за 200 поколений, особенно при $p_m \geq 0.05$.
    \end{itemize}

    \subsubsection*{Второй критерий остановки (достижение фитнеса 0.005)}

    Использование фиксированного порога фитнеса демонстрирует принципиально иную картину и подтверждает правильность введения альтернативного критерия:

    \begin{itemize}
        \item \textbf{Инверсия требований к мутации:} В отличие от первого критерия, здесь малые популяции требуют более высоких значений мутации для достижения целевого фитнеса. Для $N=10$ большинство комбинаций с $p_m \leq 0.01$ вообще не достигают порога, что подтверждает проблему качества при первом критерии.
        
        \item \textbf{Лучшие результаты больших популяций:} Популяции $N=50$ и $N=100$ показывают отличные результаты — достижение высокого качества за минимальное время: $N=50$ при $p_c=0.7$, $p_m=0.2$ (1.1 мс, 3 поколения) и $N=100$ при $p_c=0.6$, $p_m=0.1$ (0.9 мс, 2 поколения).
    \end{itemize}

    
    \newpage
    \section{Ответ на контрольный вопрос}

    \textbf{Вопрос}: Опишите понятие «оптимизационная задача».

    \textbf{Ответ}: Оптимизационная задача — это математическая задача, в которой требуется найти такие значения переменных, при которых некоторая функция, называемая целевой, принимает наибольшее или наименьшее значение. При этом искомые значения должны удовлетворять определённым условиям или ограничениям, задающим допустимую область решений. Цель оптимизации заключается в выборе наилучшего варианта среди множества возможных с точки зрения заданного критерия эффективности.

    Такие задачи широко применяются в науке, технике, экономике и управлении для рационального распределения ресурсов, минимизации затрат или максимизации прибыли. В зависимости от формы целевой функции и ограничений оптимизационные задачи могут быть линейными, нелинейными, дискретными или непрерывными. Их решение позволяет принимать обоснованные решения и повышать эффективность различных процессов и систем.
        

    \newpage
    \section*{Заключение}
    \addcontentsline{toc}{section}{Заключение}

    В ходе второй лабораторной работы была успешно решена задача оптимизации функции Axis parallel hyper-ellipsoid function с использованием генетических алгоритмов:

    \begin{enumerate}
        \item Изучен теоретический материал о real-coded генетических алгоритмах и различных операторах кроссинговера и мутации;
        \item Создана программная библиотека на языке Python с реализацией арифметического и геометрического кроссоверов, случайной мутации и селекции методом рулетки;
        \item Проведено исследование влияния параметров ГА на эффективность поиска для популяций размером 10, 25, 50 и 100 особей;
    \end{enumerate}

\newpage
\section*{Список литературы}
\addcontentsline{toc}{section}{Список литературы}

\vspace{-1.5cm}
\begin{thebibliography}{0}
    \bibitem{vostrov}
    Методические указания по выполнению лабораторных работ к курсу «Генетические алгоритмы», 119 стр.
\end{thebibliography}

\end{document}