Algorithme de combinaison : imprimer toutes les combinaisons possibles de R
โก Rรฉsumรฉ intelligent
L'algorithme de combinaison affiche toutes les sรฉlections possibles de r รฉlรฉments parmi un ensemble de n, l'ordre n'ayant pas d'importance. Cette ressource explique la formule de combinaison, la complexitรฉ temporelle, deux mรฉthodes rรฉcursives, la gestion des doublons et le code C complet. C++ et Python mises en ลuvre.

Quelle est la combinaison ?
La combinaison est une sorte dโarrangement de certains objets donnรฉs. En termes mathรฉmatiques, la combinaison est un ensemble de choix/sรฉlection dโรฉlรฉments parmi un ensemble unique dโรฉlรฉments/objets. Ici, lโordre des รฉlรฉments nโa pas dโimportance. Cette mรฉthode est รฉgalement connue pour calculer le rรฉsultat total d'un รฉvรฉnement, oรน l'ordre du rรฉsultat n'a pas d'importance.
Par exemple, on vous donne un sac avec 5 couleurs diffรฉrentes et on vous demande de gรฉnรฉrer un motif avec 3 couleurs au choix. Vous pouvez รฉgalement choisir 3 couleurs parmi 4, puis les disposer dans des ordres diffรฉrents.
Supposons que les couleurs soient RGYBI (R= Rouge, G= Vert, Y= Jaune, B= Bleu, I= Indigo). Ainsi, le motif possible peut รชtre RVB, RGY, etc.
Regardons la figure suivante :

