Retour
Cours précédent
Cours suivant

Partition d’un entier

Le nombre de partition d’un entier est le nombre de paquets différents que l’on peut faire avec cet entier.

Exemple : 4 = 4 = 3+1 = 2+2 = 2+1+1 = 1+1+1+1
Il y a 5 différents paquets. L’entier 4 a 5 partitions.

Les premières valeurs sont :

n 1 2 3 4 5 6 7 8 9 10
P(n) 1 2 3 5 7 11 15 22 30 42

Formule asymptotique

Il n’y a pas de formule close pour P(n).

La formule de Fibonacci semble s’approcher de P(n) mais n’est pas totalement ça.

Il y a cependant une formule asymptotique. Un formule dont le quotient avec p(n) s’approche de 1.

\[p(n) \sim \frac{1}{4n\sqrt{3}}* exp(\pi \sqrt{2n/3}) \approx 2^{3.7\sqrt{n}}\]

Approche exhaustive

Une approche exhaustive en codant les partitions sous forme de bits n’est pas optimal car il y a trop de possibilités.

Récurrence

On utilise une représentation graphique.

Exemple : Entier 4

             *
         *   *
*    **  *   *
***  **  **  *

Il y a deux type de partitions(diagrammes) :

Pour le type 1 : On peut enlever la dernière colonne pour se ramener à un diagramme plus petit. On enlève une partition et on diminue l’entier de 1.
Pour le type 2 : On peut enlever la ligne du bas pour se ramener à un diagramme plus petit. On diminue l’entier du nombre de partition.

\(p(n,k) = p_1(n,k) + p_2(n,k) = p(n-1,k-1)+p(n-k, k)\) avec n l’entier et k le nombre de partitions.
Il faut \(n \ge k > 1\)

Code

int p(int n, int k) {
	if (k>n)  return 0;
	if(n==1 || k==1) return 1;
}
int p_rec(int n) {
	int s=0;
	for (int k=1; k<=n; k++) {
		s += p(n, k);
	}
	return s;
}

Arbre des appels

C’est un arbre dont les nœuds représentent les paramètres d’appels et les fils les différents appels. L’exécution de la fonction correspond à un parcours en profondeur de cet arbre, la racine représente les paramètres du 1er appel.

Arbre p_rec(6) :

Arbre p(6,3) :

La complexité est O(#noeus) = O(n*p(n)) = \(2^{\Theta(\sqrt{n})}\)

Ici, on a calculé la complexité en nombre d’opérations arithmétiques.

Attention : op arithmétique (+) est élémentaire si les calculs tiennent sur des mots mémoires. Problème si n est très grand.

Complexité en temps : \(O(\sqrt{n})\times 2^{\Theta(\sqrt{n})} = 2^{\Theta(\sqrt{n})}\)

Calculs inutiles

Il y a des parties de l’arbre des appels qui se répètent.

Programmation dynamique

Mémoriser les calculs déjà effectués.

On peut stocker les résultats des calculs dans une table pour pouvoir y accéder plus tard à la place de refaire le calcul.

P[n][k] = p(n,k)

Mémorisation paresseuse

Pour toute fonction récursive, on stocke dans une table les résultats calculés.
Supprimer la redondance de la récursivité par mémorisation.


Retour
Cours précédent
Cours suivant