1
0

Proof of correctness Simple Algorithm

This commit is contained in:
Ruben
2019-05-23 19:37:34 +02:00
parent 32299f4f9c
commit 2366308ae1

View File

@@ -3,7 +3,7 @@
\usepackage[utf8]{inputenc} \usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc} \usepackage[T1]{fontenc}
\usepackage[dutch]{babel} \usepackage[dutch]{babel}
\usepackage[margin=2.56cm]{geometry} \usepackage[margin=2.4cm]{geometry}
\usepackage[linesnumbered, algoruled, lined]{algorithm2e} \usepackage[linesnumbered, algoruled, lined]{algorithm2e}
\usepackage{float} \usepackage{float}
\usepackage{wrapfig} \usepackage{wrapfig}
@@ -122,15 +122,33 @@
} }
\caption{Doorlooplijnalgoritme $O((N+S)log_2(N))$} \caption{Doorlooplijnalgoritme $O((N+S)log_2(N))$}
\end{algorithm} \end{algorithm}
\section{Beschrijving experimenten}\label{exp} \section{Beschrijving experimenten}\label{exp}
Om de complexiteit van de algoritmen na te gaan, voeren we experimenten op een toenemend aantal cirkels uit. We starten van 10 cirkels en verdubbelen steeds het aantal. Bij elk aantal voeren we 100 testen uit, meten we de tijd die het algoritme erover doet en nemen we het gemiddelde. Zo gaan we door tot ongeveer 10.000 cirkels voor het simpele algoritme en tot ongeveer 80.000 cirkels voor de andere algoritmes. Deze gemiddelde tijd kunnen we dan plotten in functie van het aantal cirkels en deze vergelijken met de grafiek van de complexiteit die we verwachten, met eventueel verschillende factoren. Ook kunnen we het beschouwen als een 'doubling ratio'-experiment en de verhouding tussen de opeenvolgende gemiddelde tijden berekenen. Deze 'doubling ratio' geeft ook een idee van de grootte-orde van de complexiteit. Zo geeft een verhouding van ongeveer 4 weer dat bij een verdubbeling de tijd met een factor 4 toeneemt. Dit wijst op een kwadratisch verband tussen het aantal cirkels en de tijd. Om de complexiteit van de algoritmen na te gaan, voeren we experimenten op een toenemend aantal cirkels uit. We starten met $10$ cirkels en verdubbelen steeds het aantal. Bij elk aantal voeren we $100$ testen uit, meten de tijd die het algoritme erover doet en nemen het gemiddelde. Dit herhalen we tot ongeveer $20.000$ cirkels voor het simpele algoritme en tot ongeveer $80.000$ cirkels voor de andere algoritmes, aangezien we dan voldoende informatie hebben om de complexiteit aan te tonen, zonder onnodig langdurige experimenten uit te moeten voeren. Deze gemiddelde tijd kunnen we dan plotten in functie van het aantal cirkels en deze vergelijken met de grafiek van de complexiteit die we verwachten.
De concrete resultaten zijn te vinden in Sectie \ref{comp}. \subsection{Alternatieve benadering}
Het enige probleem met het vergelijken van de voorgenoemde plots is dat we ze moeilijk op eenzelfde grafiek kunnen plaatsen omdat de grootte-orde van tijden ten opzichte van aantallen sterk verschillen. Om geen schaalfactor in te moeten voeren, kiezen we daarom voor een andere manier om het verloop van de tijd te bepalen, namelijk het doubling ratio experiment. Hierbij verdubbelen we steeds de invoerwaarde - in dit geval het aantal cirkels - en berekenen de verhouding waarmee de gemeten tijd elke keer toeneemt. Deze verhouding is de doubling ratio. We doen daarna hetzelfde voor de functie die de tijdscomplexiteit voorstelt, bijvoorbeeld $Nlog_2(N)$. Wanneer we van al deze verhoudingen het gemiddelde nemen, hebben we dan twee getallen om met elkaar te vergelijken, in plaats van grafieken.\\
Wanneer een getal kleiner is, duidt dit op een kleinere stijging bij een verdubbeling van de grootte van de invoer en dus ook een kleinere stijging van de grafiek ten opzichte van de grafiek met het grotere getal. Wanneer we dus een gelijkaardige waarde uitkomen voor de testwaarden en de complexiteitsfunctie, kunnen we besluiten dat de complexiteitsfunctie de complexiteit van de testwaarden voldoende benaderd. De concrete resultaten van onze experimenten zijn te vinden in Sectie \ref{comp}.
\section{Correctheid van het algoritme} \section{Correctheid van het algoritme}
Om de correctheid van de drie algoritmes na te gaan, bewijzen we eerst de correctheid van het simpele algoritme. Hierna voeren we een groot aantal testen uit waarbij zowel het simpele algoritme als een van de andere algoritme uitgevoerd worden. Na het uitvoeren vergelijken we de uitvoer met elkaar, waarin we nagaan of de resultaten op kleine afrondingsfouten na, hetzelfde zijn. Indien dit zo is voor het grote aantal testen, gaan we ervan uit dat het andere algoritme correct is. Om de correctheid van de drie algoritmes na te gaan, bewijzen we eerst de correctheid van het simpele algoritme. Hierna voeren we een groot aantal testen uit waarbij zowel het simpele algoritme als een van de andere algoritmes uitgevoerd worden. Na het uitvoeren vergelijken we de uitvoer met elkaar, waarin we nagaan of de resultaten op kleine afrondingsfouten na, hetzelfde zijn. Indien dit zo is voor het grote aantal testen, gaan we ervan uit dat het andere algoritme correct is.
\subsection{Correctheid simpel algoritme}
We zoeken alle onderlinge snijpunten tussen cirkels. Om na te gaan of algoritme \ref{algo1} dit op een correcte manier doet, beginnen we bij de eenvoudigste gevallen.
\begin{itemize}
\item In het geval dat er geen cirkels zijn, zal de lijst $S$ met snijpunten leeg zijn, aangezien de for-lus geen enkele keer uitgevoerd zal worden. Dit is het correcte resultaat.
\item In het geval van één cirkel wordt de buitenste for-lus slechts eenmaal uitgevoerd. De binnenste zal niet uitgevoerd worden aangezien er geen andere cirkels zijn. Aan $S$ zullen dus ook geen snijpunten toegevoegd worden, waardoor $S$ leeg zal zijn. Dit is ook het correcte resultaat.
\item In het geval van twee cirkels wordt de buitenste for-lus eerst uitgevoerd voor de eerste cirkel, de binnenste for-lus dan enkel voor de tweede cirkel. Indien er snijpunten zijn, worden deze aan $S$ toegevoegd. De buitenste for-lus wordt nog een keer voor de tweede cirkel uitgevoerd, maar er zijn geen andere cirkels meer. Enkel de snijpunten tussen de eerste en de tweede cirkel worden dus toegevoegd, indien die er zijn. Dit is ook het correcte resultaat.
\item Deze redenering kan doorgetrokken worden voor $N$ cirkels, waarna de correcte snijpunten bekomen worden.
\end{itemize}
\textbf{Bemerking:} Een laatste bemerking die wel nog gemaakt moet worden is dat wanneer drie cirkels in eenzelfde punt snijden, dit punt meermaals aan $S$ toegevoegd zal worden. Dit kan opgelost worden door van $S$ een set te maken (die geen dubbele waarden bijhoudt), of extra te controleren of een waarde zich al in $S$ bevindt.\\
Indien dit zo geïmplementeerd wordt, is de uitvoer van het simpele algoritme correct.
\section{Bespreking resultaten en rekentijden}\label{comp} \section{Bespreking resultaten en rekentijden}\label{comp}