Le compte est bon

 

Principe de l’algorithme de résolution

Vue d’ensemble

La première partie consistera à réaliser le tirage aléatoire des six plaques et du nombre N  et à mettre les valeurs des plaques dans un tableau (CompteEstBonAlgo::Calcul())

La deuxième partie consistera à rechercher la solution optimale (CompteEstBonAlgo::resoudre).
Pour cela, on partira du résultat à trouver (Valeur) ou en cas d'échec, Valeur -1, Valeur +1, Valeur -2, Valeur +2, etc…, et on cherchera à obtenir en utilisant les six plaques.

Une difficulté est de choisir une bonne représentation pour les ensembles d'entiers. On choisira la représentation qui permet le calcul le plus rapide (le type long) et on évitera toute conversion inutile.

La règle n’autorisant l’utilisation que d’une plaque à la fois une implémentation récursive de la résolution est bien adaptée à ce type de traitement. L’algorithme de recherche de solution repose sur l’application exhaustive de toutes les opérations entre toutes les combinaisons de plaques.

On effectuera donc au maximum C62 *  4 * C52 *  4 * C42 *  4 * C32 *  4 * C22 *  4  soit  2764800 opérations arithmétiques.

En réalité, les contraintes liés aux opérations arithmétiques diminuent sensiblement le nombre d’opérations effectuées. En effet, la division est dans la plupart des cas non réalisables (une opération de moins sur les 4).

 

Le nombre minimum quant à lui correspond au cas ou le résultat de la première opération avec les 2 premières plaque correspond à la valeur recherchée.

 

L’algorithme prend les 2 premières plaques parmi les 6 et on effectue la première opération arithmétique. Si le résultat de l’opération est acceptable (résultat entier pour une division par exemple) on reconstitue un tableau de plaques avec ce résultat auquel on ajoute pour les indices suivants les 4 autres plaques restantes. Chaque changement d’opération fait suite à l’échec de tous les calculs effectués à partir des plaques restantes.


Vue détaillée :

 

On dispose de 6 plaques {p1,p2,p3,p4,p5,p6}, on choisit 2 plaques parmi ces 6 plaques :
Il y a donc = 6x5/2 = 15 combinaisons :
{(p1,p2),(p1,p3),(p1,p4),(p1,p5),(p1,p6),(p2,p3),(p2,p4),(p2,p5),(p2,p6),(p3,p4),(p3,p5),(p3,p6),(p4,p5),(p4,p6),(p5,p6)}

Pour chacun des couples (pi,pj), on dispose des 4 opérations arithmétiques.
La soustraction et la division n'étant pas commutative, il faut aussi penser à l'inverse :
pi - pj et aussi pj - pi
pi / pj et aussi pj / pi

Remarque :

p1 + p2 = p2 + p1 (commutativité de l'addition)
p1 x p2 = p2 x p1 (commutativité de la multiplication)

En y regardant de plus près, seules les valeurs positives nous intéressent :
Hors si p1 - p2 > 0 alors p2 - p1 < 0
Et si p1 - p2 > 0 alors p1> p2 et p2 / p1 n'existe pas (valeur non entière).

On peut donc tester le couple (pi,pj) et faire ensuite la soustraction qui est positive :
pi - pj ou pj - pi.
Si la soustraction est nulle, on peut éliminer le calcul, la valeur nulle ne pouvant nous aider dans la recherche de solutions.

On fait de même la division pi / pj ou pj / pi suivant le test.
Ce qui ramène le couple (pi,pj) à quatre opérations arithmétiques (la multiplication et surtout la division étant les plus coûteuses).
Si pi ou pj dans la multiplication (ou la division) est de valeur 1, alors pi x pj = pi ou pj (pi / pj = pi si pj = 1) et donc ces opérations ne font pas avancer le calcul et la recherche de solutions :
On peut donc éliminer ces cas également.
Si la division n'existe pas dans N, ce qui est très fréquent, on évite une opération de plus, ce qui donne en tout moins de 4 opérations en moyenne par couple (pi,pj).

On a donc 15 couples (pi,pj), et au plus 4 opérations pour chacun de ces couples, soit au plus 60 opérations pour les 2 premières plaques.

Supposons l'opération pi + pj :
La valeur calculée peut être considéré comme une nouvelle plaque.

On se retrouve alors avec le même problème mais avec 5 plaques et non plus avec 6 (2 plaques remplacées par le résultat de l'opération entre ces 2 plaques), il y a donc = 5x4/2 = 10 combinaisons.
Si par exemple p1 et p2 étaient les 2 premières plaques utilisées et si p1 devenait le résultat de la première opération de p1 et p2, on a ces 10 combinaisons :
{(p1,p3),(p1,p4),(p1,p5),(p1,p6),(p3,p4),(p3,p5),(p3,p6),(p4,p5),(p4,p6),(p5,p6)}

On fait le même raisonnement avec 4 plaques, 3 plaques, puis 2 plaques.

Dès qu'il ne reste plus qu'une seule plaque on dépile.

A chaque niveau de récursivité, on vérifie si le résultat de l'opération faite au niveau de récursivité précédent n'est pas le résultat qu'on cherche (simple test sur la nouvelle plaque issue des 2 anciennes : si p1 est toujours le résultat de l'opération précédente, on teste simplement si p1 est le résultat qu'on cherche).

 

Graphes de l'algorithme :

Ces graphes illustrent le fonctionnement de l'algorithme récursif :

 

Contact