You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 4/report.tex
+65-12Lines changed: 65 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@
9
9
\usepackage{graphicx}
10
10
\usepackage{fontspec}
11
11
\usepackage{float}
12
-
%\usepackage{listings}
12
+
\usepackage{listings}
13
13
\setlength{\parskip}{10pt}
14
14
\setmainfont{texgyreheros}[
15
15
UprightFont = *-regular,
@@ -18,6 +18,10 @@
18
18
BoldItalicFont = *-bolditalic,
19
19
Extension = .otf
20
20
]
21
+
\lstset{
22
+
language=C++,
23
+
keepspaces=true
24
+
}
21
25
22
26
\title{Laboratório 4 — Emparelhamentos}
23
27
\author{Eduardo Menges Mattje}
@@ -26,15 +30,15 @@
26
30
\maketitle
27
31
28
32
\section{Introdução}
29
-
30
33
O algoritmo húngaro resolve problemas de emparelhamento para grafos bi-partidos ao buscar repetidamente por caminhos aumentantes de forma a tornar valores potenciais iguais à atribuição que minimiza (ou maximiza) a soma dos emparelhamentos.
31
34
A forma de encontrar os caminhos aumentantes escolhida para esta implementação foi a de Johnson, que utiliza Dijkstra para encontrar os menores caminhos.
32
35
33
36
\section{Detalhes de implementação}
37
+
\label{sec:implementation-details}
34
38
35
-
O algoritmo é iterativo, atribuindo um trabalho a um trabalhador a cada iteração.
39
+
O algoritmo é iterativo, atribuindo um trabalho a um trabalhador a cada iteração, chegando, portanto, na solução somente na última iteração.
36
40
37
-
Há um trabalhador extra, que se liga a todos os trabalhos no começo das iterações e inicializa a pilha (implementada com std::priority\_queue) do Dijkstra.
41
+
Há um trabalhador extra, que se liga a todos os trabalhos no começo das iterações e inicializa a pilha (implementada com \lstinline|std::priority_queue|) do Dijkstra.
38
42
Então, para cada outro trabalhador, empilha com as distâncias atualizadas considerando seus potenciais (valores do dual) e a relaxação em relação ao trabalhador atual, somente se essa for menor do que a distância já existente.
39
43
40
44
O Dijkstra se encerra ao encontrar o primeiro trabalhador que não possui trabalho associado.
@@ -44,30 +48,79 @@ \section{Detalhes de implementação}
44
48
45
49
\section{Ambiente de teste}
46
50
47
-
A máquina de teste possui Linux Mint 22.1, processador Intel i5-12450H e 16GB de memória RAM.
48
-
O compilador utilizado foi o GCC, versão 14.2, com todas as otimizações padrões habilitadas, e a implementação da biblioteca padrão do C++ é a libstdc++ versão 14.
51
+
A máquina de teste possui Windows 11, um processador AMD Ryzen 5 7600X e 32 GB de memória RAM. O compilador utilizado foi o Clang, versão 19.1.5, com todas as otimizações padrões habilitadas e utilizando a especificação do C++ 23.
49
52
50
53
\section{Plano de teste}
51
54
52
-
O gerador utilizado para gerar os grafos toma uma entrada $n$ e gera uma matriz $N \times N$ com valores no intervalo $[0, n \cdot n]$.
55
+
O gerador utilizado para gerar os grafos toma uma entrada $n$ e gera uma matriz de tamanho $n \times n$ com valores uniformemente distribuídos no intervalo $[0, n \cdot n]$.
56
+
57
+
Foram gerados $10$ testes para cada $n$ pertencente ao intervalo $[1000, 20000]$, incrementando $1000$ a cada passo. Para cada teste, mensurou-se:
58
+
59
+
\begin{itemize}
53
60
54
-
Foram gerados $10$ testes para cada $n$ pertencente ao intervalo $[1000, 20000]$, incrementando $1000$ a cada passo. Para cada teste, mensurou-se o tempo de execução.
Utilizando o algoritmo de Johnson para caminhos aumentantes, o algoritmo húngaro tem como complexidade $O(n(m+n \log n))$.
66
-
Como o gerador gera matrizes quadradas, $n = m$, logo a complexidade é $O(n^2 + n^2\log n)$.
67
-
Uma regressão não linear com coeficientes $a$ e $b$ para esses termos cabe aos dados, conforme apontado na figura \ref{fig:n_time}.
79
+
Utilizando o algoritmo de Johnson para caminhos aumentantes, o algoritmo húngaro tem como complexidade $O(n(m + n \log n))$.
80
+
Como o gerador gera matrizes quadradas, $m = n^2$, logo a complexidade esperada é $O(n^3 + n^2\log n)$.
81
+
Uma regressão para a equação $an^3 + bn^2\log n$ cabe aos dados, conforme apontado na figura \ref{fig:n_time}, tendo o coeficiente $R^2 = 0,9987$ muito próximo de 1.
82
+
83
+
\subsection{Laço principal}
84
+
85
+
\begin{figure}[H]
86
+
\centering
87
+
\caption{Iterações no laço principal em relação a $n$}
Conforme discutido em \ref{sec:implementation-details}, o Dijkstra para ao encontrar o primeiro trabalhador livre, e na $k$-ésima iteração, há $n - k + 1$ trabalhadores livres.
105
+
Desta forma, o número esperado de operações \lstinline|pop()| até encontrarmos o primeiro trabalhador livre é $\frac{n}{n - k + 1}$, o que, nas primeiras 50\% das iterações é $<= 2$, e mesmo nos 10\% finais o valor é $<= 10$, o que seria um tempo constante $\Theta(1)$.
106
+
107
+
Como percorremos todos os outros $n$ vizinhos no processo de relaxação, e como cada relaxação pode gerar um \lstinline|push()| no heap, temos $O(n)$ operações no heap.
108
+
Por fim, o laço principal do algoritmo faz $O(n^2)$ operações no heap, conforme observado nos dados coletados.
109
+
110
+
\subsection{Relaxações}
111
+
112
+
\begin{figure}[H]
113
+
\centering
114
+
\caption{Relaxações bem-sucedidas em função de $n$}
As relaxações são contadas somente quando bem-sucedidas ou seja, se realmente melhoram a distância, e só ocorrem caso o primeiro \lstinline|pop()| não ocorra com um trabalhador livre. Seguindo um raciocínio parecido com o item \ref{sec:heap_ops}, sabemos que a probabilidade de isso ocorrer é baixa, e cada vez que ocorre são realizadas no máximo $n$ relaxações.
120
+
Deste modo, $O(1) * O(n) = O(n)$, e contando as iterações do laço principal temos $O(n^2)$.
68
121
69
122
\section{Conclusão}
70
123
71
-
Com essa mensuração, conseguimos observar que a complexidade teórica é respeitada.
124
+
Com essa mensuração e os testes com matrizes quadradas, conseguimos observar que a complexidade teórica é respeitada para o caso médio, o que é reforçado pelos testes de regressão realizados e a probabilidade de emparelhamento dos trabalhadores livres.
0 commit comments