Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 43 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,33 @@ Mesurez combien de temps prend python à générer un tableau composés de :
- ...
- 10 000 000 entrées

*Time to generate array of 1000000 numbers: 0.7310469150543213*
<br>
*Time to generate array of 2000000 numbers: 1.1986496448516846*
<br>
*Time to generate array of 3000000 numbers: 1.6297695636749268*
<br>
*Time to generate array of 4000000 numbers: 2.190520763397217*
<br>
*Time to generate array of 5000000 numbers: 2.74592661857605*
<br>
*Time to generate array of 6000000 numbers: 3.341700553894043*
<br>
*Time to generate array of 7000000 numbers: 3.849144697189331*
<br>
*Time to generate array of 8000000 numbers: 4.3899266719818115*
<br>
*Time to generate array of 9000000 numbers: 4.8259007930755615*
<br>
*Time to generate array of 10000000 numbers: 5.432266473770142*

**Astuce** : vous pouvez écrire les nombres avec des underscores pour mieux les lire : `1_000_000`

Sur un tableur, générez un tableau permettant de visualiser le temps d'éxécution en fonction de la taille de l'entrée.

Comment vous semble évoluer la courbe ? Observez bien les différentes courbes du graphique ci-dessous. Quelle est la plus ressemblante à notre situation ? *Écrivez votre réponse ici*
<img src="graphs/Generation-times.png">

Comment vous semble évoluer la courbe ? Observez bien les différentes courbes du graphique ci-dessous. Quelle est la plus ressemblante à notre situation ? *La courbe semble évoluer de façon linéaire. La courbe la plus ressemblante est la courbe n log n.*

<img src="img/o.webp" width="400">

Expand All @@ -73,9 +95,8 @@ Comment vous semble évoluer la courbe ? Observez bien les différentes courbes

Observez attentivement l'animation de tri par sélection ci-dessous pour en comprendre le fonctionnement.

<img src="img/selection.gif">

Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *Écrivez votre réponse ici*
Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ?
*On sélectionne la première valeur non triée du tableau, et on la marque comme étant la plus petite valeur du tableau. On parcourt les autres valeurs en sélectionannt une valeur plus petite s'il en existe une. Ensuite, on place la plus petite valeur au début du tableau et on répète toute l'opération avec la deuxième valeur du tableau jusqu'à ce qu'il soit trié.*

Puis implémentez l'algorithme en python dans la fonction `sort` du fichier `sort/selection.py`. Vérifiez son bon fonctionnement en éxécutant le fichier `python3 -m unittest`. Le test correspondant au tri par sélection doit passer.

Expand All @@ -88,15 +109,19 @@ Mesurez le temps d'éxécution pour un tableau de :

Tracez le graphique correspondant.

Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Écrivez votre réponse ici*
<img src="graphs/selection-sort.png">

<img src="img/selection.gif">

Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Le tri par sélection semble être de complexité O(n^2) et cela semble cohérent avec les deux boucles for imbriquées dans mon code.*

### 2. Tri par insertion

Observez attentivement l'animation de tri par insertion ci-dessous pour en comprendre le fonctionnement.

<img src="img/insertion.gif">

Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *Écrivez votre réponse ici*
Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *On prend la première valeur non traitée du tableau et on parcourt les valeurs vers la gauche jusqu'à temps d'insérer la valeur sélectionnée si elle est plus petite que la valeur parcourue.*

Puis implémentez l'algorithme en python dans la fonction `sort` du fichier `sort/insertion.py`. Utilisez les tests automatiques pour vérifier votre implémentation.

Expand All @@ -109,7 +134,9 @@ Mesurez le temps d'éxécution pour un tableau de :

Tracez le graphique correspondant.

Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Écrivez votre réponse ici*
<img src="graphs/insertion-sort.png">

Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Le tri par insertion semble avoir une complexité en O(n^2). Cela est logique par rapport au code implémenté (une boucle for et une boucle while).*

### 3. Tri par fusion

Expand Down Expand Up @@ -154,7 +181,7 @@ Observez bien le schéma suivant : il représente le concept du tri par fusion.

Cet algorithme est de type "diviser pour régner".

Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *Écrivez votre réponse ici*
Écrivez en français classique ce que vous voyez. Quel est le fonctionnement ? Comment l'expliqueriez-vous à quelqu'un ? *Le tableau en entrée est séparé en deux jusqu'à ce que les tableaux ne soient que de taille 1, puis ils sont fusionnés deux à deux jusqu'à obtenir un tableau trié de la taille d'origine.*

Complétez la fonction `sort` du fichier `sort/fusion.py` en suivant les instructions suivantes.

Expand All @@ -174,16 +201,22 @@ Mesurez le temps d'éxécution pour un tableau de :

Tracez le graphique correspondant.

Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Écrivez votre réponse ici*
<img src="graphs/fusion-sort.png">

Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? *Le tri par fusion semble avoir une complexité en O(n log n). Cela semble logique par rapport à monde code.*

Question bonus : Y a-t-il des tailles de tableaux pour lesquelles le tri par fusion n'est pas aussi rapide que les précédents tris abordés ? *Écrivez votre réponse ici*
Question bonus : Y a-t-il des tailles de tableaux pour lesquelles le tri par fusion n'est pas aussi rapide que les précédents tris abordés ? *Le tri par fusion est en général plus rapide que l'insertion et la sélection sur les tableaux de très grandes tailles. Sur les petits tableaux, il est moins rapide.*