Explication:
- Prenez 4 couleurs sur 5 et listez-les
- Dans chaque bloc de 4 couleurs, choisissez-en 3 et listez-les toutes. Par exemple, nous avons uniquement choisi ยซ RGBI ยป dans la figure et prรฉsentรฉ 4 combinaisons.
- Il y a une thรฉorie derriรจre cela pour calculer le nombre total de combinaisons que nous pouvons faire. Une combinaison de r รฉlรฉments sur n peut รชtre mathรฉmatiquement prรฉsentรฉe comme :
Le signe "!" signifie le factoriel. Par exemple,
N! = N * (N-1) * (N-2) * โฆ * 3 * 2 * 1
Dis, 5 ! = 5*4*3*2*1 = 120
Donc, pour notre problรจme ci-dessus, nous avons 5 couleurs signifiant n = 5, et ร tout moment, nous devons en choisir 3. Donc, r = 3. Aprรจs le calcul, nous obtenons,
Un total de 10 combinaisons de couleurs est possible pour le scรฉnario ci-dessus.
L'analyse de complexitรฉ temporelle pour la combinaison
Maintenant, disons que, รฉtant donnรฉ un tableau de taille n, on nous demande de prendre r รฉlรฉments du tableau et d'effectuer des combinaisons de r รฉlรฉments.
Si un tableau de taille n est donnรฉ, alors il faudra O(n2) le temps d'effectuer la tรขche. De plus, si nous voulons supprimer l'entrรฉe en double, alors,
Nous devons effectuer les รฉtapes suivantes :
รtape 1) Triez les donnรฉes du tableau dโentrรฉe par ordre croissant. La complexitรฉ temporelle du tri est O(n*log(n)).
รtape 2) Crรฉez un autre tableau contenant un รฉlรฉment unique ร partir des donnรฉes du tableau temporaire donnรฉes.
รtape 3) Ensuite, exรฉcutez la fonction de combinaison.
Ainsi, la complexitรฉ temporelle totale devient = Sur2) + O(nLog(n)). On peut le considรฉrer O(n2), comme n2 est beaucoup plus grand que n*log(n).
Mรฉthode 1 : รฉlรฉment fixe avec rรฉcursivitรฉ
Dans cette mรฉthode, nous choisirons un รฉlรฉment puis trouverons une combinaison dโรฉlรฉments r-1. Lorsque nous sรฉlectionnons un รฉlรฉment dans le reste de l'รฉlรฉment, nous le faisons de maniรจre rรฉcursive, et c'est pourquoi cela est appelรฉ รฉlรฉment fixe et rรฉcursion.
Montrons l'algorithme รฉtape par รฉtape avec un diagramme :
Les รฉtapes sont indiquรฉes ci-dessous :
รtape 1) Dans la premiรจre couche, prenez n-r+1 รฉlรฉments. Cela signifie que nous avons pris 3 รฉlรฉments.
รtape 2) Choisissez un รฉlรฉment de la 2รจme couche et montez-le au nยฐ. Donc, si nous prenons ยซ R ยป, alors avec R, nous pouvons prendre G, Y et B.
รtape 3) Choisissez un รฉlรฉment de la 3รจme couche et amenez-le jusqu'au niรจme รฉlรฉment, et formez des blocs contenant 3 รฉlรฉments chacun.
Le chiffre ci-dessus est la valeur de retour de la rรฉcursion. Seule la derniรจre couche sera imprimรฉe.
Faux Code
function combination: pass in: inputArray, combinationArray, start, end, index, r if index is equal to r: for each element in combinationArray: print each element return for i = start: if i <=end and end -i+1 > r-index: combinationArray[index] = inputArray[i] call combination function again with updated parameter
Implรฉmentation en C/C++
#include<bits/stdc++.h> #include<stdio.h> void Combination(char inputArray[], char combinationArray[], int start, int end, int index, int r) { if (index == r) { for (int i = 0; i < r; i++) { printf("%c", combinationArray[i]); } printf("\n"); return; } for (int i = start; i <= end && end - i + 1 >= r - index; i++) { combinationArray[index] = inputArray[i]; Combination(inputArray, combinationArray, i + 1, end, index + 1, r); } } int main() { char inputArray[] = {'R','G','Y','B','I'}; int n = sizeof(inputArray) / sizeof(inputArray[0]); int r = 3; char combinationArray[r]; printf("Combinations:\n"); Combination(inputArray, combinationArray, 0, n - 1, 0, r); }
Sortie :
Combinations: RGY RGB RGI RYB RYI RBI GYB GYI GBI YBI
Mise en ลuvre dans Python
def Combination(inputArray, combinationArray, start, end, index, r): if index == r: for item in combinationArray: print(item, end = " ") print() return i = start while (i <= end and end - i + 1 >= r - index): combinationArray[index] = inputArray[i] Combination(inputArray, combinationArray, i + 1, end, index + 1, r) i += 1 inputArray = "RGYBI" n = len(inputArray) r = 3 combinationArray = [0] * r Combination(inputArray, combinationArray, 0, n - 1, 0, r)
Sortie :
R G Y R G B R G I R Y B R Y I R B I G Y B G Y I G B I Y B I
Mรฉthode 2 (inclure et exclure chaque รฉlรฉment)
Cette mรฉthode est basรฉe sur l'identitรฉ de Pascal. Auparavant, nous utilisions la rรฉcursivitรฉ pour calculer le nCr. Ici, la mรฉthode est simplement divisรฉe au lieu dโune boucle complexe.
D'aprรจs l'identitรฉ de Pascal,
nCr = (n-1)Cr + (n-1)C(r-1)
Ainsi, il y aura 2 logiques rรฉcursives pour que l'algorithme rรฉcursif trouve une combinaison de r รฉlรฉments d'un tableau donnรฉ de taille n.
- L'รฉlรฉment est inclus dans la combinaison actuelle
- L'รฉlรฉment est exclu de la combinaison actuelle
Faux Code
function combination: pass in: inputArray, combinationArray, n, r, index, i if the index is equal to r: for each element in combination array: print each element if i>=n: return combinationArray[index] = inputArray[i] combination(inputArray, combinationArray, n, r, index+1, i+1) combination(inputArray, combinationArray, n, r, index, i+1)
Implรฉmentation en C/C++
#include<bits/stdc++.h> #include<stdio.h> void Combination(char inputArray[], char combinationArray[], int n, int r, int index, int i) { if (index == r) { for (int j = 0; j < r; j++) { printf("%c", combinationArray[j]); } printf("\n"); return; } if (i >= n) return; combinationArray[index] = inputArray[i]; Combination(inputArray, combinationArray, n, r, index + 1, i + 1); Combination(inputArray, combinationArray, n, r, index, i + 1); } int main() { char inputArray[] = {'R','G','Y','B','I'}; int n = sizeof(inputArray) / sizeof(inputArray[0]); int r = 3; char combinationArray[r]; printf("Combinations:\n"); Combination(inputArray, combinationArray, n, r, 0, 0); }
Sortie :
Combinations: RGY RGB RGI RYB RYI RBI GYB GYI GBI YBI
Mise en ลuvre dans Python
def Combination(inputArray, combinationArray, n, r, index, i): if index == r: for item in combinationArray: print(item, end = " ") print() return if i >= n: return combinationArray[index] = inputArray[i] Combination(inputArray, combinationArray, n, r, index + 1, i + 1); Combination(inputArray, combinationArray, n, r, index, i + 1); inputArray = "RGYBI" n = len(inputArray) r = 3 combinationArray = [""] * r Combination(inputArray, combinationArray, n, r, 0, 0)
Sortie :
R G Y R G B R G I R Y B R Y I R B I G Y B G Y I G B I Y B I
Gestion des combinaisons en double
Parfois, il peut y avoir des รฉlรฉments en double dans le tableau d'entrรฉe.
Par exemple,
- Le tableau d'entrรฉe contient n = {5, 2, 3, 1, 5}.
- Ici, nous pouvons voir que 5 est prรฉsent 2 fois.
- Maintenant, si nous voulons exรฉcuter le code de ce tableau, certaines combinaisons seront rรฉpรฉtรฉes.
- Nous trouverons {5, 2, 5}, {5, 2, 3} etc. ou toute combinaison contenant 5 sera rรฉpรฉtรฉe.
Nous pouvons utiliser ces deux mรฉthodes :
- Triez le tableau d'entrรฉe. Le tri prendra un temps O(nlog(n)).
- Augmentez ensuite la valeur de i, tandis que la valeur i et la valeur i+1 sont identiques. Fondamentalement, mettez les deux lignes de code suivantes dans la fonction Combinaison.
// For c/c++ while(inputArray[i] == inputArray[i+1]){ i++; }
# for python while inputArray[i]==inputArray[i+1]: i+=1
Utiliser un dictionnaire ou une carte non ordonnรฉe pour track combinaisons en double
Donc, si nous ne voulons pas trier les รฉlรฉments pour tracPour obtenir le doublon, nous pouvons suivre les รฉtapes indiquรฉes.
รtape 1) Dรฉclarez un dictionnaire global ou une hashmap.
รtape 2) Poussez la combinaison gรฉnรฉrรฉe vers la table de hachage et augmentez la valeur de un. La combinaison est la clรฉ et leurs occurrences sont des valeurs.
รtape 3) lorsque la fonction aura fini de s'exรฉcuter, nous imprimerons simplement toutes les clรฉs du hashmap ou du dictionnaire.
Voici l'implรฉmentation en python
unique_combination = dict() def Combination(inputArray, combinationArray, n, r, index, i): if index == r: temp_combination = "" for item in combinationArray: temp_combination += item unique_combination[temp_combination] = unique_combination.get(temp_combination, 0) + 1 return if i >= n: return combinationArray[index] = inputArray[i] Combination(inputArray, combinationArray, n, r, index + 1, i + 1); Combination(inputArray, combinationArray, n, r, index, i + 1); inputArray = "RGYBIB" n = len(inputArray) r = 3 combinationArray = [""] * r Combination(inputArray, combinationArray, n, r, 0, 0) for item in unique_combination.keys(): print(item)
Sortie :
RGY RGB RGI RYB RYI RBI RBB RIB GYB GYI GBI GBB GIB YBI YBB YIB BIB
Ici, vous pouvez voir que l'entrรฉe รฉtait ยซ RGYBIB ยป. En gรฉnรฉral, il devrait y avoir des combinaisons en double. Mais comme nous avons utilisรฉ un dictionnaire et traitรฉ chaque combinaison comme la clรฉ, nous ne pouvons imprimer que la combinaison unique.
Maintenant, si vous รฉcrivez ยซ print(unique_combination) ยป, vous pouvez voir la frรฉquence de chaque combinaison. Cela s'affichera comme ceci :
{'RGY': 1, 'RGB': 2, 'RGI': 1, 'RYB': 2, 'RYI': 1, 'RBI': 1, 'RBB': 1, 'RIB': 1, 'GYB': 2, 'GYI': 1, 'GBI': 1, 'GBB': 1, 'GIB': 1, 'YBI': 1, 'YBB': 1, 'YIB': 1, 'BIB': 1}
Ainsi, nous pouvons voir que RGB, RYB, GYB se sont produits 2 fois. La complexitรฉ temporelle de l'insertion de la clรฉ dans un dictionnaire est essentiellement O(1). Ainsi, si vous utilisez un dictionnaire, la complexitรฉ temporelle totale d'exรฉcution du code sera :
O(1) + O(n*n)
รquivalent ร O(n*n).
En utilisant la mรฉthode prรฉcรฉdente pour tracPour k doublons, le tri nรฉcessite O(n*log(n)) ; la comparaison, O(n) ; et la fonction elle-mรชme a une complexitรฉ temporelle de O(n*n). La complexitรฉ temporelle totale sera :
O(n*log(n)) + O(n) +O(n*n)


