Logo de kxs.frCours d'informatique pour le lycée et la prépa

Diviser pour régner

Description

Diviser pour régner est une technique algorithmique qui se déroule en trois étapes :

Exemple du tri fusion

Le tri fusion est encore un algorithme de tri. Celui-ci est récursif et utilise, bien sur, la méthode diviser pour régner. Voici un algorithme décrivant le tri fusion :

triFusion(liste):
    si la liste contient un élément ou moins:
		retourner liste
    sinon:
		listegauche = demi-liste gauche de liste
		listedroite = demi-liste droite de liste
		retourner combinaison(triFusion(listegauche), triFusion(listedroite))

combinaison(listegauche, listedroite):
	# listegauche et listedroite sont des listes ordonées
	listeretour = liste vide
	indicelistegauche = 1
	indicelistedroite = 1
	tant que indicelistegauche < taille(listegauche) et indicelistedroite < taille(listedroite):
		si listegauche[indicelistegauche] < listedroite[indicelistedroite]:
			on ajoute listegauche[indicelistegauche] à listeretour
			indicelistegauche = indicelistegauche + 1
		sinon:
			on ajoute listedroite[indicelistedroite] à listeretour
			indicelistedroite = indicelistedroite + 1
	renvoyer listeretour + la fin de la liste non totalement explorée

Voici un schéma montrant le déroulement de cet algorithme sur la liste [4, 3, 8, 2, 7, 1, 5] :

1) Quelle ligne de l'algorithme fait qu'il est récursif ?

2) Expliquer en une phrases ce que fait la fonction combinaison.

3) Proposez une implémentation en Python de la fonction combinaison.

4) Proposez enfin une implémentation en Python du tri fusion.

Application : rotation d'image

Il est possible d'appliquer la méthode diviser pour régner à la rotation d'une image carrée. Nous ferons tourner l'image de 90° dans le sens trigonométrique. La méthode est illustrée sur le schéma ci-dessous :

Nous utiliserons le module PIL déjà utilisé l'année dernière. L'image à faire tourner sera la joconde. Elle est carrée avec une taille égale à une puissance de 2. Voici la structure que vous pourrez utiliser :

from PIL import Image

img = Image.open("joconde.png")
# Affiche l'image originale
img.show()

def echangePixels(image,pixel_a,pixel_b):
	"""
	Échange la couleur des deux pixels pixel_a et pixel_b.
	pixel_a : tuple de coordonnées
	pixel_b : tuple de coordonnées

	À compléter !
	"""
	…

def tourne(image):
	"""
	Lance la fonction récursive sur l'image originale.

	Fonction complète.
	"""
    tourneRecursif(image,(0,0),image.size[0])

def echangeQuadrant(image,coinHautGauche_a,coinHautGauche_b,n):
	"""
	Échange les pixels entre les deux quadrants de taille n
	définis par leur coin haut gauche.

	coinHautGauche_a : tuple des coordonnées du coin supérieur gauche du quadrant a
	coinHautGauche_b : tuple des coordonnées du coin supérieur gauche du quadrant b
	n : taille des deux quadrants

	À compléter !
	"""
	…

def tourneRecursif(image,coinHautGauche,taille):
	"""
	Applique une rotation du quadrant de l'image défini par
	son coin supérieur gauche et sa taille.

	coinHautGauche : tuple des coordonnées du coin supérieur gauche du quadrant
	taille : taille du quadrant à faire tourner

	À compléter !
	"""
	…

# Lance le programme
tourne(img)
# Affiche l'image
img.show()

Vous chercherez vous-même sur la documentation de PIL les méthodes à utiliser pour accéder aux pixels de l'image.

Application : minimum et maximum d'un tableau

L'objectif est d'écrire une fonction récursive min_et_max(T, a, b) renvoyant le couple (minimum, maximum) du tableau T[a:b].

Un algorithme du type « diviser pour régner » permet de déterminer ce couple en exploitant le fait qu’une seule comparaison suffit pour obtenir à la fois le minimum et le maximum d'un tableau de taille 2. Voici cet algorithme :

VARIABLES
T : tableau

DEBUT
si T ne contient qu'un élément:
	retourner (T[0], T[0])
sinon si T contient deux éléments:
	retourner le couple (minimum, maximum)
sinon:
	tableaugauche = demi-tableau gauche de T
	tableaudroit = demi-tableau droit de T
	calculer récursivement le couple (min, max) des deux tableaux
	fusionner les résultats précédents
	retourner le couple (minimum, maximum)
FIN

5) Écrire la fonction min_et_max(T) en Python.

6) La tester sur le tableau T = [1, 6, -5, 8, 14, -2, -7, 21] en lancant la commande min_et_max(T)

7) Combien cette fonction utilise de comparaisons pour un tableau de 4 éléments ?

8) Combien un algorithme classique utilise de comparaisons pour un tableau de 4 éléments ?

9) Répondez aux deux questions précédentes pour des tableaux de 8, 16 et 32 éléments. Que pouvez-vous conclure sur la complexité de cet algorithme ?