### 4. sort()

Bien que tout cela soit fascinant, Python possède sa propre méthode de tri : `sort()`.

Une dernière fois, analysez le temps d'exécution et découvrez si python fait mieux que nos implémentations rudimentaires ;)

*Il est en effet bien plus rapide : *

<img src="graphs/python-built-in-sort.png">

## Pour rendre ce TP

Merci de faire une Pull Request vers ce repository.
Expand Down
70 changes: 69 additions & 1 deletion __main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
import sort.range
import sort.selection as selection
import matplotlib.pyplot as plt
import sort.insertion as insertion
import time
import sort.fusion as fusion


def get_1k_10k_arrays_execution_times(sorting_method) -> tuple[list[float],
list[int]]:
"""Returns the execution times and array sizes of
generated arrays of 1k to 10k numbers with a step of 1k."""

times: list[float] = []
sizes: list[int] = []

for i in range(1, 11):
array_size: int = 1000*i
array: list[int] = sort.range.generate_array_of_number(array_size)
execution_time: float = get_execution_time(array, sorting_method)
print(f"Execution time for {array_size} numbers: {execution_time} s")
sizes.append(array_size)
times.append(execution_time)

return times, sizes


def get_execution_time(array: list[int], sorting_method) -> float:
"""Returns the execution time for sorting the given array
with given sorting method."""

start: float = time.time()
sorting_method(array)
end: float = time.time()
return end - start


def draw_graph(sizes: list[int], times: list[float], title: str):
"""Draws a graph with the given input sizes and execution times."""

plt.plot(sizes, times, 'ro-')
plt.xlabel('Input size')
plt.ylabel('Execution time (s)')
plt.title(title)
plt.show()


def main():
print("Hello world")
"""Main function."""

sort.range.execution_time_for_array_of_numbers()

sizes: list[int] = []
times: list[float] = []

# Selection sort
times, sizes = get_1k_10k_arrays_execution_times(selection.sort)
draw_graph(sizes, times, "Selection sort")

# Insertion sort
times, sizes = get_1k_10k_arrays_execution_times(insertion.sort)
draw_graph(sizes, times, "Insertion sort")

# Fusion sort
times, sizes = get_1k_10k_arrays_execution_times(fusion.sort)
draw_graph(sizes, times, "Fusion sort")

# Python built-in sort
times, sizes = get_1k_10k_arrays_execution_times(sorted)
draw_graph(sizes, times, "Python built-in sort")


main()
Binary file added graphs-sorts.xlsx
Binary file not shown.
Binary file added graphs/Generation-times.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/fusion-sort.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/insertion-sort.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/python-built-in-sort.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/selection-sort.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 31 additions & 1 deletion sort/fusion.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,32 @@
def merge(left: list[int], right: list[int]) -> list[int]:
"""Merges two sorted arrays into one sorted array."""

result: list[int] = []
left_index: int = 0
right_index: int = 0

while left_index < len(left) and right_index < len(right):
if left[left_index] < right[right_index]:
result.append(left[left_index])
left_index += 1
else:
result.append(right[right_index])
right_index += 1

result.extend(left[left_index:])
result.extend(right[right_index:])

return result


def sort(array: list[int]) -> list[int]:
return array
"""Sorts the given array using fusion sort."""

if len(array) <= 1:
return array

mid = len(array) // 2
left_half = sort(array[:mid])
right_half = sort(array[mid:])

return merge(left_half, right_half)
9 changes: 9 additions & 0 deletions sort/insertion.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
def sort(array: list[int]) -> list[int]:
"""Sorts the given array using insertion sort."""

for index in range(1, len(array)):
key: int = array[index]
index_2 = index - 1
while index_2 >= 0 and key < array[index_2]:
array[index_2 + 1] = array[index_2]
index_2 -= 1
array[index_2 + 1] = key
return array
23 changes: 22 additions & 1 deletion sort/range.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
import time
import random


def generate_array_of_number(array_size: int) -> list[int]:
return []
"""Returns an array of the given size with random
numbers between 0 and 100."""

array: list[int] = []
for i in range(array_size):
array.append(random.randint(0, 100))
return array


def execution_time_for_array_of_numbers():
"""Prints the execution time for generating
an array of numbers."""

for i in range(1, 11):
start: float = time.time()
generate_array_of_number(1000000*i)
end: float = time.time()
print(f"Time to generate array of {1000000*i} numbers: {end - start}")
7 changes: 6 additions & 1 deletion sort/recursion.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
def get_factorial(number: int) -> int:
return number
"""Returns the factorial of the given number."""

if number == 0:
return 1
else:
return number * get_factorial(number - 1)
13 changes: 11 additions & 2 deletions sort/selection.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
def sort(array: list[int]) -> list[int]:
return array
# Selection sort
def sort(arr) -> list[int]:
"""Sorts the given array using selection sort."""

for i in range(len(arr)):
min_idx: int = i
for j in range(i + 1, len(arr)):
if arr[min_idx] > arr[j]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr