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
25 changes: 12 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Mesurez combien de temps prend python à générer un tableau composés de :

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*
Comment vous semble évoluer la courbe ? Observez bien les différentes courbes du graphique ci-dessous. Quelle est la plus ressemblante à notre situation ? Une droite en NlogN

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

Expand All @@ -75,7 +75,7 @@ Observez attentivement l'animation de tri par sélection ci-dessous pour en comp

<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 ? L'algo cherche le plus petit élément de la liste en la parcourant, il l'échange avec le premier, puis recommence, il prend à nouveau le plus petit (mais sans compter ceux triés évidement) et le déplace. Jusqu'à avoir trié la liste

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 @@ -86,17 +86,16 @@ Mesurez le temps d'éxécution pour un tableau de :
- ...
- 10000 entrées

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*
Tracez le graphique correspondant. voir main

Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ? N²
### 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 ? L'algorithme parcourt la liste un élément après l'autre et place l'élément au bon endroit par rapport aux précédents

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 @@ -107,9 +106,9 @@ Mesurez le temps d'éxécution pour un tableau de :
- ...
- 10000 entrées

Tracez le graphique correspondant.
Tracez le graphique correspondant. voir main

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*
Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ?

### 3. Tri par fusion

Expand Down Expand Up @@ -154,7 +153,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 ? Il trie une liste efficassement via une séries d'étapes répétées à plusieurs échelles. Il y a 2 grandes étapes : 1/ couper la liste en 2 listes, puis chacune en 2 etc. jusqu'à laisser que des listes de 1 élément. 2/ Il rassemble chaque liste par paire en les les triant (trie que les premières valeurs entre elles mais comme on part de listes de 1 élément elles sont finalement toutes triées)

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

Expand All @@ -174,15 +173,15 @@ 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*
Quelle semble être la complexité de notre fonction de tri ? Cela est-il logique par rapport au code que vous avez implémenté ?

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 ? pour de petits tableaux

### 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 ;)
Une dernière fois, analysez le temps d'exécution et découvrez si python fait mieux que nos implémentations rudimentaires :)

## Pour rendre ce TP

Expand Down
98 changes: 97 additions & 1 deletion __main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,101 @@
import time
import numpy as np
import matplotlib.pyplot as plt
from sort.fusion import sort as fusion_sort
from sort.insertion import sort as insertion_sort
from sort.selection import sort as selection_sort
from sort.range import generate_array


def measure_time(algo_func, array):
"""Mesurer la durée d'exécution d'une fonction de tri"""
start_time = time.time()
algo_func(array)
end_time = time.time()
return end_time - start_time


def main():
print("Hello world")
"""Fonction principale"""
max_tab_size = int(input("Enter the maximum size of the array: "))
num_sizes = int(input("Enter the number of array sizes to generate: "))
critical_time = float(input("Enter the critical time for stopping the \
execution (in seconds): "))

# Choix de l'échelle avec par défaut la logarithmique
scale_choice = input("Choose scale (linear/log): ").lower()
if scale_choice not in ['linear', 'log']:
# Utilisation de l'échelle logarithmique par défaut
scale_choice = 'log'

# Générer des tableaux intermédiaires de taille croissante
if scale_choice == 'log':
sizes = np.logspace(0, np.log10(max_tab_size), num=num_sizes,
endpoint=True, base=10, dtype=int)
else:
sizes = np.linspace(1, max_tab_size, num=num_sizes, dtype=int)

selection_times = []
insertion_times = []
fusion_times = []

# Variables de contrôle pour arrêter la mesure du temps pour chaque algo
stop_selection = False
stop_insertion = False
stop_fusion = False

for size in sizes:
tab = generate_array(size)

# Mesurer la durée d'exécution du tri par SELECTION
if not stop_selection:
selection_time = measure_time(selection_sort, tab.copy())
selection_times.append(selection_time)
if size < max_tab_size and selection_time > critical_time:
print(f"Selection Sort exceeded critical time ({critical_time}\
seconds) for size {size}. Stopping.")
stop_selection = True

# Mesurer la durée d'exécution du tri par insertion
if not stop_insertion:
insertion_time = measure_time(insertion_sort, tab.copy())
insertion_times.append(insertion_time)
if size < max_tab_size and insertion_time > critical_time:
print(f"Insertion Sort exceeded critical time ({critical_time}\
seconds) for size {size}. Stopping.")
stop_insertion = True

# Mesurer la durée d'exécution du tri par FUSION
if not stop_fusion:
fusion_time = measure_time(fusion_sort, tab.copy())
fusion_times.append(fusion_time)
if size < max_tab_size and fusion_time > critical_time:
print(f"Fusion Sort exceeded critical time ({critical_time}\
seconds) for size {size}. Stopping.")
stop_fusion = True

# Vérifier si tous les algorithmes ont atteint le seuil critique
if stop_selection and stop_insertion and stop_fusion:
break

# Créer un graphique avec la légende à gauche
plt.plot(sizes[:len(selection_times)], selection_times,
label='Selection Sort', marker='o')
plt.plot(sizes[:len(insertion_times)], insertion_times,
label='Insertion Sort', marker='o')
plt.plot(sizes[:len(fusion_times)], fusion_times, label='Fusion Sort',
marker='o')

if scale_choice == 'log':
# Utiliser échelle logarithmique pour l'axe des x
plt.xscale('log')

# Paramètres du graph
plt.xlabel('Array Size')
plt.ylabel('Time (s)')
plt.title('Comparison of Sorting Algorithms')
plt.legend(loc='upper left')
plt.show()


main()
Binary file added chart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[tool.poetry]
name = "pyproject-toml"
version = "1"
description = "1"
authors = ["1"]
readme = "README.md"
packages = [{include = "pyproject"}]

[tool.poetry.dependencies]
python = "^3.12"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
33 changes: 33 additions & 0 deletions sort/fusion.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,35 @@
def sort(array: list[int]) -> list[int]:
"""Tri par algorithme de fusion"""
if len(array) <= 1:
return array

if len(array) <= 10:
# Utiliser un tri plus simple pour de petites listes
return sorted(array)

mid = len(array) // 2
left = sort(array[:mid])
right = sort(array[mid:])
return merge(left, right)


def merge(array1: list[int], array2: list[int]) -> list[int]:
"""Donne 1 liste triée à partir de 2 listes triées"""
array: list[int] = []

# Indices pour les deux listes
i = j = 0

while i < len(array1) and j < len(array2):
if array1[i] < array2[j]:
array.append(array1[i])
i += 1
else:
array.append(array2[j])
j += 1

# Ajouter les éléments restants de array1 et array2
array.extend(array1[i:])
array.extend(array2[j:])

return array
14 changes: 14 additions & 0 deletions sort/insertion.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
def sort(array: list[int]) -> list[int]:
"""Tri par algorithme d'insertion"""
len_list = len(array)
for index in range(1, len_list):
value = array[index]
start = index - 1

# Trouver le bon emplacement en déplaçant les éléments plus grands
while start >= 0 and array[start] > value:
array[start + 1] = array[start]
start -= 1

# Insérer la valeur à la bonne position
array[start + 1] = value

return array
9 changes: 7 additions & 2 deletions sort/range.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
def generate_array_of_number(array_size: int) -> list[int]:
return []
import random


def generate_array(array_size: int) -> list[int]:
"""Génère un tableau de n entiers posififs aléatoires (avec n la
taille du tableau en para)"""
return [random.randint(0, 100) for i in range(array_size)]
3 changes: 2 additions & 1 deletion sort/recursion.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
def get_factorial(number: int) -> int:
return number
"""factoctorielle"""
return number if number <= 1 else number * get_factorial(number - 1)
17 changes: 17 additions & 0 deletions sort/selection.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
def sort(array: list[int]) -> list[int]:
"""Tri par algorithme de sélection"""
len_list = len(array)

for index in range(len_list - 1):
min_index = index

for j in range(index + 1, len_list):
if array[j] < array[min_index]:
min_index = j

# Echanger les valeurs si nécessaire
if min_index != index:
array[index], array[min_index] = array[min_index], array[index]

return array


print(sort([1, 2, 3, 4, 6, 9, 5, 7, 9, 1, 2, 0]))